"use client";

import { useActionState, useEffect, useState, useTransition } from "react";
import { Archive, ArchiveRestore, Loader2, Pencil, Trash2 } from "lucide-react";
import { toast } from "sonner";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogClose,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  archiveProstheticAction,
  deleteProstheticAction,
  updateProstheticAction,
} from "@/lib/appwrite/prosthetic-actions";
import {
  PROSTHETIC_TYPE_OPTIONS,
  initialProstheticActionState,
  initialProstheticFormState,
} from "@/lib/appwrite/prosthetic-types";
import type { Prosthetic } from "@/lib/appwrite/schema";

const TYPE_LABELS = Object.fromEntries(
  PROSTHETIC_TYPE_OPTIONS.map((o) => [o.value, o.label]),
) as Record<string, string>;

function formatMoney(amount: number, currency: string) {
  try {
    return new Intl.NumberFormat("tr-TR", { style: "currency", currency }).format(amount);
  } catch {
    return `${amount.toFixed(2)} ${currency}`;
  }
}

export function ProstheticsTable({
  rows,
  defaultCurrency,
}: {
  rows: Prosthetic[];
  defaultCurrency: string;
}) {
  if (rows.length === 0) {
    return (
      <p className="text-muted-foreground py-6 text-center text-sm">
        Henüz ürün eklemediniz. Sağdaki formdan ekleyebilirsiniz.
      </p>
    );
  }

  return (
    <Table>
      <TableHeader>
        <TableRow>
          <TableHead>Protez Adı</TableHead>
          <TableHead>Tür</TableHead>
          <TableHead className="text-right">Birim Fiyat</TableHead>
          <TableHead>Durum</TableHead>
          <TableHead className="text-right">İşlem</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {rows.map((r) => (
          <ProstheticRow key={r.$id} row={r} defaultCurrency={defaultCurrency} />
        ))}
      </TableBody>
    </Table>
  );
}

function ProstheticRow({
  row,
  defaultCurrency,
}: {
  row: Prosthetic;
  defaultCurrency: string;
}) {
  const [archiveState, archiveAction, archivePending] = useActionState(
    archiveProstheticAction,
    initialProstheticActionState,
  );
  const [deleteState, deleteAction, deletePending] = useActionState(
    deleteProstheticAction,
    initialProstheticActionState,
  );
  const [, startTransition] = useTransition();
  const [editOpen, setEditOpen] = useState(false);
  const [deleteOpen, setDeleteOpen] = useState(false);

  useEffect(() => {
    if (archiveState.ok) toast.success(row.archived ? "Aktifleştirildi." : "Arşivlendi.");
    else if (archiveState.error) toast.error(archiveState.error);
  }, [archiveState, row.archived]);

  useEffect(() => {
    if (deleteState.ok) {
      toast.success("Ürün silindi.");
      setDeleteOpen(false);
    } else if (deleteState.error) {
      toast.error(deleteState.error);
    }
  }, [deleteState]);

  return (
    <TableRow className={row.archived ? "opacity-60" : ""}>
      <TableCell className="font-medium">{row.name}</TableCell>
      <TableCell className="text-muted-foreground">
        {TYPE_LABELS[row.type] ?? row.type}
      </TableCell>
      <TableCell className="text-right tabular-nums">
        {formatMoney(row.unitPrice, row.currency || defaultCurrency)}
      </TableCell>
      <TableCell>
        {row.archived ? (
          <Badge variant="outline">Arşiv</Badge>
        ) : (
          <Badge variant="secondary">Aktif</Badge>
        )}
      </TableCell>
      <TableCell className="text-right">
        <div className="flex justify-end gap-1.5">
          <Button
            size="sm"
            variant="outline"
            onClick={() => setEditOpen(true)}
            disabled={archivePending || deletePending}
          >
            <Pencil className="size-4" />
          </Button>
          <form
            action={(fd) => {
              startTransition(() => archiveAction(fd));
            }}
          >
            <input type="hidden" name="id" value={row.$id} />
            <Button
              type="submit"
              size="sm"
              variant="outline"
              disabled={archivePending || deletePending}
            >
              {archivePending ? (
                <Loader2 className="size-4 animate-spin" />
              ) : row.archived ? (
                <ArchiveRestore className="size-4" />
              ) : (
                <Archive className="size-4" />
              )}
            </Button>
          </form>
          <Button
            size="sm"
            variant="outline"
            onClick={() => setDeleteOpen(true)}
            disabled={archivePending || deletePending}
          >
            <Trash2 className="size-4" />
          </Button>
        </div>

        <EditDialog
          row={row}
          defaultCurrency={defaultCurrency}
          open={editOpen}
          onOpenChange={setEditOpen}
        />
        <Dialog open={deleteOpen} onOpenChange={setDeleteOpen}>
          <DialogContent>
            <DialogHeader>
              <DialogTitle>Ürün silinsin mi?</DialogTitle>
              <DialogDescription>
                {row.name} kalıcı olarak silinecek. Mevcut işlerden bu ürünün referansı kaldırılmaz.
              </DialogDescription>
            </DialogHeader>
            <DialogFooter>
              <DialogClose asChild>
                <Button type="button" variant="outline">
                  Vazgeç
                </Button>
              </DialogClose>
              <form
                action={(fd) => {
                  startTransition(() => deleteAction(fd));
                }}
              >
                <input type="hidden" name="id" value={row.$id} />
                <Button type="submit" variant="destructive" disabled={deletePending}>
                  {deletePending ? (
                    <Loader2 className="size-4 animate-spin" />
                  ) : (
                    <Trash2 className="size-4" />
                  )}
                  Sil
                </Button>
              </form>
            </DialogFooter>
          </DialogContent>
        </Dialog>
      </TableCell>
    </TableRow>
  );
}

function EditDialog({
  row,
  defaultCurrency,
  open,
  onOpenChange,
}: {
  row: Prosthetic;
  defaultCurrency: string;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}) {
  const [state, action, pending] = useActionState(
    updateProstheticAction,
    initialProstheticFormState,
  );

  useEffect(() => {
    if (state.ok) {
      toast.success("Ürün güncellendi.");
      onOpenChange(false);
    } else if (state.error) {
      toast.error(state.error);
    }
  }, [state, onOpenChange]);

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Ürünü düzenle</DialogTitle>
          <DialogDescription>{row.name}</DialogDescription>
        </DialogHeader>
        <form action={action} className="grid gap-4">
          <input type="hidden" name="id" value={row.$id} />
          <div className="grid gap-2">
            <Label htmlFor={`edit-name-${row.$id}`}>Protez Adı *</Label>
            <Input
              id={`edit-name-${row.$id}`}
              name="name"
              defaultValue={row.name}
              required
              maxLength={255}
            />
            {state.fieldErrors?.name && (
              <p className="text-destructive text-xs">{state.fieldErrors.name}</p>
            )}
          </div>
          <div className="grid gap-2">
            <Label htmlFor={`edit-type-${row.$id}`}>Protez Türü *</Label>
            <Select name="type" defaultValue={row.type}>
              <SelectTrigger id={`edit-type-${row.$id}`}>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {PROSTHETIC_TYPE_OPTIONS.map((o) => (
                  <SelectItem key={o.value} value={o.value}>
                    {o.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="grid grid-cols-[minmax(0,1fr)_100px] gap-3">
            <div className="grid gap-2">
              <Label htmlFor={`edit-price-${row.$id}`}>Birim Fiyatı *</Label>
              <Input
                id={`edit-price-${row.$id}`}
                name="unitPrice"
                type="number"
                step="0.01"
                min="0"
                defaultValue={row.unitPrice}
                required
              />
            </div>
            <div className="grid gap-2">
              <Label htmlFor={`edit-currency-${row.$id}`}>Para</Label>
              <Input
                id={`edit-currency-${row.$id}`}
                name="currency"
                defaultValue={row.currency || defaultCurrency}
                maxLength={8}
                style={{ textTransform: "uppercase" }}
              />
            </div>
          </div>
          <DialogFooter>
            <DialogClose asChild>
              <Button type="button" variant="outline">
                Vazgeç
              </Button>
            </DialogClose>
            <Button type="submit" disabled={pending}>
              {pending ? <Loader2 className="size-4 animate-spin" /> : <Pencil className="size-4" />}
              Kaydet
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}
