"use client";

import { useMemo, useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useLocale, useTranslations } from "next-intl";
import { FilePen, Loader2, Plus, Trash2 } from "lucide-react";
import { apiGet, apiGetPaged, apiPost } from "@/lib/api/client";
import { notify, notifyError } from "@/lib/notify";
import { useAuthStore } from "@/lib/stores/auth.store";
import { formatCurrency, formatNumber } from "@/lib/format";
import { isoTodayTehran } from "@/lib/reports/analytics";
import type { Order, PaymentLine } from "@/lib/api/types";
import { Button } from "@/components/ui/button";
import { MoneyInput } from "@/components/ui/money-input";
import { JalaliDateField } from "@/components/ui/jalali-date-field";
import { LabeledField } from "@/components/ui/labeled-field";
import { Card, CardContent } from "@/components/ui/card";
import { cn } from "@/lib/utils";

type Branch = { id: string; name: string };
type Method = "Cash" | "Card" | "Credit";
type ReplacementRow = { method: Method; amount: string };

const METHODS: Method[] = ["Cash", "Card", "Credit"];

function methodKey(method: string): string {
  return method.charAt(0).toLowerCase() + method.slice(1);
}

export function PaymentCorrectionsTab() {
  const t = useTranslations("reports.corrections");
  const tMethods = useTranslations("reports");
  const locale = useLocale();
  const numberLocale = locale === "en" ? "en-US" : "fa-IR";
  const cafeId = useAuthStore((s) => s.user?.cafeId);
  const queryClient = useQueryClient();

  const [date, setDate] = useState<string>(() => isoTodayTehran());
  const [branchId, setBranchId] = useState<string>("");
  const [page, setPage] = useState(1);
  const [target, setTarget] = useState<Order | null>(null);

  const { data: branches = [] } = useQuery({
    queryKey: ["branches", cafeId],
    queryFn: () => apiGet<Branch[]>(`/api/cafes/${cafeId}/branches`),
    enabled: !!cafeId,
  });

  const queryString = useMemo(() => {
    const params = new URLSearchParams({ date, page: String(page), pageSize: "30" });
    if (branchId) params.set("branchId", branchId);
    return params.toString();
  }, [date, branchId, page]);

  const { data, isLoading, isError, refetch } = useQuery({
    queryKey: ["closed-orders", cafeId, queryString],
    queryFn: () => apiGetPaged<Order>(`/api/cafes/${cafeId}/orders/closed?${queryString}`),
    enabled: !!cafeId,
  });

  const orders = data?.items ?? [];
  const total = data?.meta.total ?? 0;
  const totalPages = Math.max(1, Math.ceil(total / 30));

  const timeFormatter = useMemo(
    () =>
      new Intl.DateTimeFormat(numberLocale, {
        hour: "2-digit",
        minute: "2-digit",
        hour12: false,
      }),
    [numberLocale]
  );

  if (!cafeId) return null;

  return (
    <div className="space-y-4">
      <Card className="rounded-xl border border-border/80 bg-card">
        <CardContent className="flex flex-wrap items-end gap-4 pt-6">
          <LabeledField label={t("date")} htmlFor="corr-date">
            <JalaliDateField
              id="corr-date"
              className="w-40"
              value={date}
              onChange={(iso) => {
                setDate(iso);
                setPage(1);
              }}
            />
          </LabeledField>
          {branches.length > 1 ? (
            <LabeledField label={t("branch")} htmlFor="corr-branch">
              <select
                id="corr-branch"
                className="h-9 min-w-[10rem] rounded-md border border-input bg-background px-3 text-sm"
                value={branchId}
                onChange={(e) => {
                  setBranchId(e.target.value);
                  setPage(1);
                }}
              >
                <option value="">{t("allBranches")}</option>
                {branches.map((b) => (
                  <option key={b.id} value={b.id}>
                    {b.name}
                  </option>
                ))}
              </select>
            </LabeledField>
          ) : null}
          <p className="ms-auto text-xs text-muted-foreground">{t("hint")}</p>
        </CardContent>
      </Card>

      <Card className="rounded-xl border border-border/80 bg-card">
        <CardContent className="overflow-x-auto pt-6">
          {isLoading ? (
            <div className="flex items-center justify-center py-10 text-muted-foreground">
              <Loader2 className="size-5 animate-spin" />
            </div>
          ) : isError ? (
            <div className="flex flex-col items-center gap-3 py-8 text-center text-sm text-muted-foreground">
              <p>{t("loadFailed")}</p>
              <Button variant="outline" size="sm" onClick={() => refetch()}>
                {t("retry")}
              </Button>
            </div>
          ) : orders.length === 0 ? (
            <p className="py-8 text-center text-sm text-muted-foreground">{t("empty")}</p>
          ) : (
            <table className="w-full min-w-[40rem] text-sm">
              <thead>
                <tr className="border-b text-[11px] font-medium uppercase tracking-[0.06em] text-muted-foreground">
                  <th className="py-2 text-start">{t("colOrder")}</th>
                  <th className="py-2 text-start">{t("colTime")}</th>
                  <th className="py-2 text-start">{t("colStatus")}</th>
                  <th className="py-2 text-end">{t("colTotal")}</th>
                  <th className="py-2 text-start ps-6">{t("colPayments")}</th>
                  <th className="py-2 text-end" />
                </tr>
              </thead>
              <tbody>
                {orders.map((o) => {
                  const cancelled = o.status === "Cancelled";
                  return (
                    <tr key={o.id} className="border-b border-border/50">
                      <td className="py-2.5 font-medium">
                        #{formatNumber(o.displayNumber, numberLocale)}
                        {o.tableNumber ? (
                          <span className="ms-2 text-xs text-muted-foreground">
                            {t("table")} {o.tableNumber}
                          </span>
                        ) : null}
                      </td>
                      <td className="py-2.5 tabular-nums text-muted-foreground">
                        {timeFormatter.format(new Date(o.createdAt))}
                      </td>
                      <td className="py-2.5">
                        <span
                          className={cn(
                            "rounded-full px-2 py-0.5 text-xs font-medium",
                            cancelled
                              ? "bg-red-50 text-red-700"
                              : "bg-emerald-50 text-emerald-700"
                          )}
                        >
                          {cancelled ? t("statusCancelled") : t("statusPaid")}
                        </span>
                      </td>
                      <td className="py-2.5 text-end font-medium tabular-nums">
                        {formatCurrency(o.total, numberLocale)}
                      </td>
                      <td className="py-2.5 ps-6">
                        <div className="flex flex-wrap gap-1.5">
                          {o.payments.length === 0 ? (
                            <span className="text-xs text-muted-foreground">—</span>
                          ) : (
                            o.payments.map((p) => (
                              <span
                                key={p.id}
                                className={cn(
                                  "rounded-md border px-1.5 py-0.5 text-xs tabular-nums",
                                  p.status === "Refunded"
                                    ? "border-border/60 text-muted-foreground line-through"
                                    : "border-border"
                                )}
                              >
                                {tMethods(methodKey(p.method))} ·{" "}
                                {formatCurrency(p.amount, numberLocale)}
                              </span>
                            ))
                          )}
                        </div>
                      </td>
                      <td className="py-2.5 text-end">
                        {o.payments.some((p) => p.status === "Completed") ? (
                          <Button
                            variant="outline"
                            size="sm"
                            className="gap-1.5"
                            onClick={() => setTarget(o)}
                          >
                            <FilePen className="size-3.5" />
                            {t("correctAction")}
                          </Button>
                        ) : null}
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          )}

          {totalPages > 1 ? (
            <div className="flex items-center justify-center gap-3 pt-4">
              <Button
                variant="outline"
                size="sm"
                disabled={page <= 1}
                onClick={() => setPage((p) => p - 1)}
              >
                {t("prevPage")}
              </Button>
              <span className="text-xs tabular-nums text-muted-foreground">
                {formatNumber(page, numberLocale)} / {formatNumber(totalPages, numberLocale)}
              </span>
              <Button
                variant="outline"
                size="sm"
                disabled={page >= totalPages}
                onClick={() => setPage((p) => p + 1)}
              >
                {t("nextPage")}
              </Button>
            </div>
          ) : null}
        </CardContent>
      </Card>

      {target ? (
        <CorrectionDialog
          cafeId={cafeId}
          order={target}
          numberLocale={numberLocale}
          onClose={() => setTarget(null)}
          onDone={() => {
            setTarget(null);
            void queryClient.invalidateQueries({ queryKey: ["closed-orders", cafeId] });
            void queryClient.invalidateQueries({ queryKey: ["audit-logs", cafeId] });
          }}
        />
      ) : null}
    </div>
  );
}

function CorrectionDialog({
  cafeId,
  order,
  numberLocale,
  onClose,
  onDone,
}: {
  cafeId: string;
  order: Order;
  numberLocale: string;
  onClose: () => void;
  onDone: () => void;
}) {
  const t = useTranslations("reports.corrections");
  const tMethods = useTranslations("reports");

  const [voidIds, setVoidIds] = useState<Set<string>>(new Set());
  const [replacements, setReplacements] = useState<ReplacementRow[]>([]);
  const [reason, setReason] = useState("");

  const livePayments = order.payments.filter((p) => p.status === "Completed");

  const toggleVoid = (p: PaymentLine) => {
    setVoidIds((prev) => {
      const next = new Set(prev);
      if (next.has(p.id)) next.delete(p.id);
      else next.add(p.id);
      return next;
    });
  };

  const addReplacement = () =>
    setReplacements((rows) => [...rows, { method: "Cash", amount: "" }]);
  const removeReplacement = (i: number) =>
    setReplacements((rows) => rows.filter((_, idx) => idx !== i));
  const patchReplacement = (i: number, patch: Partial<ReplacementRow>) =>
    setReplacements((rows) => rows.map((r, idx) => (idx === i ? { ...r, ...patch } : r)));

  const keptAmount = livePayments
    .filter((p) => !voidIds.has(p.id))
    .reduce((s, p) => s + p.amount, 0);
  const replacementAmount = replacements.reduce(
    (s, r) => s + (Number(r.amount) > 0 ? Number(r.amount) : 0),
    0
  );
  const paidAfter = keptAmount + replacementAmount;
  const delta = paidAfter - order.total;

  const valid =
    reason.trim().length >= 3 &&
    (voidIds.size > 0 || replacements.length > 0) &&
    replacements.every((r) => Number(r.amount) > 0);

  const mutation = useMutation({
    mutationFn: () =>
      apiPost(`/api/cafes/${cafeId}/orders/${order.id}/payments/corrections`, {
        voidPaymentIds: Array.from(voidIds),
        replacements: replacements.map((r) => ({
          method: r.method,
          amount: Number(r.amount),
          reference: null,
        })),
        reason: reason.trim(),
      }),
    onSuccess: () => {
      notify.success(t("saved"));
      onDone();
    },
    onError: (err) => notifyError(err, t("saveFailed")),
  });

  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4"
      role="dialog"
      aria-modal="true"
      aria-labelledby="correction-modal-title"
    >
      <Card className="flex max-h-[90vh] w-full max-w-lg flex-col overflow-hidden rounded-xl border border-border/80 bg-card shadow-lg">
        <div className="border-b border-border px-5 py-4">
          <h2 id="correction-modal-title" className="text-base font-semibold">
            {t("dialogTitle")} — #{formatNumber(order.displayNumber, numberLocale)}
          </h2>
          <p className="mt-0.5 text-xs text-muted-foreground">
            {t("orderTotal")}: {formatCurrency(order.total, numberLocale)}
          </p>
        </div>

        <div className="min-h-0 flex-1 space-y-5 overflow-y-auto px-5 py-4">
          {/* Payments to void */}
          <section>
            <h3 className="mb-2 text-sm font-medium">{t("voidSection")}</h3>
            <div className="space-y-1.5">
              {livePayments.map((p) => (
                <label
                  key={p.id}
                  className="flex cursor-pointer items-center gap-3 rounded-lg border border-border px-3 py-2.5 text-sm transition-colors hover:bg-accent/40"
                >
                  <input
                    type="checkbox"
                    className="size-4 accent-primary"
                    checked={voidIds.has(p.id)}
                    onChange={() => toggleVoid(p)}
                  />
                  <span className={cn(voidIds.has(p.id) && "line-through opacity-60")}>
                    {tMethods(methodKey(p.method))} — {formatCurrency(p.amount, numberLocale)}
                  </span>
                </label>
              ))}
            </div>
          </section>

          {/* Replacements */}
          <section>
            <div className="mb-2 flex items-center justify-between">
              <h3 className="text-sm font-medium">{t("replacementSection")}</h3>
              <Button variant="outline" size="sm" className="gap-1" onClick={addReplacement}>
                <Plus className="size-3.5" />
                {t("addReplacement")}
              </Button>
            </div>
            {replacements.length === 0 ? (
              <p className="text-xs text-muted-foreground">{t("noReplacements")}</p>
            ) : (
              <div className="space-y-2">
                {replacements.map((r, i) => (
                  <div key={i} className="flex items-center gap-2">
                    <select
                      aria-label={t("method")}
                      className="h-9 rounded-md border border-input bg-background px-2 text-sm"
                      value={r.method}
                      onChange={(e) => patchReplacement(i, { method: e.target.value as Method })}
                    >
                      {METHODS.map((m) => (
                        <option key={m} value={m}>
                          {tMethods(methodKey(m))}
                        </option>
                      ))}
                    </select>
                    <MoneyInput
                      placeholder={t("amount")}
                      className="h-9 flex-1"
                      value={r.amount}
                      onValueChange={(raw) => patchReplacement(i, { amount: raw })}
                    />
                    <Button
                      variant="ghost"
                      size="sm"
                      className="h-9 w-9 p-0 text-muted-foreground hover:text-destructive"
                      onClick={() => removeReplacement(i)}
                      aria-label={t("removeReplacement")}
                    >
                      <Trash2 className="size-4" />
                    </Button>
                  </div>
                ))}
              </div>
            )}
          </section>

          {/* Reason */}
          <section>
            <LabeledField label={t("reason")} htmlFor="corr-reason">
              <textarea
                id="corr-reason"
                rows={2}
                className="w-full rounded-md border border-input bg-background px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-primary/40"
                placeholder={t("reasonPlaceholder")}
                value={reason}
                onChange={(e) => setReason(e.target.value)}
              />
            </LabeledField>
          </section>

          {/* Balance summary */}
          <div className="rounded-lg bg-muted/60 px-3 py-2.5 text-sm">
            <div className="flex justify-between">
              <span className="text-muted-foreground">{t("paidAfter")}</span>
              <span className="font-medium tabular-nums">
                {formatCurrency(paidAfter, numberLocale)}
              </span>
            </div>
            {delta !== 0 ? (
              <div className="mt-1 flex justify-between text-xs">
                <span className="text-muted-foreground">
                  {delta < 0 ? t("shortBy") : t("overBy")}
                </span>
                <span
                  className={cn(
                    "tabular-nums font-medium",
                    delta < 0 ? "text-amber-600" : "text-sky-600"
                  )}
                >
                  {formatCurrency(Math.abs(delta), numberLocale)}
                </span>
              </div>
            ) : null}
          </div>
        </div>

        <div className="flex justify-end gap-2 border-t border-border px-5 py-3">
          <Button variant="ghost" onClick={onClose} disabled={mutation.isPending}>
            {t("cancel")}
          </Button>
          <Button
            onClick={() => mutation.mutate()}
            disabled={!valid || mutation.isPending}
            className="gap-1.5"
          >
            {mutation.isPending ? <Loader2 className="size-4 animate-spin" /> : null}
            {t("submit")}
          </Button>
        </div>
      </Card>
    </div>
  );
}
