"use client";

import { Pencil, Trash2 } from "lucide-react";
import { useCallback, useState } from "react";
import { useExportLabels } from "@/hooks/use-export-labels";
import { useTranslation } from "react-i18next";
import { useAsyncEffect } from "@/hooks/use-async-effect";
import { useTranslationRef } from "@/hooks/use-translation-ref";
import { toast } from "sonner";

import {
  deleteAdminCurrency,
  getAdminCurrencies,
  postAdminCurrency,
  putAdminCurrency,
} from "@/api/admin-currencies";
import { AdminTableNoResourceRow } from "@/components/admin/admin-no-resource-state";
import { AdminPageCard } from "@/components/admin/admin-page-card";
import { AdminRowActionsMenu } from "@/components/admin/admin-row-actions-menu";
import { AdminStatusBadge } from "@/components/admin/admin-status-badge";
import { Button } from "@/components/ui/button";
import { AdminTableExportButton } from "@/components/admin/admin-table-export-button";
import { Switch } from "@/components/ui/switch";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { adminHasAnyPermission } from "@/lib/admin-permissions";
import { useAdminProfile } from "@/stores/admin-session";
import { LotteryApiBizError } from "@/types/api/errors";
import type { AdminCurrencyRow } from "@/types/api/admin-currency";

type CurrencyFormState = {
  code: string;
  name: string;
  is_enabled: boolean;
  is_bettable: boolean;
};

const EMPTY_FORM: CurrencyFormState = {
  code: "",
  name: "",
  is_enabled: true,
  is_bettable: false,
};

function toFormState(row: AdminCurrencyRow): CurrencyFormState {
  return {
    code: row.code,
    name: row.name,
    is_enabled: row.is_enabled,
    is_bettable: row.is_enabled && row.is_bettable,
  };
}

export function CurrencySettingsPanel() {
  const { t } = useTranslation(["config", "adminUsers"]);
  const tRef = useTranslationRef(["config", "adminUsers"]);
  const exportLabels = useExportLabels("currencies");
  const profile = useAdminProfile();
  const canManage = adminHasAnyPermission(profile?.permissions, ["prd.currency.manage"]);
  const [items, setItems] = useState<AdminCurrencyRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [dialogOpen, setDialogOpen] = useState(false);
  const [mode, setMode] = useState<"create" | "edit">("create");
  const [editingCode, setEditingCode] = useState<string | null>(null);
  const [form, setForm] = useState<CurrencyFormState>(EMPTY_FORM);
  const [deleteTarget, setDeleteTarget] = useState<AdminCurrencyRow | null>(null);
  const [deleteBusy, setDeleteBusy] = useState(false);

  const load = useCallback(async () => {
    if (!canManage) {
      setItems([]);
      setLoading(false);
      return;
    }

    setLoading(true);
    try {
      const data = await getAdminCurrencies();
      setItems(data.items);
    } catch (error) {
      toast.error(
        error instanceof LotteryApiBizError
          ? error.message
          : tRef.current("currencies.loadFailed", { ns: "config" }),
      );
    } finally {
      setLoading(false);
    }
  }, [canManage, tRef]);

  useAsyncEffect(() => {
    void load();
  }, [canManage]);

  function openCreate(): void {
    setMode("create");
    setEditingCode(null);
    setForm(EMPTY_FORM);
    setDialogOpen(true);
  }

  function openEdit(row: AdminCurrencyRow): void {
    setMode("edit");
    setEditingCode(row.code);
    setForm(toFormState(row));
    setDialogOpen(true);
  }

  function updateForm<K extends keyof CurrencyFormState>(key: K, value: CurrencyFormState[K]): void {
    setForm((prev) => {
      const next = { ...prev, [key]: value };
      if (key === "is_enabled" && value === false) {
        next.is_bettable = false;
      }
      return next;
    });
  }

  async function handleSubmit(): Promise<void> {
    const payload = {
      name: form.name.trim(),
      is_enabled: form.is_enabled,
      is_bettable: form.is_enabled && form.is_bettable,
    };

    if (mode === "create") {
      if (form.code.trim() === "" || payload.name === "") {
        toast.error(t("currencies.form.required", { ns: "config" }));
        return;
      }
    }

    setSaving(true);
    try {
      if (mode === "create") {
        await postAdminCurrency({
          code: form.code.trim().toUpperCase(),
          ...payload,
        });
        toast.success(t("currencies.createSuccess", { ns: "config" }));
      } else if (editingCode !== null) {
        await putAdminCurrency(editingCode, payload);
        toast.success(t("currencies.updateSuccess", { ns: "config" }));
      }

      setDialogOpen(false);
      await load();
    } catch (error) {
      toast.error(
        error instanceof LotteryApiBizError
          ? error.message
          : t(mode === "create" ? "currencies.createFailed" : "currencies.updateFailed", { ns: "config" }),
      );
    } finally {
      setSaving(false);
    }
  }

  async function confirmDelete(): Promise<void> {
    if (deleteTarget === null) {
      return;
    }

    setDeleteBusy(true);
    try {
      await deleteAdminCurrency(deleteTarget.code);
      toast.success(t("currencies.deleteSuccess", { ns: "config", code: deleteTarget.code }));
      setDeleteTarget(null);
      await load();
    } catch (error) {
      toast.error(
        error instanceof LotteryApiBizError
          ? error.message
          : t("currencies.deleteFailed", { ns: "config" }),
      );
    } finally {
      setDeleteBusy(false);
    }
  }

  if (!canManage) {
    return null;
  }

  return (
    <>
      <AdminPageCard
        title={t("currencies.title", { ns: "config" })}
        description={t("currencies.description", { ns: "config" })}
        actions={
          <>
            <AdminTableExportButton
              tableId="admin-currencies-table"
              filename={exportLabels.filename}
              sheetName={exportLabels.sheetName}
            />
            <Button onClick={openCreate}>{t("currencies.actions.create", { ns: "config" })}</Button>
          </>
        }
      >
        <div className="admin-table-shell">
          <Table id="admin-currencies-table">
            <TableHeader>
              <TableRow>
                <TableHead className="whitespace-nowrap">{t("currencies.table.code", { ns: "config" })}</TableHead>
                <TableHead>{t("currencies.table.name", { ns: "config" })}</TableHead>
                <TableHead className="whitespace-nowrap">{t("currencies.table.enabled", { ns: "config" })}</TableHead>
                <TableHead className="whitespace-nowrap">{t("currencies.table.bettable", { ns: "config" })}</TableHead>
                <TableHead className="sticky right-0 z-20 bg-muted w-14 whitespace-nowrap text-center shadow-[-1px_0_0_rgba(203,213,225,0.7)]">{t("currencies.table.actions", { ns: "config" })}</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {loading ? (
                <TableRow>
                  <TableCell colSpan={5} className="text-center text-sm text-muted-foreground">
                    {t("currencies.loading", { ns: "config" })}
                  </TableCell>
                </TableRow>
              ) : items.length === 0 ? (
                <AdminTableNoResourceRow colSpan={5} cellClassName="text-center" />
              ) : (
                items.map((row) => (
                  <TableRow key={row.code}>
                    <TableCell className="font-mono">{row.code}</TableCell>
                    <TableCell>{row.name}</TableCell>
                    <TableCell>
                      <AdminStatusBadge status={row.is_enabled ? "enabled" : "disabled"}>
                        {row.is_enabled
                          ? t("system.states.enabled", { ns: "config" })
                          : t("system.states.disabled", { ns: "config" })}
                      </AdminStatusBadge>
                    </TableCell>
                    <TableCell>
                      <AdminStatusBadge
                        status={row.is_enabled && row.is_bettable ? "enabled" : "disabled"}
                      >
                        {row.is_enabled && row.is_bettable
                          ? t("system.states.enabled", { ns: "config" })
                          : t("system.states.disabled", { ns: "config" })}
                      </AdminStatusBadge>
                    </TableCell>
                    <TableCell className="sticky right-0 z-10 bg-card text-center shadow-[-1px_0_0_rgba(203,213,225,0.7)]">
                      <AdminRowActionsMenu
                        actions={[
                          {
                            key: "edit",
                            label: t("currencies.actions.edit", { ns: "config" }),
                            icon: Pencil,
                            onClick: () => openEdit(row),
                          },
                          {
                            key: "delete",
                            label: t("currencies.actions.delete", { ns: "config" }),
                            icon: Trash2,
                            destructive: true,
                            onClick: () => setDeleteTarget(row),
                          },
                        ]}
                      />
                    </TableCell>
                  </TableRow>
                ))
              )}
            </TableBody>
          </Table>
        </div>
      </AdminPageCard>

      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent showCloseButton className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>
              {t(mode === "create" ? "currencies.dialog.createTitle" : "currencies.dialog.editTitle", {
                ns: "config",
              })}
            </DialogTitle>
            <DialogDescription>
              {t("currencies.dialog.description", { ns: "config" })}
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-4">
            <div className="space-y-2">
              <Label htmlFor="currency-code">{t("currencies.form.code", { ns: "config" })}</Label>
              <Input
                id="currency-code"
                value={form.code}
                placeholder={t("currencies.form.codePlaceholder", { ns: "config" })}
                onChange={(e) => updateForm("code", e.target.value.toUpperCase())}
                disabled={saving || mode === "edit"}
              />
            </div>

            <div className="space-y-2">
              <Label htmlFor="currency-name">{t("currencies.form.name", { ns: "config" })}</Label>
              <Input
                id="currency-name"
                value={form.name}
                placeholder={t("currencies.form.namePlaceholder", { ns: "config" })}
                onChange={(e) => updateForm("name", e.target.value)}
                disabled={saving}
              />
            </div>

            <div className="flex items-center justify-between rounded-xl border border-border/70 p-3">
              <div className="space-y-1">
                <p className="text-sm font-medium">{t("currencies.form.enabled", { ns: "config" })}</p>
                <p className="text-xs text-muted-foreground">{t("currencies.form.enabledHint", { ns: "config" })}</p>
              </div>
              <Switch
                checked={form.is_enabled}
                onCheckedChange={(checked) => updateForm("is_enabled", checked)}
                disabled={saving}
                aria-label={t("currencies.form.enabled", { ns: "config" })}
              />
            </div>

            <div className="flex items-center justify-between rounded-xl border border-border/70 p-3">
              <div className="space-y-1">
                <p className="text-sm font-medium">{t("currencies.form.bettable", { ns: "config" })}</p>
                <p className="text-xs text-muted-foreground">{t("currencies.form.bettableHint", { ns: "config" })}</p>
              </div>
              <Switch
                checked={form.is_enabled && form.is_bettable}
                onCheckedChange={(checked) => updateForm("is_bettable", checked)}
                disabled={saving || !form.is_enabled}
                aria-label={t("currencies.form.bettable", { ns: "config" })}
              />
            </div>

            <div className="flex justify-end gap-3">
              <Button variant="outline" onClick={() => setDialogOpen(false)} disabled={saving}>
                {t("actions.cancel", { ns: "adminUsers" })}
              </Button>
              <Button onClick={() => void handleSubmit()} disabled={saving}>
                {saving ? t("saving", { ns: "adminUsers" }) : t("actions.save", { ns: "adminUsers" })}
              </Button>
            </div>
          </div>
        </DialogContent>
      </Dialog>

      <Dialog open={deleteTarget !== null} onOpenChange={(open) => !open && setDeleteTarget(null)}>
        <DialogContent showCloseButton className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>{t("currencies.deleteDialog.title", { ns: "config" })}</DialogTitle>
            <DialogDescription>
              {t("currencies.deleteDialog.description", {
                ns: "config",
                code: deleteTarget?.code ?? "",
              })}
            </DialogDescription>
          </DialogHeader>

          <div className="flex justify-end gap-3">
            <Button variant="outline" onClick={() => setDeleteTarget(null)} disabled={deleteBusy}>
              {t("actions.cancel", { ns: "adminUsers" })}
            </Button>
            <Button variant="destructive" onClick={() => void confirmDelete()} disabled={deleteBusy}>
              {deleteBusy ? t("deleting", { ns: "adminUsers" }) : t("currencies.actions.delete", { ns: "config" })}
            </Button>
          </div>
        </DialogContent>
      </Dialog>
    </>
  );
}
