"use client";

import { useMemo, useState, useTransition } from "react";
import {
  type ColumnDef,
  flexRender,
  getCoreRowModel,
  getFilteredRowModel,
  getPaginationRowModel,
  useReactTable,
} from "@tanstack/react-table";
import {
  Loader2,
  MoreHorizontal,
  Package,
  Pencil,
  Plus,
  Search,
  Trash2,
  Users,
} from "lucide-react";
import { toast } from "sonner";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Input } from "@/components/ui/input";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
  deleteAssignmentAction,
  deleteSoftwareAction,
} from "@/lib/appwrite/software-actions";
import { BILLING_PERIOD_LABEL, formatDate, formatTRY } from "@/lib/format";

import { AssignmentFormSheet } from "./assignment-form-sheet";
import { SoftwareFormSheet } from "./software-form-sheet";
import type {
  AssignmentRow,
  CustomerOption,
  SoftwareOption,
  SoftwareRow,
} from "./types";

type Props = {
  software: SoftwareRow[];
  assignments: AssignmentRow[];
  customers: CustomerOption[];
};

export function SoftwareClient({ software, assignments, customers }: Props) {
  const [tab, setTab] = useState<"catalog" | "assignments">("catalog");
  const [softwareSearch, setSoftwareSearch] = useState("");
  const [assignmentSearch, setAssignmentSearch] = useState("");

  const [softwareFormOpen, setSoftwareFormOpen] = useState(false);
  const [editingSoftware, setEditingSoftware] = useState<SoftwareRow | null>(null);
  const [deletingSoftware, setDeletingSoftware] = useState<SoftwareRow | null>(null);

  const [assignmentFormOpen, setAssignmentFormOpen] = useState(false);
  const [editingAssignment, setEditingAssignment] = useState<AssignmentRow | null>(null);
  const [deletingAssignment, setDeletingAssignment] = useState<AssignmentRow | null>(null);

  const [busy, startTransition] = useTransition();

  const softwareOptions: SoftwareOption[] = useMemo(
    () =>
      software.map((s) => ({
        id: s.id,
        name: s.name,
        version: s.version,
        defaultFee: s.defaultFee,
      })),
    [software],
  );

  const softwareCols = useMemo<ColumnDef<SoftwareRow>[]>(
    () => [
      {
        accessorKey: "name",
        header: "Ad",
        cell: ({ row }) => (
          <div className="flex flex-col">
            <span className="font-medium">{row.original.name}</span>
            {row.original.description && (
              <span className="text-muted-foreground line-clamp-1 text-xs">
                {row.original.description}
              </span>
            )}
          </div>
        ),
      },
      {
        accessorKey: "version",
        header: "Sürüm",
        cell: ({ row }) =>
          row.original.version ? (
            <Badge variant="outline">v{row.original.version}</Badge>
          ) : (
            <span className="text-muted-foreground">—</span>
          ),
      },
      {
        accessorKey: "defaultFee",
        header: "Varsayılan ücret",
        cell: ({ row }) =>
          row.original.defaultFee !== null ? (
            <span>{formatTRY(row.original.defaultFee)}</span>
          ) : (
            <span className="text-muted-foreground">—</span>
          ),
      },
      {
        id: "actions",
        cell: ({ row }) => (
          <div className="flex justify-end">
            <DropdownMenu>
              <DropdownMenuTrigger asChild>
                <Button variant="ghost" size="icon" className="size-8">
                  <MoreHorizontal className="size-4" />
                </Button>
              </DropdownMenuTrigger>
              <DropdownMenuContent align="end">
                <DropdownMenuItem
                  onClick={() => {
                    setEditingSoftware(row.original);
                    setSoftwareFormOpen(true);
                  }}
                >
                  <Pencil className="size-3.5" />
                  Düzenle
                </DropdownMenuItem>
                <DropdownMenuItem
                  variant="destructive"
                  onClick={() => setDeletingSoftware(row.original)}
                >
                  <Trash2 className="size-3.5" />
                  Sil
                </DropdownMenuItem>
              </DropdownMenuContent>
            </DropdownMenu>
          </div>
        ),
      },
    ],
    [],
  );

  const assignmentCols = useMemo<ColumnDef<AssignmentRow>[]>(
    () => [
      {
        accessorKey: "softwareName",
        header: "Yazılım",
        cell: ({ row }) => (
          <div className="flex flex-col">
            <span className="font-medium">{row.original.softwareName}</span>
            {row.original.softwareVersion && (
              <span className="text-muted-foreground text-xs">v{row.original.softwareVersion}</span>
            )}
          </div>
        ),
      },
      {
        accessorKey: "customerName",
        header: "Müşteri",
        cell: ({ row }) => (
          <span className="text-muted-foreground">{row.original.customerName}</span>
        ),
      },
      {
        accessorKey: "fee",
        header: "Ücret",
        cell: ({ row }) => (
          <div className="flex flex-col">
            <span className="font-medium">
              {row.original.fee !== null ? formatTRY(row.original.fee) : "—"}
            </span>
            <span className="text-muted-foreground text-xs">
              {BILLING_PERIOD_LABEL[row.original.billingPeriod]}
            </span>
          </div>
        ),
      },
      {
        id: "dates",
        header: "Süre",
        cell: ({ row }) => (
          <span className="text-muted-foreground text-sm">
            {formatDate(row.original.startDate)}
            {" → "}
            {row.original.endDate ? formatDate(row.original.endDate) : "süresiz"}
          </span>
        ),
      },
      {
        id: "actions",
        cell: ({ row }) => (
          <div className="flex justify-end">
            <DropdownMenu>
              <DropdownMenuTrigger asChild>
                <Button variant="ghost" size="icon" className="size-8">
                  <MoreHorizontal className="size-4" />
                </Button>
              </DropdownMenuTrigger>
              <DropdownMenuContent align="end">
                <DropdownMenuItem
                  onClick={() => {
                    setEditingAssignment(row.original);
                    setAssignmentFormOpen(true);
                  }}
                >
                  <Pencil className="size-3.5" />
                  Düzenle
                </DropdownMenuItem>
                <DropdownMenuItem
                  variant="destructive"
                  onClick={() => setDeletingAssignment(row.original)}
                >
                  <Trash2 className="size-3.5" />
                  Kaldır
                </DropdownMenuItem>
              </DropdownMenuContent>
            </DropdownMenu>
          </div>
        ),
      },
    ],
    [],
  );

  const softwareTable = useReactTable({
    data: software,
    columns: softwareCols,
    state: { globalFilter: softwareSearch },
    onGlobalFilterChange: setSoftwareSearch,
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    initialState: { pagination: { pageSize: 20 } },
    globalFilterFn: (row, _id, fv) => {
      const v = String(fv).toLowerCase();
      return [row.original.name, row.original.version, row.original.description]
        .join(" ")
        .toLowerCase()
        .includes(v);
    },
  });

  const assignmentTable = useReactTable({
    data: assignments,
    columns: assignmentCols,
    state: { globalFilter: assignmentSearch },
    onGlobalFilterChange: setAssignmentSearch,
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    initialState: { pagination: { pageSize: 20 } },
    globalFilterFn: (row, _id, fv) => {
      const v = String(fv).toLowerCase();
      return [row.original.softwareName, row.original.customerName, row.original.notes]
        .join(" ")
        .toLowerCase()
        .includes(v);
    },
  });

  const deleteSoftware = () => {
    if (!deletingSoftware) return;
    startTransition(async () => {
      const fd = new FormData();
      fd.set("id", deletingSoftware.id);
      const result = await deleteSoftwareAction(fd);
      if (result.ok) {
        toast.success("Yazılım silindi.");
        setDeletingSoftware(null);
      } else {
        toast.error(result.error ?? "Silme başarısız.");
      }
    });
  };

  const deleteAssignment = () => {
    if (!deletingAssignment) return;
    startTransition(async () => {
      const fd = new FormData();
      fd.set("id", deletingAssignment.id);
      const result = await deleteAssignmentAction(fd);
      if (result.ok) {
        toast.success("Atama kaldırıldı.");
        setDeletingAssignment(null);
      } else {
        toast.error(result.error ?? "İşlem başarısız.");
      }
    });
  };

  return (
    <Card>
      <CardContent className="p-0">
        <Tabs value={tab} onValueChange={(v) => setTab(v as typeof tab)}>
          <div className="flex flex-col gap-3 p-4 md:flex-row md:items-center md:justify-between">
            <TabsList>
              <TabsTrigger value="catalog">
                <Package className="size-3.5" />
                Katalog ({software.length})
              </TabsTrigger>
              <TabsTrigger value="assignments">
                <Users className="size-3.5" />
                Atamalar ({assignments.length})
              </TabsTrigger>
            </TabsList>

            {tab === "catalog" ? (
              <Button
                onClick={() => {
                  setEditingSoftware(null);
                  setSoftwareFormOpen(true);
                }}
              >
                <Plus className="size-4" />
                Yeni yazılım
              </Button>
            ) : (
              <Button
                onClick={() => {
                  setEditingAssignment(null);
                  setAssignmentFormOpen(true);
                }}
                disabled={customers.length === 0 || software.length === 0}
              >
                <Plus className="size-4" />
                Yeni atama
              </Button>
            )}
          </div>

          <TabsContent value="catalog" className="m-0">
            <div className="px-4 pb-3">
              <div className="relative max-w-xs">
                <Search className="text-muted-foreground absolute top-1/2 left-3 size-4 -translate-y-1/2" />
                <Input
                  value={softwareSearch}
                  onChange={(e) => setSoftwareSearch(e.target.value)}
                  placeholder="Yazılım ara..."
                  className="pl-9"
                />
              </div>
            </div>
            <Table>
              <TableHeader>
                {softwareTable.getHeaderGroups().map((hg) => (
                  <TableRow key={hg.id}>
                    {hg.headers.map((h) => (
                      <TableHead key={h.id}>
                        {h.isPlaceholder
                          ? null
                          : flexRender(h.column.columnDef.header, h.getContext())}
                      </TableHead>
                    ))}
                  </TableRow>
                ))}
              </TableHeader>
              <TableBody>
                {softwareTable.getRowModel().rows.length ? (
                  softwareTable.getRowModel().rows.map((r) => (
                    <TableRow key={r.id}>
                      {r.getVisibleCells().map((c) => (
                        <TableCell key={c.id}>
                          {flexRender(c.column.columnDef.cell, c.getContext())}
                        </TableCell>
                      ))}
                    </TableRow>
                  ))
                ) : (
                  <TableRow>
                    <TableCell colSpan={softwareCols.length} className="h-32 text-center">
                      <div className="text-muted-foreground flex flex-col items-center gap-2">
                        <Package className="size-6" />
                        <p className="text-sm">Henüz yazılım eklenmemiş.</p>
                        <Button
                          variant="outline"
                          size="sm"
                          onClick={() => {
                            setEditingSoftware(null);
                            setSoftwareFormOpen(true);
                          }}
                        >
                          <Plus className="size-3.5" />
                          İlk yazılımı ekle
                        </Button>
                      </div>
                    </TableCell>
                  </TableRow>
                )}
              </TableBody>
            </Table>
          </TabsContent>

          <TabsContent value="assignments" className="m-0">
            <div className="px-4 pb-3">
              <div className="relative max-w-xs">
                <Search className="text-muted-foreground absolute top-1/2 left-3 size-4 -translate-y-1/2" />
                <Input
                  value={assignmentSearch}
                  onChange={(e) => setAssignmentSearch(e.target.value)}
                  placeholder="Yazılım veya müşteri ara..."
                  className="pl-9"
                />
              </div>
            </div>
            <Table>
              <TableHeader>
                {assignmentTable.getHeaderGroups().map((hg) => (
                  <TableRow key={hg.id}>
                    {hg.headers.map((h) => (
                      <TableHead key={h.id}>
                        {h.isPlaceholder
                          ? null
                          : flexRender(h.column.columnDef.header, h.getContext())}
                      </TableHead>
                    ))}
                  </TableRow>
                ))}
              </TableHeader>
              <TableBody>
                {assignmentTable.getRowModel().rows.length ? (
                  assignmentTable.getRowModel().rows.map((r) => (
                    <TableRow key={r.id}>
                      {r.getVisibleCells().map((c) => (
                        <TableCell key={c.id}>
                          {flexRender(c.column.columnDef.cell, c.getContext())}
                        </TableCell>
                      ))}
                    </TableRow>
                  ))
                ) : (
                  <TableRow>
                    <TableCell colSpan={assignmentCols.length} className="h-32 text-center">
                      <div className="text-muted-foreground flex flex-col items-center gap-2">
                        <Users className="size-6" />
                        <p className="text-sm">
                          {customers.length === 0 || software.length === 0
                            ? "Önce müşteri ve yazılım ekleyin, sonra atayabilirsiniz."
                            : "Henüz atama yapılmamış."}
                        </p>
                      </div>
                    </TableCell>
                  </TableRow>
                )}
              </TableBody>
            </Table>
          </TabsContent>
        </Tabs>
      </CardContent>

      <SoftwareFormSheet
        open={softwareFormOpen}
        onOpenChange={(v) => {
          setSoftwareFormOpen(v);
          if (!v) setEditingSoftware(null);
        }}
        software={editingSoftware}
      />

      <AssignmentFormSheet
        open={assignmentFormOpen}
        onOpenChange={(v) => {
          setAssignmentFormOpen(v);
          if (!v) setEditingAssignment(null);
        }}
        assignment={editingAssignment}
        customers={customers}
        softwareOptions={softwareOptions}
      />

      <Dialog
        open={Boolean(deletingSoftware)}
        onOpenChange={(v) => !v && setDeletingSoftware(null)}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Yazılımı sil</DialogTitle>
            <DialogDescription>
              <strong>{deletingSoftware?.name}</strong> ve müşterilerle olan tüm atamaları silinecek.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button
              variant="outline"
              onClick={() => setDeletingSoftware(null)}
              disabled={busy}
            >
              Vazgeç
            </Button>
            <Button variant="destructive" onClick={deleteSoftware} disabled={busy}>
              {busy ? <Loader2 className="size-4 animate-spin" /> : <Trash2 className="size-4" />}
              Sil
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog
        open={Boolean(deletingAssignment)}
        onOpenChange={(v) => !v && setDeletingAssignment(null)}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Atamayı kaldır</DialogTitle>
            <DialogDescription>
              <strong>{deletingAssignment?.softwareName}</strong> →{" "}
              <strong>{deletingAssignment?.customerName}</strong> ataması kaldırılacak.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button
              variant="outline"
              onClick={() => setDeletingAssignment(null)}
              disabled={busy}
            >
              Vazgeç
            </Button>
            <Button variant="destructive" onClick={deleteAssignment} disabled={busy}>
              {busy ? <Loader2 className="size-4 animate-spin" /> : <Trash2 className="size-4" />}
              Kaldır
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </Card>
  );
}
