"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { Edit, Eye, PackagePlus, Plus, RotateCcw, Trash2, Wrench } from "lucide-react";

import ConfirmDialog from "@/components/common/ConfirmDialog";
import DataTable, { type DataTableColumn } from "@/components/common/DataTable";
import EmptyState from "@/components/common/EmptyState";
import SearchInput from "@/components/common/SearchInput";
import { useToast } from "@/components/common/ToastProvider";
import InventoryItemDialog from "@/components/inventory/InventoryItemDialog";
import MasterDataSection from "@/components/inventory/MasterDataSection";
import StockActionDialog, { type StockAction } from "@/components/inventory/StockActionDialog";
import { formatMoney, getErrorMessage } from "@/components/inventory/inventory-utils";
import { Button, buttonVariants } from "@/components/ui/button";
import { api } from "@/lib/api";
import { hasPermission } from "@/lib/permissions";
import type {
  InventoryCategory,
  InventoryItem,
  InventoryItemListResponse,
  InventoryItemPayload,
  InventoryLocation,
  InventoryStockPayload,
  InventorySupplier,
} from "@/types/inventory";
import type { CurrentUser } from "@/types/rbac";

const pageSize = 10;

export default function InventoryPage() {
  const { showToast } = useToast();
  const [items, setItems] = useState<InventoryItem[]>([]);
  const [categories, setCategories] = useState<InventoryCategory[]>([]);
  const [locations, setLocations] = useState<InventoryLocation[]>([]);
  const [suppliers, setSuppliers] = useState<InventorySupplier[]>([]);
  const [currentUser, setCurrentUser] = useState<CurrentUser | null>(null);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");
  const [formError, setFormError] = useState("");
  const [stockError, setStockError] = useState("");
  const [deleteError, setDeleteError] = useState("");
  const [pending, setPending] = useState(false);
  const [tab, setTab] = useState<"items" | "categories" | "locations" | "suppliers">("items");
  const [search, setSearch] = useState("");
  const [categoryFilter, setCategoryFilter] = useState("all");
  const [locationFilter, setLocationFilter] = useState("all");
  const [supplierFilter, setSupplierFilter] = useState("all");
  const [stockFilter, setStockFilter] = useState<"all" | "low">("all");
  const [activeFilter, setActiveFilter] = useState<"true" | "false" | "all">("true");
  const [page, setPage] = useState(1);
  const [sortKey, setSortKey] = useState("name");
  const [sortDirection, setSortDirection] = useState<"asc" | "desc">("asc");
  const [formOpen, setFormOpen] = useState(false);
  const [stockOpen, setStockOpen] = useState(false);
  const [stockAction, setStockAction] = useState<StockAction>("adjust");
  const [selectedItem, setSelectedItem] = useState<InventoryItem | null>(null);
  const [deleteItem, setDeleteItem] = useState<InventoryItem | null>(null);

  const loadData = useCallback(async () => {
    setLoading(true);
    setError("");
    try {
      const params = new URLSearchParams();
      params.set("limit", String(pageSize));
      params.set("offset", String((page - 1) * pageSize));
      if (search.trim()) params.set("q", search.trim());
      if (categoryFilter !== "all") params.set("category_id", categoryFilter);
      if (locationFilter !== "all") params.set("location_id", locationFilter);
      if (supplierFilter !== "all") params.set("supplier_id", supplierFilter);
      if (stockFilter === "low") params.set("low_stock", "true");
      if (activeFilter !== "all") params.set("active", activeFilter);
      const [itemResponse, categoryResponse, locationResponse, supplierResponse, meResponse] = await Promise.all([
        api.get<InventoryItemListResponse>(`/inventory/items?${params.toString()}`),
        api.get<InventoryCategory[]>("/inventory/categories"),
        api.get<InventoryLocation[]>("/inventory/locations"),
        api.get<InventorySupplier[]>("/inventory/suppliers"),
        api.get<CurrentUser>("/me"),
      ]);
      setItems(itemResponse.data.items);
      setTotal(itemResponse.data.total);
      setCategories(categoryResponse.data);
      setLocations(locationResponse.data);
      setSuppliers(supplierResponse.data);
      setCurrentUser(meResponse.data);
    } catch (err) {
      setError(getErrorMessage(err));
    } finally {
      setLoading(false);
    }
  }, [activeFilter, categoryFilter, locationFilter, page, search, stockFilter, supplierFilter]);

  useEffect(() => {
    queueMicrotask(() => {
      void loadData();
    });
  }, [loadData]);

  const canCreate = hasPermission(currentUser, "inventory.create");
  const canUpdate = hasPermission(currentUser, "inventory.update");
  const canDelete = hasPermission(currentUser, "inventory.delete");
  const canAdjust = hasPermission(currentUser, "inventory.stock.adjust");
  const canReserve = hasPermission(currentUser, "inventory.stock.reserve");
  const canConsume = hasPermission(currentUser, "inventory.stock.consume");
  const canManageMasterdata = hasPermission(currentUser, "inventory.manage.masterdata");
  const pageCount = Math.max(1, Math.ceil(total / pageSize));
  const currentPage = Math.min(page, pageCount);

  const sortedItems = useMemo(() => [...items].sort((first, second) => {
    const firstValue = String(first[sortKey as keyof InventoryItem] ?? "").toLowerCase();
    const secondValue = String(second[sortKey as keyof InventoryItem] ?? "").toLowerCase();
    if (firstValue === secondValue) return 0;
    const result = firstValue > secondValue ? 1 : -1;
    return sortDirection === "asc" ? result : -result;
  }), [items, sortDirection, sortKey]);

  const columns: DataTableColumn<InventoryItem>[] = [
    { key: "sku", label: "SKU", sortable: true, render: (item) => <span className="font-medium text-slate-950">{item.sku}</span> },
    { key: "name", label: "Name", sortable: true, render: (item) => item.name },
    { key: "category", label: "Kategorie", render: (item) => item.category?.name ?? "Keine" },
    { key: "manufacturer", label: "Hersteller", sortable: true, render: (item) => item.manufacturer ?? "Keine Angabe" },
    { key: "quantity_on_hand", label: "Bestand", sortable: true, render: (item) => item.quantity_on_hand },
    { key: "quantity_reserved", label: "Reserviert", sortable: true, render: (item) => item.quantity_reserved },
    { key: "quantity_available", label: "Verfügbar", sortable: true, render: (item) => <span className={item.quantity_available <= item.reorder_level ? "font-semibold text-amber-700" : ""}>{item.quantity_available}</span> },
    { key: "reorder_level", label: "Mindestbestand", sortable: true, render: (item) => item.reorder_level },
    { key: "location", label: "Lagerort", render: (item) => item.location?.name ?? "Kein Lagerort" },
    { key: "selling_price_cents", label: "VK", sortable: true, render: (item) => formatMoney(item.selling_price_cents, item.currency) },
    { key: "is_active", label: "Status", sortable: true, render: (item) => item.is_active ? "Aktiv" : "Inaktiv" },
    {
      key: "actions",
      label: "Aktionen",
      className: "px-4 py-3 text-right",
      render: (item) => (
        <div className="flex justify-end gap-2">
          <Link href={`/inventory/items/${item.id}`} className={buttonVariants({ variant: "ghost", size: "icon-sm" })} title="Details"><Eye size={16} /></Link>
          {canUpdate && <Button type="button" variant="ghost" size="icon-sm" title="Bearbeiten" onClick={() => { setSelectedItem(item); setFormError(""); setFormOpen(true); }}><Edit size={16} /></Button>}
          {canAdjust && <Button type="button" variant="ghost" size="icon-sm" title="Bestand anpassen" onClick={() => openStock(item, "adjust")}><Wrench size={16} /></Button>}
          {canReserve && <Button type="button" variant="ghost" size="icon-sm" title="Reservieren" onClick={() => openStock(item, "reserve")}><PackagePlus size={16} /></Button>}
          {canConsume && <Button type="button" variant="ghost" size="icon-sm" title="Verbrauch buchen" onClick={() => openStock(item, "consume")}><RotateCcw size={16} /></Button>}
          {canDelete && <Button type="button" variant="destructive" size="icon-sm" title="Deaktivieren" onClick={() => { setDeleteItem(item); setDeleteError(""); }}><Trash2 size={16} /></Button>}
        </div>
      ),
    },
  ];

  function openStock(item: InventoryItem, action: StockAction) {
    setSelectedItem(item);
    setStockAction(action);
    setStockError("");
    setStockOpen(true);
  }

  function handleSort(key: string) {
    if (sortKey === key) {
      setSortDirection((current) => (current === "asc" ? "desc" : "asc"));
      return;
    }
    setSortKey(key);
    setSortDirection("asc");
  }

  async function saveItem(payload: InventoryItemPayload) {
    setPending(true);
    setFormError("");
    try {
      if (selectedItem) {
        await api.put<InventoryItem>(`/inventory/items/${selectedItem.id}`, payload);
        showToast({ type: "success", title: "Artikel aktualisiert", description: selectedItem.sku });
      } else {
        const response = await api.post<InventoryItem>("/inventory/items", payload);
        showToast({ type: "success", title: "Artikel angelegt", description: response.data.sku });
      }
      setFormOpen(false);
      await loadData();
    } catch (err) {
      const message = getErrorMessage(err);
      setFormError(message);
      showToast({ type: "error", title: "Artikel konnte nicht gespeichert werden", description: message });
    } finally {
      setPending(false);
    }
  }

  async function saveStock(payload: InventoryStockPayload) {
    if (!selectedItem) return;
    setPending(true);
    setStockError("");
    try {
      await api.post<InventoryItem>(`/inventory/items/${selectedItem.id}/stock/${stockAction}`, payload);
      showToast({ type: "success", title: "Bestand gebucht", description: selectedItem.sku });
      setStockOpen(false);
      await loadData();
    } catch (err) {
      const message = getErrorMessage(err);
      setStockError(message);
      showToast({ type: "error", title: "Bestand konnte nicht gebucht werden", description: message });
    } finally {
      setPending(false);
    }
  }

  async function confirmDelete() {
    if (!deleteItem) return;
    setPending(true);
    setDeleteError("");
    try {
      await api.delete(`/inventory/items/${deleteItem.id}`);
      showToast({ type: "success", title: "Artikel deaktiviert", description: deleteItem.sku });
      setDeleteItem(null);
      await loadData();
    } catch (err) {
      const message = getErrorMessage(err);
      setDeleteError(message);
      showToast({ type: "error", title: "Artikel konnte nicht deaktiviert werden", description: message });
    } finally {
      setPending(false);
    }
  }

  return (
    <div className="space-y-6">
      <div className="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
        <div>
          <h1 className="text-3xl font-bold text-slate-950">Lager / Ersatzteile</h1>
          <p className="mt-1 text-sm text-slate-500">{total} Artikel im aktuellen Filter</p>
        </div>
        {canCreate && <Button type="button" onClick={() => { setSelectedItem(null); setFormError(""); setFormOpen(true); }}><Plus size={16} />Artikel anlegen</Button>}
      </div>

      <div className="flex flex-wrap gap-2">
        {(["items", "categories", "locations", "suppliers"] as const).map((value) => (
          <Button key={value} type="button" variant={tab === value ? "default" : "outline"} onClick={() => setTab(value)}>
            {{ items: "Artikel", categories: "Kategorien", locations: "Lagerorte", suppliers: "Lieferanten" }[value]}
          </Button>
        ))}
      </div>

      {tab === "items" ? (
        <>
          <div className="flex flex-col gap-3 rounded-lg border bg-white p-4 xl:flex-row xl:items-center">
            <SearchInput value={search} onChange={(value) => { setSearch(value); setPage(1); }} placeholder="Artikel suchen" />
            <select value={categoryFilter} onChange={(event) => { setCategoryFilter(event.target.value); setPage(1); }} className="h-8 rounded-lg border px-2 text-sm">
              <option value="all">Alle Kategorien</option>
              {categories.map((category) => <option key={category.id} value={category.id}>{category.name}</option>)}
            </select>
            <select value={locationFilter} onChange={(event) => { setLocationFilter(event.target.value); setPage(1); }} className="h-8 rounded-lg border px-2 text-sm">
              <option value="all">Alle Lagerorte</option>
              {locations.map((location) => <option key={location.id} value={location.id}>{location.name}</option>)}
            </select>
            <select value={supplierFilter} onChange={(event) => { setSupplierFilter(event.target.value); setPage(1); }} className="h-8 rounded-lg border px-2 text-sm">
              <option value="all">Alle Lieferanten</option>
              {suppliers.map((supplier) => <option key={supplier.id} value={supplier.id}>{supplier.name}</option>)}
            </select>
            <select value={stockFilter} onChange={(event) => { setStockFilter(event.target.value as "all" | "low"); setPage(1); }} className="h-8 rounded-lg border px-2 text-sm">
              <option value="all">Alle Bestände</option>
              <option value="low">Niedriger Bestand</option>
            </select>
            <select value={activeFilter} onChange={(event) => { setActiveFilter(event.target.value as "true" | "false" | "all"); setPage(1); }} className="h-8 rounded-lg border px-2 text-sm">
              <option value="true">Aktiv</option>
              <option value="false">Inaktiv</option>
              <option value="all">Alle</option>
            </select>
          </div>

          {!loading && !error && total === 0 && !search ? (
            <EmptyState
              title="Noch keine Ersatzteile vorhanden."
              description="Lege den ersten Artikel an, um Bestand, Preise und Lieferanten zu pflegen."
              action={canCreate ? <Button type="button" onClick={() => setFormOpen(true)}><Plus size={16} />Artikel anlegen</Button> : undefined}
            />
          ) : (
            <DataTable
              columns={columns}
              rows={sortedItems}
              rowKey={(item) => item.id}
              sortKey={sortKey}
              sortDirection={sortDirection}
              loading={loading}
              error={error}
              emptyTitle="Keine Artikel gefunden."
              emptyDescription="Passe Suche oder Filter an."
              onSort={handleSort}
            />
          )}

          <div className="flex items-center justify-between text-sm text-slate-600">
            <span>Seite {currentPage} von {pageCount}</span>
            <div className="flex gap-2">
              <Button type="button" variant="outline" disabled={currentPage === 1} onClick={() => setPage((current) => Math.max(1, current - 1))}>Zurück</Button>
              <Button type="button" variant="outline" disabled={currentPage === pageCount} onClick={() => setPage((current) => Math.min(pageCount, current + 1))}>Weiter</Button>
            </div>
          </div>
        </>
      ) : (
        <div className="grid gap-4 xl:grid-cols-2">
          {tab === "categories" && <MasterDataSection title="Kategorien" kind="categories" entries={categories} canManage={canManageMasterdata} onChanged={() => void loadData()} />}
          {tab === "locations" && <MasterDataSection title="Lagerorte" kind="locations" entries={locations} canManage={canManageMasterdata} onChanged={() => void loadData()} />}
          {tab === "suppliers" && <MasterDataSection title="Lieferanten" kind="suppliers" entries={suppliers} canManage={canManageMasterdata} onChanged={() => void loadData()} />}
        </div>
      )}

      <InventoryItemDialog key={`item-${selectedItem?.id ?? "new"}-${formOpen}`} open={formOpen} item={selectedItem} categories={categories} locations={locations} suppliers={suppliers} pending={pending} serverError={formError} onOpenChange={setFormOpen} onSubmit={saveItem} />
      <StockActionDialog key={`stock-${selectedItem?.id ?? "none"}-${stockAction}-${stockOpen}`} open={stockOpen} item={selectedItem} action={stockAction} pending={pending} serverError={stockError} onOpenChange={setStockOpen} onSubmit={saveStock} />
      <ConfirmDialog
        open={Boolean(deleteItem)}
        title="Artikel deaktivieren"
        description="Artikel mit Bewegungen werden nicht hart gelöscht, sondern deaktiviert."
        confirmLabel="Deaktivieren"
        pending={pending}
        onOpenChange={(open) => !open && setDeleteItem(null)}
        onConfirm={confirmDelete}
      >
        <div className="space-y-2">
          <p>{deleteItem?.sku} · {deleteItem?.name}</p>
          {deleteError && <p className="text-sm text-red-600">{deleteError}</p>}
        </div>
      </ConfirmDialog>
    </div>
  );
}
