import { useState, useEffect, useRef } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { Link as RouterLink, useNavigate } from "react-router-dom";
import Box from "@mui/material/Box";
import IconButton from "@mui/material/IconButton";
import { useAlert } from "../context/AlertContext";
import { useAuth } from "../context/AuthContext";
import Forbidden from "../components/Forbidden";
import StatusChipMenu, {
  type StatusChipAction,
} from "../components/StatusChipMenu";
import apiFetch from "../utils/api";
import {
  formatCurrency,
  formatDate,
  formatMultiCurrency,
} from "../utils/formatters";
import useTableSort from "../hooks/useTableSort";
import useDebounce from "../hooks/useDebounce";
import { usePaginatedQuery } from "../hooks/usePaginatedQuery";
import {
  orderListOptions,
  orderStatsOptions,
  orderNextNumberOptions,
} from "../lib/queries/orders";
import { offerCustomersOptions } from "../lib/queries/offers";
import { companySettingsOptions } from "../lib/queries/settings";
import { useApiMutation } from "../lib/queries/mutations";
import {
  Card,
  DataTable,
  Pagination,
  Modal,
  ConfirmDialog,
  Field,
  TextField,
  Select,
  CheckboxField,
  FileUpload,
  FilterBar,
  EmptyState,
  LoadingState,
  type DataColumn,
} from "../ui";
import {
  ORDER_STATUS,
  statusLabel,
  statusColor,
  statusOptions,
} from "../lib/documentStatus";

const API_BASE = "/api/admin";

const STATUS_OPTIONS = statusOptions(ORDER_STATUS, {
  value: "",
  label: "Všechny stavy",
});

interface Order {
  id: number;
  order_number: string;
  quotation_id: number;
  quotation_number: string;
  customer_name: string;
  status: string;
  created_at: string;
  total: number;
  currency: string;
  invoice_id?: number;
}

const ViewIcon = (
  <svg
    width="18"
    height="18"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
    <circle cx="12" cy="12" r="3" />
  </svg>
);
const InvoiceViewIcon = (
  <svg
    width="18"
    height="18"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
    <polyline points="14 2 14 8 20 8" />
    <text
      x="12"
      y="16.5"
      textAnchor="middle"
      fill="currentColor"
      stroke="none"
      fontSize="9"
      fontWeight="700"
    >
      F
    </text>
  </svg>
);
const InvoiceCreateIcon = (
  <svg
    width="18"
    height="18"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
    <polyline points="14 2 14 8 20 8" />
    <line x1="12" y1="11" x2="12" y2="17" />
    <line x1="9" y1="14" x2="15" y2="14" />
  </svg>
);
const DeleteIcon = (
  <svg
    width="18"
    height="18"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
    strokeLinecap="round"
    strokeLinejoin="round"
  >
    <polyline points="3 6 5 6 21 6" />
    <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
  </svg>
);

interface OrdersReceivedProps {
  month: number;
  year: number;
  createOpen: boolean;
  setCreateOpen: (open: boolean) => void;
}

export default function OrdersReceived({
  month,
  year,
  createOpen,
  setCreateOpen,
}: OrdersReceivedProps) {
  const alert = useAlert();
  const { hasPermission } = useAuth();

  const { sort, order, handleSort } = useTableSort("order_number");
  const [search, setSearch] = useState("");
  const debouncedSearch = useDebounce(search, 300);
  const [status, setStatus] = useState("");
  const [page, setPage] = useState(1);
  // Track first successful load so later refetches (filter/status/page change)
  // keep the table visible instead of flashing the full-page skeleton.
  const hasLoadedOnce = useRef(false);

  const [deleteConfirm, setDeleteConfirm] = useState<{
    show: boolean;
    order: Order | null;
  }>({ show: false, order: null });
  const [deleteFiles, setDeleteFiles] = useState(false);

  const deleteMutation = useApiMutation<
    { id: number; delete_files: boolean },
    { message?: string; error?: string }
  >({
    url: ({ id }) => `${API_BASE}/orders/${id}`,
    method: () => "DELETE",
    invalidate: ["orders", "offers", "projects", "invoices"],
    onSuccess: (data) => {
      setDeleteConfirm({ show: false, order: null });
      setDeleteFiles(false);
      alert.success(data?.message || "Objednávka byla smazána");
    },
  });

  // Quick status change from the table chip (StatusChipMenu). The `id` rides
  // along in the input only to build the URL; UpdateOrderSchema strips it.
  const statusMutation = useApiMutation<
    { id: number; status: string },
    unknown
  >({
    url: ({ id }) => `${API_BASE}/orders/${id}`,
    method: () => "PUT",
    invalidate: ["orders", "offers", "projects", "invoices"],
  });

  const [createForm, setCreateForm] = useState({
    customer_id: "",
    customer_order_number: "",
    currency: "CZK",
    scope_title: "",
    scope_description: "",
    notes: "",
    create_project: true,
    price: "",
    quantity: "1",
  });
  const [creating, setCreating] = useState(false);
  const queryClient = useQueryClient();
  const navigate = useNavigate();
  const [orderAttachment, setOrderAttachment] = useState<File | null>(null);

  const customersQuery = useQuery({
    ...offerCustomersOptions(),
    enabled: createOpen,
  });
  const nextNumberQuery = useQuery({
    ...orderNextNumberOptions(),
    enabled: createOpen,
  });
  const companySettings = useQuery(companySettingsOptions()).data;
  // Configurable currency list from company settings (falls back to the
  // built-in list when settings are empty) — matches Offers/Invoices.
  const currencyOptions = (
    companySettings?.available_currencies || ["CZK", "EUR", "USD", "GBP"]
  ).map((c) => ({ value: c, label: c }));

  const closeCreate = () => {
    setCreateOpen(false);
    setCreateForm({
      customer_id: "",
      customer_order_number: "",
      currency: "CZK",
      scope_title: "",
      scope_description: "",
      notes: "",
      create_project: true,
      price: "",
      quantity: "1",
    });
    setOrderAttachment(null);
  };

  const handleCreate = async () => {
    setCreating(true);
    try {
      const priceNum = createForm.price ? Number(createForm.price) : 0;
      const qtyNum = createForm.quantity ? Number(createForm.quantity) : 1;
      const items =
        priceNum > 0
          ? [
              {
                description: createForm.scope_title || "Položka",
                quantity: qtyNum,
                unit_price: priceNum,
                is_included_in_total: true,
              },
            ]
          : undefined;

      let fetchOptions: RequestInit;
      if (orderAttachment) {
        const fd = new FormData();
        if (createForm.customer_id)
          fd.append("customer_id", createForm.customer_id);
        fd.append("customer_order_number", createForm.customer_order_number);
        fd.append("currency", createForm.currency);
        fd.append("scope_title", createForm.scope_title);
        fd.append("scope_description", createForm.scope_description);
        fd.append("notes", createForm.notes);
        fd.append("create_project", createForm.create_project ? "1" : "0");
        if (items) fd.append("items", JSON.stringify(items));
        fd.append("attachment", orderAttachment);
        fetchOptions = { method: "POST", body: fd };
      } else {
        fetchOptions = {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            customer_id: createForm.customer_id
              ? Number(createForm.customer_id)
              : null,
            customer_order_number: createForm.customer_order_number,
            currency: createForm.currency,
            scope_title: createForm.scope_title,
            scope_description: createForm.scope_description,
            notes: createForm.notes,
            create_project: createForm.create_project,
            ...(items ? { items } : {}),
          }),
        };
      }

      const response = await apiFetch(`${API_BASE}/orders`, fetchOptions);
      const result = await response.json();
      if (result.success) {
        closeCreate();
        alert.success(result.message || "Objednávka byla vytvořena");
        await queryClient.invalidateQueries({ queryKey: ["orders"] });
        await queryClient.invalidateQueries({ queryKey: ["projects"] });
        await queryClient.invalidateQueries({ queryKey: ["offers"] });
        await queryClient.invalidateQueries({ queryKey: ["invoices"] });
        if (result.data?.id) navigate(`/orders/${result.data.id}`);
      } else {
        alert.error(result.error || "Nepodařilo se vytvořit objednávku");
      }
    } catch {
      alert.error("Chyba připojení");
    } finally {
      setCreating(false);
    }
  };

  const {
    items: orders,
    pagination,
    isPending,
    isFetching,
  } = usePaginatedQuery<Order>(
    orderListOptions({
      search: debouncedSearch,
      sort,
      order,
      page,
      status: status || undefined,
      month,
      year,
    }),
  );

  // Per-currency total over the WHOLE filtered set (not one page). Uses the
  // SAME filters as the list query so the summary matches what's shown.
  const statsQuery = useQuery(
    orderStatsOptions({
      search: debouncedSearch,
      status: status || undefined,
      month,
      year,
    }),
  );

  // Mark first load done in an effect (not during render) to avoid a
  // render-phase ref mutation.
  useEffect(() => {
    if (!isPending) hasLoadedOnce.current = true;
  }, [isPending]);

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

  const handleDelete = async () => {
    if (!deleteConfirm.order) return;
    try {
      await deleteMutation.mutateAsync({
        id: deleteConfirm.order.id,
        delete_files: deleteFiles,
      });
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    }
  };

  // Only show the full-page skeleton on the very first load; on subsequent
  // refetches (filter/status/page change) keep the table visible (the Card
  // dims via isFetching) so it doesn't flash.
  if (isPending && !hasLoadedOnce.current) {
    return <LoadingState />;
  }

  // Quick actions for the status chip menu, mirroring the order status
  // machine (VALID_TRANSITIONS incl. the reopen edges). Rejections propagate
  // so the ConfirmDialog stays open per app convention; we toast here.
  const statusActions = (o: Order): StatusChipAction[] => {
    const changeStatus = (status: string) => async () => {
      try {
        await statusMutation.mutateAsync({ id: o.id, status });
        alert.success("Stav byl změněn");
      } catch (e) {
        alert.error(e instanceof Error ? e.message : "Chyba připojení");
        throw e;
      }
    };
    const stornovat: StatusChipAction = {
      key: "stornovana",
      label: "Stornovat",
      danger: true,
      confirm: {
        title: "Stornovat objednávku",
        message: `Opravdu chcete stornovat objednávku „${o.order_number}“? Propojený projekt bude automaticky zrušen.`,
        confirmText: "Stornovat",
      },
      onAction: changeStatus("stornovana"),
    };
    switch (o.status) {
      case "prijata":
        return [
          {
            key: "v_realizaci",
            label: "Zahájit realizaci",
            confirm: {
              title: "Zahájit realizaci",
              message: `Opravdu chcete zahájit realizaci objednávky „${o.order_number}“?`,
              confirmText: "Zahájit realizaci",
            },
            onAction: changeStatus("v_realizaci"),
          },
          stornovat,
        ];
      case "v_realizaci":
        return [
          {
            key: "dokoncena",
            label: "Dokončit",
            confirm: {
              title: "Dokončit objednávku",
              message: `Opravdu chcete dokončit objednávku „${o.order_number}“? Propojený projekt bude automaticky dokončen.`,
              confirmText: "Dokončit",
            },
            onAction: changeStatus("dokoncena"),
          },
          stornovat,
        ];
      case "dokoncena":
      case "stornovana":
        // Reopen — deliberately no cascade to the linked project.
        return [
          {
            key: "v_realizaci",
            label: "Obnovit",
            confirm: {
              title: "Obnovit objednávku",
              message: `Opravdu chcete obnovit objednávku „${o.order_number}“? Objednávka se vrátí do stavu "V realizaci". Propojený projekt zůstane beze změny.`,
              confirmText: "Obnovit",
            },
            onAction: changeStatus("v_realizaci"),
          },
        ];
      default:
        return [];
    }
  };

  const columns: DataColumn<Order>[] = [
    {
      key: "order_number",
      header: "Číslo",
      width: "14%",
      sortKey: "order_number",
      mono: true,
      render: (o) => (
        <Box
          component={RouterLink}
          to={`/orders/${o.id}`}
          sx={{
            color: "primary.main",
            textDecoration: "none",
            "&:hover": { textDecoration: "underline" },
          }}
        >
          {o.order_number}
        </Box>
      ),
    },
    {
      key: "quotation",
      header: "Nabídka",
      width: "14%",
      render: (o) => (
        <Box
          component={RouterLink}
          to={`/offers/${o.quotation_id}`}
          sx={{
            color: "text.secondary",
            textDecoration: "none",
            "&:hover": { textDecoration: "underline" },
          }}
        >
          {o.quotation_number}
        </Box>
      ),
    },
    {
      key: "customer",
      header: "Zákazník",
      width: "20%",
      render: (o) => o.customer_name || "—",
    },
    {
      key: "status",
      header: "Stav",
      width: "13%",
      sortKey: "status",
      render: (o) => (
        <StatusChipMenu
          label={statusLabel(ORDER_STATUS, o.status)}
          color={statusColor(ORDER_STATUS, o.status)}
          actions={statusActions(o)}
          disabled={!hasPermission("orders.edit")}
        />
      ),
    },
    {
      key: "created_at",
      header: "Datum",
      width: "12%",
      sortKey: "created_at",
      mono: true,
      render: (o) => formatDate(o.created_at),
    },
    {
      key: "total",
      header: "Celkem",
      width: "13%",
      align: "right",
      mono: true,
      bold: true,
      render: (o) => formatCurrency(o.total, o.currency),
    },
    {
      key: "actions",
      header: "Akce",
      width: "14%",
      align: "right",
      render: (o) => (
        <Box sx={{ display: "flex", gap: 0.5, justifyContent: "flex-end" }}>
          <IconButton
            size="small"
            onClick={() => navigate(`/orders/${o.id}`)}
            aria-label="Detail"
            title="Detail"
          >
            {ViewIcon}
          </IconButton>
          {o.invoice_id ? (
            <IconButton
              size="small"
              color="primary"
              onClick={() => navigate(`/invoices/${o.invoice_id}`)}
              aria-label="Zobrazit fakturu"
              title="Zobrazit fakturu"
            >
              {InvoiceViewIcon}
            </IconButton>
          ) : (
            hasPermission("invoices.create") && (
              <IconButton
                size="small"
                onClick={() => navigate(`/invoices/new?fromOrder=${o.id}`)}
                aria-label="Vytvořit fakturu"
                title="Vytvořit fakturu"
              >
                {InvoiceCreateIcon}
              </IconButton>
            )
          )}
          {hasPermission("orders.delete") && (
            <IconButton
              size="small"
              color="error"
              onClick={() => setDeleteConfirm({ show: true, order: o })}
              aria-label="Smazat"
              title="Smazat"
            >
              {DeleteIcon}
            </IconButton>
          )}
        </Box>
      ),
    },
  ];

  // Per-status row tints — subtle channel-alpha washes (never a solid `.light`
  // fill, which is invisible-text in dark mode). Completed = success wash,
  // cancelled (stornovana) = faded/muted, matching the Offers/Invoices intensity.
  const rowSx = (o: Order) => {
    if (o.status === "stornovana") {
      return {
        opacity: 0.6,
        "& td": { color: "var(--mui-palette-text-secondary)" },
      };
    }
    if (o.status === "dokoncena") {
      return {
        backgroundColor: "rgba(var(--mui-palette-success-mainChannel) / 0.12)",
        "&:hover": {
          backgroundColor:
            "rgba(var(--mui-palette-success-mainChannel) / 0.18)",
        },
      };
    }
    return {};
  };

  // Search/status filter is active → an empty list means "nothing matches"
  // (no create hint); a genuinely empty list keeps the explanatory empty state.
  const isFiltered = !!debouncedSearch || !!status;

  return (
    <>
      <FilterBar>
        <Box sx={{ flex: "1 1 320px" }}>
          <TextField
            value={search}
            onChange={(e) => {
              setSearch(e.target.value);
              setPage(1);
            }}
            placeholder="Hledat podle čísla, nabídky, projektu nebo zákazníka..."
            fullWidth
          />
        </Box>
        <Box sx={{ flex: "0 1 200px" }}>
          <Select
            value={status}
            onChange={(value) => {
              setStatus(value);
              setPage(1);
            }}
            options={STATUS_OPTIONS}
          />
        </Box>
      </FilterBar>

      <Card sx={{ opacity: isFetching ? 0.6 : 1, transition: "opacity .2s" }}>
        <DataTable<Order>
          columns={columns}
          rows={orders}
          rowKey={(o) => o.id}
          rowSx={rowSx}
          sortBy={sort}
          sortDir={order}
          onSort={handleSort}
          empty={
            isFiltered ? (
              <EmptyState title="Žádné objednávky neodpovídají filtru." />
            ) : (
              <EmptyState
                title="Zatím nejsou žádné objednávky."
                description="Objednávky se vytvářejí z nabídek."
              />
            )
          }
        />
        {(statsQuery.data?.length ?? 0) > 0 && (
          <Box
            sx={{
              display: "flex",
              justifyContent: "flex-end",
              mt: 1.5,
              px: 1,
              gap: 1,
              color: "text.secondary",
              fontSize: "0.9rem",
            }}
          >
            <span>Celkem bez DPH:</span>
            <Box
              component="span"
              sx={{ fontWeight: 700, color: "text.primary" }}
            >
              {formatMultiCurrency(statsQuery.data ?? [])}
            </Box>
          </Box>
        )}
        <Pagination
          page={page}
          pageCount={pagination?.total_pages ?? 1}
          onChange={setPage}
        />
      </Card>

      <ConfirmDialog
        isOpen={deleteConfirm.show}
        onClose={() => {
          setDeleteConfirm({ show: false, order: null });
          setDeleteFiles(false);
        }}
        onConfirm={handleDelete}
        title="Smazat objednávku"
        message={
          deleteConfirm.order
            ? `Opravdu chcete smazat objednávku „${deleteConfirm.order.order_number}“? Bude smazán i přidružený projekt. Tato akce je nevratná.`
            : ""
        }
        confirmText="Smazat"
        confirmVariant="danger"
        loading={deleteMutation.isPending}
      >
        <CheckboxField
          label="Smazat i soubory projektu na disku"
          checked={deleteFiles}
          onChange={setDeleteFiles}
        />
      </ConfirmDialog>

      <Modal
        isOpen={createOpen}
        onClose={closeCreate}
        onSubmit={handleCreate}
        title="Vytvořit objednávku bez nabídky"
        subtitle={`Číslo objednávky: ${
          nextNumberQuery.data?.number ??
          nextNumberQuery.data?.next_number ??
          "…"
        } (přiděleno automaticky)`}
        submitText="Vytvořit"
        loading={creating}
      >
        <Box sx={{ display: "flex", gap: 2, flexWrap: "wrap" }}>
          <Box sx={{ flex: "1 1 200px" }}>
            <Field label="Zákazník">
              <Select
                value={createForm.customer_id}
                onChange={(value) =>
                  setCreateForm({ ...createForm, customer_id: value })
                }
                options={[
                  { value: "", label: "Vyberte zákazníka" },
                  ...(customersQuery.data ?? []).map((c) => ({
                    value: String(c.id),
                    label: c.name,
                  })),
                ]}
              />
            </Field>
          </Box>
          <Box sx={{ flex: "1 1 200px" }}>
            <Field label="Číslo objednávky zákazníka">
              <TextField
                value={createForm.customer_order_number}
                onChange={(e) =>
                  setCreateForm({
                    ...createForm,
                    customer_order_number: e.target.value,
                  })
                }
              />
            </Field>
          </Box>
        </Box>

        <Box sx={{ display: "flex", gap: 2, flexWrap: "wrap" }}>
          <Box sx={{ flex: "1 1 200px" }}>
            <Field label="Měna">
              <Select
                value={createForm.currency}
                onChange={(value) =>
                  setCreateForm({ ...createForm, currency: value })
                }
                options={currencyOptions}
              />
            </Field>
          </Box>
        </Box>

        <Box sx={{ display: "flex", gap: 2, flexWrap: "wrap" }}>
          <Box sx={{ flex: "1 1 200px" }}>
            <Field label="Cena za jednotku (bez DPH)">
              <TextField
                type="number"
                inputMode="decimal"
                value={createForm.price}
                onChange={(e) =>
                  setCreateForm({ ...createForm, price: e.target.value })
                }
                placeholder="0"
                slotProps={{ htmlInput: { min: 0, step: 0.01 } }}
              />
            </Field>
          </Box>
          <Box sx={{ flex: "1 1 200px" }}>
            <Field label="Množství">
              <TextField
                type="number"
                inputMode="decimal"
                value={createForm.quantity}
                onChange={(e) =>
                  setCreateForm({ ...createForm, quantity: e.target.value })
                }
                slotProps={{ htmlInput: { min: 0, step: 1 } }}
              />
            </Field>
          </Box>
        </Box>

        <Field label="Předmět (scope)">
          <TextField
            value={createForm.scope_title}
            onChange={(e) =>
              setCreateForm({ ...createForm, scope_title: e.target.value })
            }
          />
        </Field>

        <Field label="Popis">
          <TextField
            multiline
            minRows={3}
            value={createForm.scope_description}
            onChange={(e) =>
              setCreateForm({
                ...createForm,
                scope_description: e.target.value,
              })
            }
          />
        </Field>

        <Field label="Poznámka">
          <TextField
            multiline
            minRows={2}
            value={createForm.notes}
            onChange={(e) =>
              setCreateForm({ ...createForm, notes: e.target.value })
            }
          />
        </Field>

        <Field label="Příloha (PO zákazníka, PDF)">
          <FileUpload
            files={orderAttachment ? [orderAttachment] : []}
            onFilesChange={(files) => setOrderAttachment(files[0] ?? null)}
            accept="application/pdf"
            multiple={false}
          />
        </Field>

        <CheckboxField
          label="Vytvořit propojený projekt"
          checked={createForm.create_project}
          onChange={(v) => setCreateForm({ ...createForm, create_project: v })}
        />
      </Modal>
    </>
  );
}
