"use client";

import { useState } from "react";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm, type Resolver } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/input";
import { FormField } from "@/components/ui/form-field";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { useT } from "@/i18n";
import {
  approveDriver,
  rejectDriver,
  requestDriverDocuments,
  type VehicleAssignmentInput,
} from "@/services/drivers";
import { applyFieldErrors, friendlyErrorMessage } from "@/lib/errors";
import { useCan } from "@/features/auth/use-can";
import type { Driver } from "@/types/driver";

const reviewNoteSchema = z.object({
  review_note: z.string().min(1, "errors.required"),
});

const vehicleSchema = z.object({
  plate_number: z.string().min(1, "errors.required"),
  brand: z.string().min(1, "errors.required"),
  model: z.string().min(1, "errors.required"),
  manufacture_year: z.coerce
    .number()
    .int()
    .min(1900, "errors.generic")
    .max(new Date().getFullYear() + 1, "errors.generic"),
  color: z.string().min(1, "errors.required"),
});

type ReviewNoteValues = z.infer<typeof reviewNoteSchema>;
type VehicleValues = z.infer<typeof vehicleSchema>;
type DialogKind = "approve" | "reject" | "documents";

// `z.coerce.number()` widens the schema input type to `unknown`; zodResolver is
// given a `Resolver` whose input matches the form's already-coerced values.
const vehicleResolver = zodResolver(vehicleSchema) as unknown as Resolver<VehicleValues>;

function ReviewNoteForm({
  kind,
  form,
}: {
  kind: "reject" | "documents";
  form: ReturnType<typeof useForm<ReviewNoteValues>>;
}) {
  const t = useT();
  return (
    <FormField
      label={
        kind === "reject" ? t("applications.reasonForReject") : t("applications.whatIsMissing")
      }
      htmlFor="review_note"
      required
      error={form.formState.errors.review_note?.message}
    >
      <Textarea
        id="review_note"
        rows={3}
        placeholder={t("applications.reviewNotePlaceholder")}
        {...form.register("review_note")}
      />
    </FormField>
  );
}

/**
 * The approve / reject / request-documents decision flows for a captain
 * application. Approving a captain who registered a company-owned vehicle
 * requires a fleet vehicle assignment first (ApproveDriverRequest behaviour).
 */
export function ReviewActions({
  driver,
  onDone,
  compact = false,
}: {
  driver: Driver;
  onDone: () => void;
  compact?: boolean;
}) {
  const t = useT();
  const { can } = useCan();
  const canReview = can("drivers.review");

  const [kind, setKind] = useState<DialogKind | null>(null);
  const [busy, setBusy] = useState(false);

  const noteForm = useForm<ReviewNoteValues>({
    resolver: zodResolver(reviewNoteSchema),
    defaultValues: { review_note: "" },
  });
  const vehicleForm = useForm<VehicleValues>({
    resolver: vehicleResolver,
    defaultValues: {
      plate_number: "",
      brand: "",
      model: "",
      manufacture_year: new Date().getFullYear(),
      color: "",
    },
  });

  if (!canReview) return null;

  function close() {
    setKind(null);
    noteForm.reset();
    vehicleForm.reset();
  }

  async function run(action: () => Promise<{ Message: string | null }>) {
    setBusy(true);
    try {
      const response = await action();
      toast.success(response.Message || t("applications.approve"));
      close();
      onDone();
    } catch (error) {
      // Two forms feed one request, so each takes only what it renders: the note box, and the
      // vehicle fields the server names `vehicle.*` — a plate already held by another captain is
      // the refusal that actually happens here.
      const onNote = applyFieldErrors(
        error,
        (field, message) => noteForm.setError(field as never, { message }),
        { only: ["review_note"] },
      );
      const onVehicle = applyFieldErrors(
        error,
        (field, message) => vehicleForm.setError(field as never, { message }),
        { prefix: "vehicle" },
      );
      if (onNote + onVehicle === 0) toast.error(friendlyErrorMessage(error, t));
    } finally {
      setBusy(false);
    }
  }

  async function handleApprove() {
    if (driver.vehicle?.ownership_type === "company_owned") {
      const valid = await vehicleForm.trigger();
      if (!valid) return;
      const data = vehicleForm.getValues();
      const vehicle: VehicleAssignmentInput = {
        plate_number: data.plate_number,
        brand: data.brand,
        model: data.model,
        manufacture_year: data.manufacture_year,
        color: data.color,
      };
      await run(() => approveDriver(driver.uuid, vehicle));
      return;
    }
    await run(() => approveDriver(driver.uuid));
  }

  async function handleReject() {
    const valid = await noteForm.trigger();
    if (!valid) return;
    const data = noteForm.getValues();
    await run(() => rejectDriver(driver.uuid, data.review_note));
  }

  async function handleRequestDocuments() {
    const valid = await noteForm.trigger();
    if (!valid) return;
    const data = noteForm.getValues();
    await run(() => requestDriverDocuments(driver.uuid, data.review_note));
  }

  const needsFleetVehicle =
    driver.vehicle?.ownership_type === "company_owned" && driver.status === "pending";

  return (
    <>
      <div className="flex flex-wrap items-center gap-2">
        <Button
          size={compact ? "sm" : "default"}
          variant="outline"
          onClick={() => setKind("reject")}
        >
          {t("applications.reject")}
        </Button>
        <Button
          size={compact ? "sm" : "default"}
          variant="outline"
          onClick={() => setKind("documents")}
        >
          {t("applications.requestDocuments")}
        </Button>
        <Button
          size={compact ? "sm" : "default"}
          onClick={() => setKind("approve")}
        >
          {t("applications.approve")}
        </Button>
      </div>

      <Dialog open={kind !== null} onOpenChange={(next) => !next && close()}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>
              {kind === "approve"
                ? t("applications.approveTitle")
                : kind === "reject"
                  ? t("applications.rejectTitle")
                  : t("applications.documentsTitle")}
            </DialogTitle>
            <DialogDescription>
              {kind === "approve"
                ? t("applications.approveBody")
                : kind === "reject"
                  ? t("applications.rejectBody")
                  : t("applications.documentsBody")}
            </DialogDescription>
          </DialogHeader>

          {kind === "approve" && needsFleetVehicle ? (
            <>
              <div className="rounded-lg border p-4 text-xs leading-relaxed text-muted-foreground">
                {t("applications.vehicleHint")}
              </div>
              <div className="grid gap-3">
                <FormField
                  label="Plate number"
                  htmlFor="plate_number"
                  required
                  error={vehicleForm.formState.errors.plate_number?.message}
                >
                  <Input id="plate_number" dir="ltr" placeholder="ABC 1234" {...vehicleForm.register("plate_number")} />
                </FormField>
                <div className="grid grid-cols-2 gap-3">
                  <FormField label="Brand" htmlFor="brand" required error={vehicleForm.formState.errors.brand?.message}>
                    <Input id="brand" {...vehicleForm.register("brand")} />
                  </FormField>
                  <FormField label="Model" htmlFor="model" required error={vehicleForm.formState.errors.model?.message}>
                    <Input id="model" {...vehicleForm.register("model")} />
                  </FormField>
                  <FormField
                    label="Year"
                    htmlFor="manufacture_year"
                    required
                    error={vehicleForm.formState.errors.manufacture_year?.message}
                  >
                    <Input
                      id="manufacture_year"
                      type="number"
                      min={1900}
                      dir="ltr"
                      {...vehicleForm.register("manufacture_year", { valueAsNumber: true })}
                    />
                  </FormField>
                  <FormField label="Color" htmlFor="color" required error={vehicleForm.formState.errors.color?.message}>
                    <Input id="color" {...vehicleForm.register("color")} />
                  </FormField>
                </div>
              </div>
            </>
          ) : null}

          {kind === "reject" || kind === "documents" ? (
            <ReviewNoteForm kind={kind} form={noteForm} />
          ) : null}

          <DialogFooter>
            <Button variant="outline" onClick={close} disabled={busy}>
              {t("common.cancel")}
            </Button>
            <Button
              variant={kind === "reject" ? "destructive" : "default"}
              loading={busy}
              onClick={
                kind === "approve"
                  ? handleApprove
                  : kind === "reject"
                    ? handleReject
                    : handleRequestDocuments
              }
            >
              {kind === "approve"
                ? t("applications.approve")
                : kind === "reject"
                  ? t("applications.reject")
                  : t("applications.requestDocuments")}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
}