import { useEffect, useMemo, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { api } from "./api.js";
import type { Bin, Bootstrap, Brand, Item, Product, Shop } from "./types.js";
import { enrichItems } from "./types.js";
import { computeStats } from "./stats.js";
import { Sidebar } from "./components/Sidebar.js";
import type { ViewKey } from "./components/Sidebar.js";
import { Dashboard } from "./views/Dashboard.js";
import { Inventory } from "./views/Inventory.js";
import { BinsView } from "./views/BinsView.js";
import { BrandsView } from "./views/BrandsView.js";
import { ShopsView } from "./views/ShopsView.js";
import { ChartsView } from "./views/ChartsView.js";
import { SettingsView } from "./views/SettingsView.js";
import type { ThemeKey } from "./views/SettingsView.js";
import { ProductDetail } from "./components/ProductDetail.js";
import { AddInventoryFlow } from "./components/modals/AddInventoryFlow.js";
import { EditInventoryFlow } from "./components/modals/EditInventoryFlow.js";
import { EditProductFlow } from "./components/modals/EditProductFlow.js";
import { ConsumeFlow } from "./components/modals/ConsumeFlow.js";
import { MarkGoneFlow } from "./components/modals/MarkGoneFlow.js";
import { AuditFlow } from "./components/modals/AuditFlow.js";
import {
  AddBinModal,
  AddBrandModal,
  AddShopModal,
  EditBinModal,
  EditBrandModal,
  EditShopModal,
} from "./components/modals/CatalogModals.js";

type ModalKey =
  | "add"
  | "edit"
  | "editProduct"
  | "consume"
  | "gone"
  | "audit"
  | "addBrand"
  | "addShop"
  | "addBin"
  | "editBin"
  | "editBrand"
  | "editShop"
  | null;

export function App() {
  const [view, setView] = useState<ViewKey>("dashboard");
  const [selected, setSelected] = useState<Item | null>(null);
  const [modal, setModal] = useState<ModalKey>(null);
  const [modalItem, setModalItem] = useState<Item | null>(null);
  const [modalProduct, setModalProduct] = useState<Product | null>(null);
  const [modalBin, setModalBin] = useState<Bin | null>(null);
  const [modalBrand, setModalBrand] = useState<Brand | null>(null);
  const [modalShop, setModalShop] = useState<Shop | null>(null);

  const [theme, setTheme] = useState<ThemeKey>(
    () => (localStorage.getItem("apothecary.theme") as ThemeKey | null) ?? "light",
  );

  useEffect(() => {
    document.documentElement.dataset.theme = theme;
    localStorage.setItem("apothecary.theme", theme);
  }, [theme]);

  const { data, isLoading, error } = useQuery<Bootstrap>({
    queryKey: ["bootstrap"],
    queryFn: api.bootstrap,
  });

  const stats = useMemo(() => (data ? computeStats(data) : null), [data]);
  const items = useMemo(() => (data ? enrichItems(data) : []), [data]);

  // Re-sync the selected item reference whenever bootstrap refetches
  // — otherwise the drawer keeps showing stale audit history after a
  // mutation invalidates the cache.
  useEffect(() => {
    if (selected && data) {
      const fresh = items.find((i) => i.id === selected.id);
      if (fresh && fresh !== selected) setSelected(fresh);
    }
  }, [data, items]); // eslint-disable-line react-hooks/exhaustive-deps

  const openAdd = () => {
    setModalItem(null);
    setModal("add");
  };
  const openConsume = (i?: Item) => {
    setModalItem(i ?? null);
    setSelected(null);
    setModal("consume");
  };
  const openMarkGone = (i?: Item) => {
    setModalItem(i ?? null);
    setSelected(null);
    setModal("gone");
  };
  const openAudit = (i?: Item) => {
    setModalItem(i ?? null);
    setModal("audit");
  };
  const openEdit = (i: Item) => {
    setModalItem(i);
    setSelected(null);
    setModal("edit");
  };
  const openEditProduct = (p: Product) => {
    setModalProduct(p);
    setSelected(null);
    setModal("editProduct");
  };

  if (isLoading) {
    return (
      <div className="parchment" style={{ padding: 60, color: "var(--ink-3)" }}>
        Loading…
      </div>
    );
  }
  if (error || !data || !stats) {
    return (
      <div className="parchment" style={{ padding: 60, color: "var(--terracotta)" }}>
        Failed to load: {String(error ?? "no data")}
      </div>
    );
  }

  return (
    <div className="app-shell" data-screen-label="App">
      <Sidebar
        view={view}
        onNav={setView}
        onAddProduct={openAdd}
        onMarkFinished={() => openConsume()}
        onAudit={() => openAudit()}
      />

      <main className="main parchment" style={{ minWidth: 0 }}>
        {view === "dashboard" && (
          <Dashboard
            data={data}
            stats={stats}
            onAuditItem={openAudit}
            onSelectItem={setSelected}
          />
        )}
        {view === "inventory" && (
          <Inventory
            data={data}
            onSelectItem={setSelected}
            onAddInventory={openAdd}
            onAuditNew={() => openAudit()}
          />
        )}
        {view === "bins" && (
          <BinsView
            data={data}
            onSelectItem={setSelected}
            onAddBin={() => setModal("addBin")}
            onEditBin={(bin) => {
              setModalBin(bin);
              setModal("editBin");
            }}
          />
        )}
        {view === "shops" && (
          <ShopsView
            data={data}
            onAddShop={() => setModal("addShop")}
            onEditShop={(shop) => {
              setModalShop(shop);
              setModal("editShop");
            }}
          />
        )}
        {view === "brands" && (
          <BrandsView
            data={data}
            onAddBrand={() => setModal("addBrand")}
            onEditBrand={(brand) => {
              setModalBrand(brand);
              setModal("editBrand");
            }}
          />
        )}
        {view === "charts" && <ChartsView data={data} stats={stats} />}
        {view === "settings" && (
          <SettingsView data={data} theme={theme} onThemeChange={setTheme} />
        )}
      </main>

      {selected && (
        <ProductDetail
          item={selected}
          data={data}
          onClose={() => setSelected(null)}
          onConsume={openConsume}
          onMarkGone={openMarkGone}
          onAudit={openAudit}
          onEdit={openEdit}
          onEditProduct={openEditProduct}
        />
      )}

      {modal === "add" && <AddInventoryFlow data={data} onClose={() => setModal(null)} />}
      {modal === "edit" && modalItem && (
        <EditInventoryFlow data={data} item={modalItem} onClose={() => setModal(null)} />
      )}
      {modal === "editProduct" && modalProduct && (
        <EditProductFlow data={data} product={modalProduct} onClose={() => setModal(null)} />
      )}
      {modal === "consume" && (
        <ConsumeFlow data={data} onClose={() => setModal(null)} item={modalItem} />
      )}
      {modal === "gone" && (
        <MarkGoneFlow data={data} onClose={() => setModal(null)} item={modalItem} />
      )}
      {modal === "audit" && (
        <AuditFlow data={data} onClose={() => setModal(null)} item={modalItem} />
      )}
      {modal === "addBrand" && <AddBrandModal onClose={() => setModal(null)} />}
      {modal === "addShop" && <AddShopModal onClose={() => setModal(null)} />}
      {modal === "addBin" && <AddBinModal onClose={() => setModal(null)} />}
      {modal === "editBin" && modalBin && (
        <EditBinModal bin={modalBin} onClose={() => setModal(null)} />
      )}
      {modal === "editBrand" && modalBrand && (
        <EditBrandModal brand={modalBrand} onClose={() => setModal(null)} />
      )}
      {modal === "editShop" && modalShop && (
        <EditShopModal shop={modalShop} onClose={() => setModal(null)} />
      )}
    </div>
  );
}
