"use client";

import { useActionState, useState, type FormEvent, type ReactNode } from "react";
import { Button } from "@/components/ui/button";
import { ButtonLink } from "@/components/ui/button-link";
import { Card } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import {
  PROJECT_DEFAULTS,
  PROJECT_LIMITS,
  projectFormValues,
  validateProject,
  type ProjectField,
  type ProjectFieldErrors,
  type ProjectFormValues,
} from "@/lib/validation/project";
import type { ProjectFormState } from "@/app/(dashboard)/apps/actions";

type ProjectFormProps = {
  action: (prev: ProjectFormState, formData: FormData) => Promise<ProjectFormState>;
  initialValues?: ProjectFormValues;
  submitLabel: string;
};

const EMPTY_VALUES: ProjectFormValues = {
  projectCode: "",
  projectName: "",
  productionUrl: "",
  monitoringEnabled: true,
  expectedHttpStatus: String(PROJECT_DEFAULTS.expectedHttpStatus),
  timeoutSeconds: String(PROJECT_DEFAULTS.timeoutSeconds),
  description: "",
};

function Field({
  id,
  label,
  required,
  hint,
  error,
  children,
}: {
  id: ProjectField;
  label: string;
  required?: boolean;
  hint?: string;
  error?: string;
  children: ReactNode;
}) {
  return (
    <div className="space-y-1.5">
      <Label htmlFor={id}>
        {label}
        {required && (
          <span className="ml-0.5 text-red-600" aria-hidden>
            *
          </span>
        )}
      </Label>
      {children}
      {error ? (
        <p id={`${id}-error`} className="text-xs text-red-600">
          {error}
        </p>
      ) : (
        hint && <p className="text-xs text-slate-500">{hint}</p>
      )}
    </div>
  );
}

export function ProjectForm({ action, initialValues, submitLabel }: ProjectFormProps) {
  const [state, formAction, pending] = useActionState(action, {});
  const [clientErrors, setClientErrors] = useState<ProjectFieldErrors | null>(null);

  const values = state.values ?? initialValues ?? EMPTY_VALUES;
  const errors = clientErrors ?? state.fieldErrors ?? {};

  // Same schema as the server; this only saves a round trip.
  function handleSubmit(event: FormEvent<HTMLFormElement>) {
    const result = validateProject(projectFormValues(new FormData(event.currentTarget)));
    if (result.ok) {
      setClientErrors(null);
      return;
    }
    event.preventDefault();
    setClientErrors(result.fieldErrors);
    const firstInvalid = Object.keys(result.fieldErrors)[0];
    if (firstInvalid) event.currentTarget.querySelector<HTMLElement>(`#${firstInvalid}`)?.focus();
  }

  const invalid = (field: ProjectField) => ({
    "aria-invalid": Boolean(errors[field]),
    "aria-describedby": errors[field] ? `${field}-error` : undefined,
  });

  return (
    <Card className="max-w-2xl p-5">
      <form action={formAction} onSubmit={handleSubmit} noValidate className="space-y-5">
        {state.error && (
          <p role="alert" className="rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
            {state.error}
          </p>
        )}

        <div className="grid gap-5 sm:grid-cols-2">
          <Field id="projectCode" label="Project Code" required error={errors.projectCode}>
            <Input
              id="projectCode"
              name="projectCode"
              defaultValue={values.projectCode}
              placeholder="1118"
              maxLength={50}
              required
              {...invalid("projectCode")}
            />
          </Field>

          <Field id="projectName" label="Project Name" required error={errors.projectName}>
            <Input
              id="projectName"
              name="projectName"
              defaultValue={values.projectName}
              placeholder="2ndLine"
              maxLength={150}
              required
              {...invalid("projectName")}
            />
          </Field>
        </div>

        <Field id="productionUrl" label="Production Health API URL" required error={errors.productionUrl}>
          <Input
            id="productionUrl"
            name="productionUrl"
            type="url"
            inputMode="url"
            defaultValue={values.productionUrl}
            placeholder="https://api.example.com/health"
            required
            {...invalid("productionUrl")}
          />
        </Field>

        <div className="grid gap-5 sm:grid-cols-2">
          <Field
            id="expectedHttpStatus"
            label="Expected HTTP Status"
            hint={`Default ${PROJECT_DEFAULTS.expectedHttpStatus}`}
            error={errors.expectedHttpStatus}
          >
            <Input
              id="expectedHttpStatus"
              name="expectedHttpStatus"
              inputMode="numeric"
              defaultValue={values.expectedHttpStatus}
              {...invalid("expectedHttpStatus")}
            />
          </Field>

          <Field
            id="timeoutSeconds"
            label="Timeout (seconds)"
            hint={`Default ${PROJECT_DEFAULTS.timeoutSeconds}, max ${PROJECT_LIMITS.timeoutSeconds.max}`}
            error={errors.timeoutSeconds}
          >
            <Input
              id="timeoutSeconds"
              name="timeoutSeconds"
              inputMode="numeric"
              defaultValue={values.timeoutSeconds}
              {...invalid("timeoutSeconds")}
            />
          </Field>
        </div>

        <Field id="description" label="Description" error={errors.description}>
          <Textarea
            id="description"
            name="description"
            defaultValue={values.description}
            maxLength={1000}
            rows={3}
            {...invalid("description")}
          />
        </Field>

        <label className="flex items-start gap-2.5">
          <input
            type="checkbox"
            name="monitoringEnabled"
            defaultChecked={values.monitoringEnabled}
            className="mt-0.5 size-4 rounded border-slate-300 accent-slate-900"
          />
          <span>
            <span className="block text-sm font-medium text-slate-700">Monitoring Enabled</span>
            <span className="block text-xs text-slate-500">
              When disabled, no health checks run and the app shows as Monitoring Disabled.
            </span>
          </span>
        </label>

        <div className="flex items-center justify-between gap-3 border-t border-slate-200 pt-4">
          <p className="text-xs text-slate-500">
            <span className="text-red-600">*</span> Required
          </p>
          <div className="flex items-center gap-2">
            <ButtonLink href="/apps" variant="secondary">
              Cancel
            </ButtonLink>
            <Button type="submit" disabled={pending}>
              {pending ? "Saving…" : submitLabel}
            </Button>
          </div>
        </div>
      </form>
    </Card>
  );
}
