import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { useAuth } from "../context/AuthContext";
import Forbidden from "../components/Forbidden";
import Box from "@mui/material/Box";
import { projectListOptions } from "../lib/queries/projects";
import {
  warehouseStockStatusOptions,
  warehouseBelowMinimumOptions,
  warehouseCategoryListOptions,
  warehouseMovementLogOptions,
  type WarehouseItem,
  type MovementLogRow,
} from "../lib/queries/warehouse";
import { jsonQuery } from "../lib/apiAdapter";
import { formatCurrency, formatDate } from "../utils/formatters";
import {
  Alert,
  Button,
  Card,
  DataTable,
  Select,
  DateField,
  StatusChip,
  PageHeader,
  PageEnter,
  FilterBar,
  EmptyState,
  LoadingState,
  Tabs,
  TabPanel,
  type DataColumn,
  type TabDef,
} from "../ui";

type TabId =
  | "stock-status"
  | "project-consumption"
  | "movement-log"
  | "below-minimum";

interface ProjectConsumptionRow {
  item_name: string;
  project_name: string;
  total_qty: number;
  total_value: number;
}

const TABS: TabDef[] = [
  { value: "stock-status", label: "Stav zásob" },
  { value: "project-consumption", label: "Spotřeba projektů" },
  { value: "movement-log", label: "Pohyby" },
  { value: "below-minimum", label: "Pod minimem" },
];

// Movement type → StatusChip color (legacy: incoming=success, outgoing=info, inventory=info)
const MOVEMENT_COLOR: Record<string, "success" | "info"> = {
  receipt: "success",
  issue: "info",
  inventory: "info",
};

export default function WarehouseReports() {
  const { hasPermission } = useAuth();
  const [activeTab, setActiveTab] = useState<TabId>("stock-status");

  // Stock status filters
  const [categoryId, setCategoryId] = useState<number | "">("");

  // Project consumption filters
  const [consumptionProjectId, setConsumptionProjectId] = useState<number | "">(
    "",
  );
  const [consumptionDateFrom, setConsumptionDateFrom] = useState("");
  const [consumptionDateTo, setConsumptionDateTo] = useState("");

  // Movement log filters
  const [movementType, setMovementType] = useState<string>("");
  const [movementDateFrom, setMovementDateFrom] = useState("");
  const [movementDateTo, setMovementDateTo] = useState("");

  if (!hasPermission("warehouse.view")) return <Forbidden />;

  return (
    <PageEnter>
      <PageHeader title="Skladové reporty" />

      <Tabs
        value={activeTab}
        onChange={(v) => setActiveTab(v as TabId)}
        tabs={TABS}
      />

      <TabPanel value="stock-status" current={activeTab}>
        <StockStatusTab categoryId={categoryId} setCategoryId={setCategoryId} />
      </TabPanel>

      <TabPanel value="project-consumption" current={activeTab}>
        <ProjectConsumptionTab
          projectId={consumptionProjectId}
          setProjectId={setConsumptionProjectId}
          dateFrom={consumptionDateFrom}
          setDateFrom={setConsumptionDateFrom}
          dateTo={consumptionDateTo}
          setDateTo={setConsumptionDateTo}
        />
      </TabPanel>

      <TabPanel value="movement-log" current={activeTab}>
        <MovementLogTab
          type={movementType}
          setType={setMovementType}
          dateFrom={movementDateFrom}
          setDateFrom={setMovementDateFrom}
          dateTo={movementDateTo}
          setDateTo={setMovementDateTo}
        />
      </TabPanel>

      <TabPanel value="below-minimum" current={activeTab}>
        <BelowMinimumTab />
      </TabPanel>
    </PageEnter>
  );
}

/* ---------- Tab 1: Stock Status ---------- */

function StockStatusTab({
  categoryId,
  setCategoryId,
}: {
  categoryId: number | "";
  setCategoryId: (v: number | "") => void;
}) {
  const { data: categories = [] } = useQuery(warehouseCategoryListOptions());
  const { data: items, isPending } = useQuery(
    warehouseStockStatusOptions({
      category_id: categoryId ? Number(categoryId) : undefined,
    }),
  );

  const columns: DataColumn<WarehouseItem>[] = [
    {
      key: "name",
      header: "Název",
      width: "30%",
      bold: true,
      render: (item) => item.name,
    },
    {
      key: "total_quantity",
      header: "Celkem",
      width: "12%",
      mono: true,
      render: (item) => String(item.total_quantity ?? 0),
    },
    {
      key: "available_quantity",
      header: "K dispozici",
      width: "13%",
      mono: true,
      render: (item) => String(item.available_quantity ?? 0),
    },
    {
      key: "stock_value",
      header: "Hodnota",
      width: "17%",
      mono: true,
      render: (item) =>
        item.stock_value != null
          ? formatCurrency(item.stock_value, "CZK")
          : "0,00 Kč",
    },
    {
      key: "min_quantity",
      header: "Min. množství",
      width: "14%",
      mono: true,
      render: (item) => (item.min_quantity ?? "—").toString(),
    },
    {
      key: "status",
      header: "Stav",
      width: "14%",
      render: (item) =>
        item.below_minimum ? (
          <StatusChip label="Pod min." color="error" />
        ) : (
          <StatusChip label="OK" color="success" />
        ),
    },
  ];

  return (
    <Box>
      <FilterBar>
        {categories.length > 0 && (
          <Box sx={{ flex: "0 0 220px" }}>
            <Select
              value={categoryId === "" ? "" : String(categoryId)}
              onChange={(val) => setCategoryId(val === "" ? "" : Number(val))}
              options={[
                { value: "", label: "Všechny kategorie" },
                ...categories.map((cat) => ({
                  value: String(cat.id),
                  label: cat.name,
                })),
              ]}
            />
          </Box>
        )}
      </FilterBar>

      {isPending ? (
        <LoadingState />
      ) : (
        <Card>
          <DataTable<WarehouseItem>
            columns={columns}
            rows={(items as WarehouseItem[] | undefined) ?? []}
            rowKey={(item) => item.id}
            empty={<EmptyState title="Žádné položky" />}
          />
        </Card>
      )}
    </Box>
  );
}

/* ---------- Tab 2: Project Consumption ---------- */

function ProjectConsumptionTab({
  projectId,
  setProjectId,
  dateFrom,
  setDateFrom,
  dateTo,
  setDateTo,
}: {
  projectId: number | "";
  setProjectId: (v: number | "") => void;
  dateFrom: string;
  setDateFrom: (v: string) => void;
  dateTo: string;
  setDateTo: (v: string) => void;
}) {
  const { data: projectsData } = useQuery(projectListOptions({ perPage: 100 }));
  const projects =
    (projectsData?.data as {
      id: number;
      project_number: string;
      name: string;
    }[]) ?? [];

  // Filters applied on "Zobrazit"; the query key carries them so results land in
  // the ["warehouse"] cache and refresh on warehouse mutations.
  const [applied, setApplied] = useState<{
    projectId: number | "";
    dateFrom: string;
    dateTo: string;
  } | null>(null);

  const {
    data,
    isFetching: loading,
    error,
  } = useQuery({
    queryKey: ["warehouse", "project-consumption", applied],
    enabled: applied !== null,
    queryFn: () => {
      const params = new URLSearchParams();
      if (applied?.projectId)
        params.set("project_id", String(applied.projectId));
      if (applied?.dateFrom) params.set("date_from", applied.dateFrom);
      if (applied?.dateTo) params.set("date_to", applied.dateTo);
      const qs = params.toString();
      return jsonQuery<ProjectConsumptionRow[]>(
        `/api/admin/warehouse/reports/project-consumption${qs ? `?${qs}` : ""}`,
      );
    },
  });

  const fetched = applied !== null;
  const handleFetch = () => setApplied({ projectId, dateFrom, dateTo });

  const columns: DataColumn<ProjectConsumptionRow & { _idx: number }>[] = [
    {
      key: "item_name",
      header: "Položka",
      width: "32%",
      bold: true,
      render: (row) => row.item_name,
    },
    {
      key: "project_name",
      header: "Projekt",
      width: "32%",
      render: (row) => row.project_name,
    },
    {
      key: "total_qty",
      header: "Množství",
      width: "18%",
      mono: true,
      render: (row) => String(row.total_qty),
    },
    {
      key: "total_value",
      header: "Hodnota",
      width: "18%",
      mono: true,
      render: (row) => formatCurrency(row.total_value, "CZK"),
    },
  ];

  return (
    <Box>
      <FilterBar>
        {projects.length > 0 && (
          <Box sx={{ flex: "0 0 220px" }}>
            <Select
              value={projectId === "" ? "" : String(projectId)}
              onChange={(val) => setProjectId(val === "" ? "" : Number(val))}
              options={[
                { value: "", label: "Všechny projekty" },
                ...projects.map((p) => ({
                  value: String(p.id),
                  label: `${p.project_number} – ${p.name}`,
                })),
              ]}
            />
          </Box>
        )}
        <Box sx={{ flex: "0 0 150px" }}>
          <DateField value={dateFrom} onChange={setDateFrom} label="Od" />
        </Box>
        <Box sx={{ flex: "0 0 150px" }}>
          <DateField value={dateTo} onChange={setDateTo} label="Do" />
        </Box>
        <Button type="button" onClick={handleFetch} disabled={loading}>
          {loading ? "Načítání..." : "Zobrazit"}
        </Button>
      </FilterBar>

      {!fetched && <EmptyState title="Zvolte filtr a klikněte na Zobrazit" />}

      {fetched && loading && <LoadingState />}

      {fetched && !loading && error && (
        <Alert severity="error">
          {error instanceof Error
            ? error.message
            : "Nepodařilo se načíst spotřebu projektů"}
        </Alert>
      )}

      {fetched && !loading && !error && data && (
        <Card>
          <DataTable<ProjectConsumptionRow & { _idx: number }>
            columns={columns}
            rows={data.map((row, i) => ({ ...row, _idx: i }))}
            rowKey={(row) => row._idx}
            empty={<EmptyState title="Žádná data" />}
          />
        </Card>
      )}
    </Box>
  );
}

/* ---------- Tab 3: Movement Log ---------- */

function MovementLogTab({
  type,
  setType,
  dateFrom,
  setDateFrom,
  dateTo,
  setDateTo,
}: {
  type: string;
  setType: (v: string) => void;
  dateFrom: string;
  setDateFrom: (v: string) => void;
  dateTo: string;
  setDateTo: (v: string) => void;
}) {
  // Filters applied on "Zobrazit"; uses the shared movement-log query option so
  // results land in the ["warehouse"] cache and refresh on warehouse mutations.
  const [applied, setApplied] = useState<{
    type: string;
    dateFrom: string;
    dateTo: string;
  } | null>(null);

  const {
    data,
    isFetching: loading,
    error,
  } = useQuery({
    ...warehouseMovementLogOptions({
      type: applied?.type || undefined,
      date_from: applied?.dateFrom || undefined,
      date_to: applied?.dateTo || undefined,
    }),
    enabled: applied !== null,
  });

  const fetched = applied !== null;
  const handleFetch = () => setApplied({ type, dateFrom, dateTo });

  const TYPE_LABEL: Record<string, string> = {
    receipt: "Příjem",
    issue: "Výdej",
  };

  const columns: DataColumn<MovementLogRow & { _idx: number }>[] = [
    {
      key: "date",
      header: "Datum",
      width: "12%",
      mono: true,
      render: (row) => formatDate(row.date),
    },
    {
      key: "type",
      header: "Typ",
      width: "12%",
      render: (row) => (
        <StatusChip
          label={TYPE_LABEL[row.type] ?? row.type}
          color={MOVEMENT_COLOR[row.type] ?? "info"}
        />
      ),
    },
    {
      key: "document_number",
      header: "Doklad",
      width: "14%",
      mono: true,
      render: (row) => row.document_number || "—",
    },
    {
      key: "item_name",
      header: "Položka",
      width: "22%",
      bold: true,
      render: (row) => row.item_name,
    },
    {
      key: "quantity",
      header: "Množství",
      width: "10%",
      mono: true,
      render: (row) => String(row.quantity),
    },
    {
      key: "unit_price",
      header: "Cena/ks",
      width: "12%",
      mono: true,
      render: (row) => formatCurrency(row.unit_price, "CZK"),
    },
    {
      key: "supplier_or_project",
      header: "Dodavatel / Projekt",
      width: "18%",
      render: (row) => row.supplier_or_project || "—",
    },
  ];

  return (
    <Box>
      <FilterBar>
        <Box sx={{ flex: "0 0 160px" }}>
          <Select
            value={type}
            onChange={setType}
            options={[
              { value: "", label: "Všechny typy" },
              { value: "receipt", label: "Příjem" },
              { value: "issue", label: "Výdej" },
            ]}
          />
        </Box>
        <Box sx={{ flex: "0 0 150px" }}>
          <DateField value={dateFrom} onChange={setDateFrom} label="Od" />
        </Box>
        <Box sx={{ flex: "0 0 150px" }}>
          <DateField value={dateTo} onChange={setDateTo} label="Do" />
        </Box>
        <Button type="button" onClick={handleFetch} disabled={loading}>
          {loading ? "Načítání..." : "Zobrazit"}
        </Button>
      </FilterBar>

      {!fetched && <EmptyState title="Zvolte filtr a klikněte na Zobrazit" />}

      {fetched && loading && <LoadingState />}

      {fetched && !loading && error && (
        <Alert severity="error">
          {error instanceof Error
            ? error.message
            : "Nepodařilo se načíst pohyby"}
        </Alert>
      )}

      {fetched && !loading && !error && data && (
        <Card>
          <DataTable<MovementLogRow & { _idx: number }>
            columns={columns}
            rows={data.map((row, i) => ({ ...row, _idx: i }))}
            rowKey={(row) => row._idx}
            empty={<EmptyState title="Žádná data" />}
          />
        </Card>
      )}
    </Box>
  );
}

/* ---------- Tab 4: Below Minimum ---------- */

function BelowMinimumTab() {
  const { data: items, isPending } = useQuery(warehouseBelowMinimumOptions());

  const columns: DataColumn<WarehouseItem>[] = [
    {
      key: "name",
      header: "Název",
      width: "40%",
      bold: true,
      render: (item) => item.name,
    },
    {
      key: "total_quantity",
      header: "Celkem",
      width: "20%",
      mono: true,
      render: (item) => String(item.total_quantity ?? 0),
    },
    {
      key: "available_quantity",
      header: "K dispozici",
      width: "20%",
      mono: true,
      render: (item) => String(item.available_quantity ?? 0),
    },
    {
      key: "min_quantity",
      header: "Min. množství",
      width: "20%",
      mono: true,
      bold: true,
      render: (item) => String(item.min_quantity ?? 0),
    },
  ];

  if (isPending) {
    return <LoadingState />;
  }

  return (
    <Card>
      <DataTable<WarehouseItem>
        columns={columns}
        rows={(items as WarehouseItem[] | undefined) ?? []}
        rowKey={(item) => item.id}
        rowDanger={() => true}
        empty={<EmptyState title="Všechny položky jsou nad minimem" />}
      />
    </Card>
  );
}
