"use client";

import { useEffect, useMemo, useState } from "react";
import { useMutation } from "@tanstack/react-query";
import { useTranslations } from "next-intl";
import { ChevronLeft, ChevronRight, X } from "lucide-react";
import { apiPatch, apiPost, ApiClientError } from "@/lib/api/client";
import type { Customer, CustomerGroup } from "@/lib/api/types";
import { useIsRtl } from "@/lib/use-is-rtl";
import { formatNumber } from "@/lib/format";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { LabeledField } from "@/components/ui/labeled-field";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";

const GROUPS: CustomerGroup[] = ["Regular", "Vip", "New", "Employee"];
const STEP_COUNT = 4;

export type CustomerWizardMode = "create" | "edit";

type CustomerWizardProps = {
  open: boolean;
  mode: CustomerWizardMode;
  cafeId: string;
  customer?: Customer | null;
  onClose: () => void;
  onSaved: () => void;
};

type FormState = {
  name: string;
  phone: string;
  nationalId: string;
  birthDateJalali: string;
  group: CustomerGroup;
  loyaltyPoints: string;
  referredBy: string;
};

function emptyForm(): FormState {
  return {
    name: "",
    phone: "",
    nationalId: "",
    birthDateJalali: "",
    group: "Regular",
    loyaltyPoints: "0",
    referredBy: "",
  };
}

function fromCustomer(c: Customer): FormState {
  return {
    name: c.name,
    phone: c.phone,
    nationalId: c.nationalId ?? "",
    birthDateJalali: c.birthDateJalali ?? "",
    group: c.group,
    loyaltyPoints: String(c.loyaltyPoints),
    referredBy: c.referredBy ?? "",
  };
}

export function CustomerWizard({
  open,
  mode,
  cafeId,
  customer,
  onClose,
  onSaved,
}: CustomerWizardProps) {
  const t = useTranslations("crm.wizard");
  const tCrm = useTranslations("crm");
  const tCommon = useTranslations("common");
  const isRtl = useIsRtl();
  const numberLocale = isRtl ? "fa-IR" : "en-US";

  const [step, setStep] = useState(1);
  const [form, setForm] = useState<FormState>(emptyForm);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (!open) return;
    setStep(1);
    setError(null);
    setForm(mode === "edit" && customer ? fromCustomer(customer) : emptyForm());
  }, [open, mode, customer]);

  const stepLabels = useMemo(
    () => [t("steps.contact"), t("steps.profile"), t("steps.loyalty"), t("steps.confirm")],
    [t]
  );

  const canNext = () => {
    if (step === 1) return form.name.trim().length > 0 && form.phone.trim().length >= 10;
    return true;
  };

  const save = useMutation({
    mutationFn: async () => {
      const loyalty = parseInt(form.loyaltyPoints, 10) || 0;
      if (mode === "create") {
        return apiPost<Customer>(`/api/cafes/${cafeId}/customers`, {
          name: form.name.trim(),
          phone: form.phone.trim(),
          nationalId: form.nationalId.trim() || undefined,
          birthDateJalali: form.birthDateJalali.trim() || undefined,
          group: form.group,
          referredBy: form.referredBy.trim() || undefined,
        });
      }
      if (!customer?.id) throw new Error("missing customer");
      return apiPatch<Customer>(`/api/cafes/${cafeId}/customers/${customer.id}`, {
        name: form.name.trim(),
        phone: form.phone.trim(),
        nationalId: form.nationalId.trim() || undefined,
        birthDateJalali: form.birthDateJalali.trim() || undefined,
        group: form.group,
        loyaltyPoints: loyalty,
        referredBy: form.referredBy.trim() || undefined,
      });
    },
    onSuccess: () => {
      onSaved();
      onClose();
    },
    onError: (err: Error) => {
      const code = err instanceof ApiClientError ? err.code : "";
      if (code === "DUPLICATE_PHONE") setError(t("errors.duplicatePhone"));
      else setError(t("errors.generic"));
    },
  });

  if (!open) return null;

  const BackIcon = isRtl ? ChevronRight : ChevronLeft;
  const NextIcon = isRtl ? ChevronLeft : ChevronRight;

  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4"
      role="dialog"
      aria-modal="true"
      aria-labelledby="customer-wizard-title"
    >
      <Card className="flex max-h-[min(90dvh,640px)] w-full max-w-lg flex-col overflow-hidden shadow-xl">
        <CardHeader className="shrink-0 space-y-3 border-b border-border/80 pb-4">
          <div className="flex items-start justify-between gap-2">
            <div>
              <CardTitle id="customer-wizard-title" className="text-lg">
                {mode === "create" ? t("titleCreate") : t("titleEdit")}
              </CardTitle>
              <p className="mt-1 text-sm text-muted-foreground">
                {t("stepOf", { current: step, total: STEP_COUNT })}
              </p>
            </div>
            <Button type="button" size="icon" variant="ghost" onClick={onClose} aria-label={tCommon("cancel")}>
              <X className="h-4 w-4" />
            </Button>
          </div>
          <div className="flex gap-1">
            {stepLabels.map((label, i) => {
              const n = i + 1;
              return (
                <div
                  key={label}
                  className={cn(
                    "h-1 flex-1 rounded-full transition-colors",
                    n <= step ? "bg-[#0F6E56]" : "bg-muted"
                  )}
                  title={label}
                />
              );
            })}
          </div>
          <p className="text-[11px] font-medium uppercase tracking-[0.06em] text-muted-foreground">
            {stepLabels[step - 1]}
          </p>
        </CardHeader>

        <CardContent className="min-h-0 flex-1 overflow-y-auto py-4">
          {error ? (
            <p className="mb-3 rounded-md border border-[#A32D2D]/30 bg-red-50 px-3 py-2 text-sm text-[#A32D2D]">
              {error}
            </p>
          ) : null}

          {step === 1 && (
            <div className="space-y-3">
              <LabeledField label={tCrm("name")} htmlFor="wiz-name">
                <Input
                  id="wiz-name"
                  value={form.name}
                  onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))}
                  autoFocus
                />
              </LabeledField>
              <LabeledField label={tCrm("phone")} htmlFor="wiz-phone">
                <Input
                  id="wiz-phone"
                  value={form.phone}
                  onChange={(e) => setForm((f) => ({ ...f, phone: e.target.value }))}
                  dir="ltr"
                  className="text-end"
                  inputMode="tel"
                />
              </LabeledField>
            </div>
          )}

          {step === 2 && (
            <div className="space-y-3">
              <LabeledField label={tCrm("nationalId")} htmlFor="wiz-national-id">
                <Input
                  id="wiz-national-id"
                  value={form.nationalId}
                  onChange={(e) => setForm((f) => ({ ...f, nationalId: e.target.value }))}
                  dir="ltr"
                  className="text-end"
                  maxLength={10}
                  inputMode="numeric"
                />
              </LabeledField>
              <LabeledField label={tCrm("birthDate")} htmlFor="wiz-birth" hint={t("birthHint")}>
                <Input
                  id="wiz-birth"
                  value={form.birthDateJalali}
                  onChange={(e) => setForm((f) => ({ ...f, birthDateJalali: e.target.value }))}
                  dir="ltr"
                  className="text-end"
                  placeholder="1400/01/01"
                />
              </LabeledField>
            </div>
          )}

          {step === 3 && (
            <div className="space-y-3">
              <LabeledField label={tCrm("group")} htmlFor="wiz-group">
                <select
                  id="wiz-group"
                  className="w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
                  value={form.group}
                  onChange={(e) =>
                    setForm((f) => ({ ...f, group: e.target.value as CustomerGroup }))
                  }
                >
                  {GROUPS.map((g) => (
                    <option key={g} value={g}>
                      {tCrm(`groups.${g}`)}
                    </option>
                  ))}
                </select>
              </LabeledField>
              <LabeledField label={tCrm("loyaltyPoints")} htmlFor="wiz-points">
                <Input
                  id="wiz-points"
                  value={form.loyaltyPoints}
                  onChange={(e) => setForm((f) => ({ ...f, loyaltyPoints: e.target.value }))}
                  inputMode="numeric"
                  dir="ltr"
                  className="text-end"
                  disabled={mode === "create"}
                />
              </LabeledField>
              {mode === "create" ? (
                <p className="text-xs text-muted-foreground">{t("loyaltyCreateHint")}</p>
              ) : null}
              <LabeledField label={t("referredBy")} htmlFor="wiz-referred">
                <Input
                  id="wiz-referred"
                  value={form.referredBy}
                  onChange={(e) => setForm((f) => ({ ...f, referredBy: e.target.value }))}
                  dir="ltr"
                  className="text-end"
                />
              </LabeledField>
            </div>
          )}

          {step === 4 && (
            <dl className="space-y-3 text-sm">
              <div className="flex justify-between gap-2 border-b border-border/60 pb-2">
                <dt className="text-muted-foreground">{tCrm("name")}</dt>
                <dd className="font-medium">{form.name}</dd>
              </div>
              <div className="flex justify-between gap-2 border-b border-border/60 pb-2">
                <dt className="text-muted-foreground">{tCrm("phone")}</dt>
                <dd className="font-mono" dir="ltr">
                  {form.phone}
                </dd>
              </div>
              {form.nationalId ? (
                <div className="flex justify-between gap-2 border-b border-border/60 pb-2">
                  <dt className="text-muted-foreground">{tCrm("nationalId")}</dt>
                  <dd dir="ltr">{form.nationalId}</dd>
                </div>
              ) : null}
              {form.birthDateJalali ? (
                <div className="flex justify-between gap-2 border-b border-border/60 pb-2">
                  <dt className="text-muted-foreground">{tCrm("birthDate")}</dt>
                  <dd dir="ltr">{form.birthDateJalali}</dd>
                </div>
              ) : null}
              <div className="flex justify-between gap-2 border-b border-border/60 pb-2">
                <dt className="text-muted-foreground">{tCrm("group")}</dt>
                <dd>
                  <Badge variant="secondary">{tCrm(`groups.${form.group}`)}</Badge>
                </dd>
              </div>
              <div className="flex justify-between gap-2">
                <dt className="text-muted-foreground">{tCrm("loyaltyPoints")}</dt>
                <dd>{formatNumber(parseInt(form.loyaltyPoints, 10) || 0, numberLocale)}</dd>
              </div>
            </dl>
          )}
        </CardContent>

        <div className="flex shrink-0 gap-2 border-t border-border/80 p-4">
          {step > 1 ? (
            <Button type="button" variant="outline" onClick={() => setStep((s) => s - 1)}>
              <BackIcon className="me-1 h-4 w-4" />
              {t("back")}
            </Button>
          ) : (
            <Button type="button" variant="outline" onClick={onClose}>
              {tCommon("cancel")}
            </Button>
          )}
          <div className="flex-1" />
          {step < STEP_COUNT ? (
            <Button
              type="button"
              className="bg-[#0F6E56] hover:bg-[#0c5a46]"
              disabled={!canNext()}
              onClick={() => {
                setError(null);
                setStep((s) => s + 1);
              }}
            >
              {t("next")}
              <NextIcon className="ms-1 h-4 w-4" />
            </Button>
          ) : (
            <Button
              type="button"
              className="bg-[#0F6E56] hover:bg-[#0c5a46]"
              disabled={save.isPending}
              onClick={() => {
                setError(null);
                save.mutate();
              }}
            >
              {save.isPending ? tCommon("loading") : tCommon("save")}
            </Button>
          )}
        </div>
      </Card>
    </div>
  );
}
