"use client";

import { useEffect, useState } from "react";
import { useQuery, useMutation } from "@tanstack/react-query";
import { useTranslations } from "next-intl";
import { ChevronDown, Search, UserPlus, X } from "lucide-react";
import { apiGet, apiPost, ApiClientError } from "@/lib/api/client";
import type { Customer } from "@/lib/api/types";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { LabeledField } from "@/components/ui/labeled-field";
import { cn } from "@/lib/utils";

type CustomerMode = "existing" | "new";

type PosCustomerPickerProps = {
  cafeId: string;
  guestName: string;
  guestPhone: string;
  customerId: string | null;
  onGuestNameChange: (value: string) => void;
  onGuestPhoneChange: (value: string) => void;
  onCustomerChange: (customer: Customer | null) => void;
  onClearCustomer: () => void;
  /** Collapsed header in POS sidebar to leave room for cart lines */
  compact?: boolean;
};

export function PosCustomerPicker({
  cafeId,
  guestName,
  guestPhone,
  customerId,
  onGuestNameChange,
  onGuestPhoneChange,
  onCustomerChange,
  onClearCustomer,
  compact = false,
}: PosCustomerPickerProps) {
  const t = useTranslations("pos");
  const tCrm = useTranslations("crm");
  const tCommon = useTranslations("common");

  const [expanded, setExpanded] = useState(!compact);
  const [mode, setMode] = useState<CustomerMode>(customerId ? "existing" : "new");
  const [search, setSearch] = useState("");
  const [debouncedSearch, setDebouncedSearch] = useState("");
  const [message, setMessage] = useState<string | null>(null);
  const [highlightIndex, setHighlightIndex] = useState(-1);

  useEffect(() => {
    const id = setTimeout(() => setDebouncedSearch(search.trim()), 300);
    return () => clearTimeout(id);
  }, [search]);

  const pickCustomer = (c: Customer) => {
    onCustomerChange(c);
    setSearch("");
    setMessage(null);
    setHighlightIndex(-1);
  };

  const handleSearchKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (results.length === 0) return;
    if (e.key === "ArrowDown") {
      e.preventDefault();
      setHighlightIndex((i) => (i < results.length - 1 ? i + 1 : 0));
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      setHighlightIndex((i) => (i > 0 ? i - 1 : results.length - 1));
    } else if (e.key === "Enter" && highlightIndex >= 0) {
      e.preventDefault();
      pickCustomer(results[highlightIndex]!);
    }
  };

  useEffect(() => {
    if (customerId) setMode("existing");
  }, [customerId]);

  const { data: results = [], isFetching } = useQuery({
    queryKey: ["customers", cafeId, debouncedSearch],
    queryFn: () =>
      apiGet<Customer[]>(
        `/api/cafes/${cafeId}/customers?q=${encodeURIComponent(debouncedSearch)}`
      ),
    enabled: !!cafeId && mode === "existing" && debouncedSearch.length >= 2,
  });

  useEffect(() => {
    setHighlightIndex(-1);
  }, [debouncedSearch, results.length]);

  const createCustomer = useMutation({
    mutationFn: () =>
      apiPost<Customer>(`/api/cafes/${cafeId}/customers`, {
        name: guestName.trim(),
        phone: guestPhone.trim(),
        group: "New",
      }),
    onSuccess: (customer) => {
      onCustomerChange(customer);
      setMode("existing");
      setMessage(t("customerSaved"));
    },
    onError: (err: Error) => {
      if (err instanceof ApiClientError && err.code === "DUPLICATE_PHONE") {
        setMessage(t("customerPhoneExists"));
        return;
      }
      setMessage(t("customerSaveError"));
    },
  });

  const switchMode = (next: CustomerMode) => {
    setMode(next);
    setMessage(null);
    if (next === "new") {
      onClearCustomer();
    }
  };

  const canSaveNew =
    guestName.trim().length > 0 &&
    /^09\d{9}$/.test(guestPhone.trim()) &&
    !customerId;

  const summaryLabel =
    guestName.trim() || guestPhone.trim()
      ? `${guestName.trim() || "—"}${guestPhone.trim() ? ` · ${guestPhone.trim()}` : ""}`
      : t("customerSection");

  return (
    <div className={cn("space-y-2", compact && !expanded && "space-y-1")}>
      {compact ? (
        <button
          type="button"
          className="flex w-full items-center justify-between gap-2 rounded-md border border-border/80 bg-muted/30 px-2 py-1.5 text-start"
          onClick={() => setExpanded((v) => !v)}
        >
          <span className="min-w-0 truncate text-xs font-medium">{summaryLabel}</span>
          <ChevronDown
            className={cn(
              "h-4 w-4 shrink-0 text-muted-foreground transition-transform",
              expanded && "rotate-180"
            )}
          />
        </button>
      ) : (
        <p className="text-xs font-medium text-muted-foreground">{t("customerSection")}</p>
      )}

      {compact && !expanded ? null : (
        <>
      <div className="flex gap-1 rounded-lg border border-border p-0.5">
        <button
          type="button"
          className={cn(
            "flex-1 rounded-md px-2 py-1.5 text-xs font-medium transition",
            mode === "existing"
              ? "bg-primary text-primary-foreground"
              : "text-muted-foreground hover:bg-muted"
          )}
          onClick={() => switchMode("existing")}
        >
          {t("existingCustomer")}
        </button>
        <button
          type="button"
          className={cn(
            "flex-1 rounded-md px-2 py-1.5 text-xs font-medium transition",
            mode === "new"
              ? "bg-primary text-primary-foreground"
              : "text-muted-foreground hover:bg-muted"
          )}
          onClick={() => switchMode("new")}
        >
          {t("newCustomer")}
        </button>
      </div>

      {customerId ? (
        <div className="flex items-center justify-between gap-2 rounded-md border border-[#0F6E56]/30 bg-[#E1F5EE] px-2 py-1.5">
          <div className="min-w-0">
            <p className="truncate text-sm font-medium text-[#0F6E56]">{guestName}</p>
            <p className="truncate text-xs text-muted-foreground" dir="ltr">
              {guestPhone}
            </p>
          </div>
          <Button
            type="button"
            size="icon"
            variant="ghost"
            className="h-7 w-7 shrink-0"
            onClick={() => {
              onClearCustomer();
              onGuestNameChange("");
              onGuestPhoneChange("");
              setMode("new");
            }}
          >
            <X className="h-3.5 w-3.5" />
          </Button>
        </div>
      ) : null}

      {mode === "existing" && !customerId ? (
        <div className="space-y-2">
          <LabeledField label={tCommon("search")} htmlFor="pos-customer-search">
            <div className="relative">
              <Search className="absolute start-2 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
              <Input
                id="pos-customer-search"
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                onKeyDown={handleSearchKeyDown}
                placeholder={t("customerSearchPlaceholder")}
                className={cn("ps-8", compact && "h-8 text-sm")}
                role="combobox"
                aria-expanded={results.length > 0 && debouncedSearch.length >= 2}
                aria-activedescendant={
                  highlightIndex >= 0 ? `pos-customer-opt-${highlightIndex}` : undefined
                }
              />
            </div>
          </LabeledField>
          {debouncedSearch.length < 2 ? (
            <p className="text-[11px] text-muted-foreground">{t("customerSearchHint")}</p>
          ) : isFetching ? (
            <p className="text-[11px] text-muted-foreground">{tCommon("loading")}</p>
          ) : results.length === 0 ? (
            <p className="text-[11px] text-muted-foreground">{t("customerNotFound")}</p>
          ) : (
            <ul
              className={cn(
                "space-y-1 overflow-y-auto overscroll-contain",
                compact ? "max-h-24" : "max-h-32"
              )}
            >
              {results.map((c, idx) => (
                <li key={c.id} id={`pos-customer-opt-${idx}`}>
                  <button
                    type="button"
                    className={cn(
                      "flex w-full items-center justify-between gap-2 rounded-md border px-2 py-1.5 text-start text-sm transition",
                      idx === highlightIndex
                        ? "border-primary bg-primary/10"
                        : "border-border/80 hover:border-primary hover:bg-muted/40"
                    )}
                    onClick={() => pickCustomer(c)}
                  >
                    <span className="min-w-0 truncate font-medium">{c.name}</span>
                    <span className="shrink-0 text-xs text-muted-foreground" dir="ltr">
                      {c.phone}
                    </span>
                  </button>
                </li>
              ))}
            </ul>
          )}
        </div>
      ) : null}

      {mode === "new" && !customerId ? (
        <form
          className="space-y-2"
          onSubmit={(e) => {
            e.preventDefault();
            if (canSaveNew && !createCustomer.isPending) createCustomer.mutate();
          }}
        >
          <LabeledField label={t("guestName")} htmlFor="pos-guest">
            <Input
              id="pos-guest"
              value={guestName}
              onChange={(e) => onGuestNameChange(e.target.value)}
              placeholder={t("guestNamePlaceholder")}
              className={compact ? "h-8 text-sm" : undefined}
            />
          </LabeledField>
          <LabeledField label={t("guestPhone")} htmlFor="pos-phone">
            <Input
              id="pos-phone"
              value={guestPhone}
              onChange={(e) => onGuestPhoneChange(e.target.value)}
              placeholder={t("guestPhonePlaceholder")}
              dir="ltr"
              className={cn("text-end", compact && "h-8 text-sm")}
            />
          </LabeledField>
          <Button
            type="submit"
            variant="outline"
            size="sm"
            className="w-full"
            disabled={!canSaveNew || createCustomer.isPending}
          >
            <UserPlus className="me-1.5 h-3.5 w-3.5" />
            {createCustomer.isPending ? "..." : tCrm("addCustomer")}
          </Button>
          {!compact ? (
            <p className="text-[10px] text-muted-foreground">{t("newCustomerHint")}</p>
          ) : null}
        </form>
      ) : null}

      {message ? (
        <p className="text-center text-xs text-primary">{message}</p>
      ) : null}
        </>
      )}
    </div>
  );
}
