import { useState } from "react";
import { useParams, useNavigate, Link as RouterLink } from "react-router-dom";
import { useQuery } from "@tanstack/react-query";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import IconButton from "@mui/material/IconButton";
import Link from "@mui/material/Link";
import { useAlert } from "../context/AlertContext";
import { useAuth } from "../context/AuthContext";
import Forbidden from "../components/Forbidden";

import { apiFetch } from "../utils/api";
import { formatCurrency, formatDate } from "../utils/formatters";
import {
  warehouseReceiptDetailOptions,
  type WarehouseReceipt,
  type WarehouseReceiptItem,
  type WarehouseReceiptAttachment,
} from "../lib/queries/warehouse";
import { useApiMutation } from "../lib/queries/mutations";
import {
  Button,
  Card,
  DataTable,
  StatusChip,
  EmptyState,
  LoadingState,
  PageHeader,
  ConfirmDialog,
  PageEnter,
  headerActionsSx,
  type DataColumn,
} from "../ui";

const STATUS_COLOR: Record<
  string,
  "default" | "success" | "error" | "warning" | "info"
> = {
  DRAFT: "warning",
  CONFIRMED: "success",
  CANCELLED: "error",
};

const STATUS_LABEL: Record<string, string> = {
  DRAFT: "Návrh",
  CONFIRMED: "Potvrzeno",
  CANCELLED: "Zrušeno",
};

function formatFileSize(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} kB`;
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}

const BackIcon = (
  <svg
    width="20"
    height="20"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <path d="M19 12H5M12 19l-7-7 7-7" />
  </svg>
);

const TrashIcon = (
  <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>
);

export default function WarehouseReceiptDetail() {
  const { id } = useParams();
  const alert = useAlert();
  const { hasPermission } = useAuth();
  const navigate = useNavigate();

  const [cancelConfirm, setCancelConfirm] = useState(false);

  const {
    data: receipt,
    isPending,
    error,
  } = useQuery(warehouseReceiptDetailOptions(id));

  const confirmMutation = useApiMutation<number, void>({
    url: (receiptId) => `/api/admin/warehouse/receipts/${receiptId}/confirm`,
    method: () => "POST",
    invalidate: ["warehouse"],
    onSuccess: () => {
      alert.success("Doklad byl potvrzen");
    },
  });

  const cancelMutation = useApiMutation<number, void>({
    url: (receiptId) => `/api/admin/warehouse/receipts/${receiptId}/cancel`,
    method: () => "POST",
    invalidate: ["warehouse"],
    onSuccess: () => {
      setCancelConfirm(false);
      alert.success("Doklad byl zrušen");
    },
  });

  const deleteAttachmentMutation = useApiMutation<
    { receiptId: number; attachmentId: number },
    void
  >({
    url: ({ receiptId, attachmentId }) =>
      `/api/admin/warehouse/receipts/${receiptId}/attachments/${attachmentId}`,
    method: () => "DELETE",
    invalidate: ["warehouse"],
    onSuccess: () => {
      alert.success("Příloha byla smazána");
    },
  });

  // All hooks above this line — permission gate is the last thing before render.
  if (!hasPermission("warehouse.view")) return <Forbidden />;

  const canOperate = hasPermission("warehouse.operate");

  const handleConfirm = async () => {
    if (!receipt) return;
    try {
      await confirmMutation.mutateAsync(receipt.id);
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    }
  };

  const handleCancel = async () => {
    if (!receipt) return;
    try {
      await cancelMutation.mutateAsync(receipt.id);
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    }
  };

  const handleDeleteAttachment = async (attachmentId: number) => {
    if (!receipt) return;
    try {
      await deleteAttachmentMutation.mutateAsync({
        receiptId: receipt.id,
        attachmentId,
      });
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    }
  };

  // A plain <a href> cannot send the Authorization header, so attachments are
  // fetched via apiFetch and handed to the browser as a temporary blob URL.
  const handleDownloadAttachment = async (att: WarehouseReceiptAttachment) => {
    if (!receipt) return;
    try {
      const response = await apiFetch(
        `/api/admin/warehouse/receipts/${receipt.id}/attachments/${att.id}`,
      );
      if (!response.ok) {
        const result = await response.json().catch(() => ({}));
        alert.error(result.error || "Nepodařilo se stáhnout přílohu");
        return;
      }
      const blob = await response.blob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = att.file_name;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      setTimeout(() => URL.revokeObjectURL(url), 60000);
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    }
  };

  const confirming = confirmMutation.isPending;
  const cancelling = cancelMutation.isPending;

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

  if (error || !receipt) {
    return (
      <Box>
        <PageHeader
          title="Příjemka"
          actions={
            <Button
              component={RouterLink}
              to="/warehouse/receipts"
              variant="outlined"
              color="inherit"
              startIcon={BackIcon}
            >
              Zpět
            </Button>
          }
        />
        <Card>
          <EmptyState title="Doklad nebyl nalezen." />
        </Card>
      </Box>
    );
  }

  const r = receipt as WarehouseReceipt;
  const items = r.items ?? [];
  const attachments = r.attachments ?? [];

  const itemColumns: DataColumn<WarehouseReceiptItem>[] = [
    {
      key: "item",
      header: "Položka",
      width: "25%",
      bold: true,
      render: (row) => row.item?.name || `ID: ${row.item_id}`,
    },
    {
      key: "quantity",
      header: "Množství",
      width: "12%",
      mono: true,
      render: (row) => String(Number(row.quantity)),
    },
    {
      key: "unit_price",
      header: "Cena/ks",
      width: "16%",
      mono: true,
      render: (row) => formatCurrency(Number(row.unit_price), "CZK"),
    },
    {
      key: "total",
      header: "Celkem",
      width: "16%",
      mono: true,
      bold: true,
      render: (row) =>
        formatCurrency(Number(row.quantity) * Number(row.unit_price), "CZK"),
    },
    {
      key: "location",
      header: "Lokace",
      width: "16%",
      mono: true,
      render: (row) => row.location?.code || "—",
    },
    {
      key: "notes",
      header: "Poznámka",
      width: "15%",
      render: (row) => row.notes || "—",
    },
  ];

  const attachmentColumns: DataColumn<WarehouseReceiptAttachment>[] = [
    {
      key: "file_name",
      header: "Název souboru",
      width: "45%",
      bold: true,
      render: (att) => (
        <Link
          component="button"
          type="button"
          onClick={() => handleDownloadAttachment(att)}
          sx={{ textAlign: "left", font: "inherit" }}
        >
          {att.file_name}
        </Link>
      ),
    },
    {
      key: "file_size",
      header: "Velikost",
      width: "15%",
      mono: true,
      render: (att) => formatFileSize(att.file_size),
    },
    {
      key: "created_at",
      header: "Datum",
      width: "20%",
      mono: true,
      render: (att) => formatDate(att.created_at),
    },
    {
      key: "actions",
      header: "Akce",
      width: "20%",
      render: (att) =>
        r.status === "DRAFT" && canOperate ? (
          <IconButton
            size="small"
            onClick={() => handleDeleteAttachment(att.id)}
            title="Smazat přílohu"
            aria-label="Smazat přílohu"
            color="error"
          >
            {TrashIcon}
          </IconButton>
        ) : null,
    },
  ];

  return (
    <PageEnter>
      {/* Header */}
      <PageHeader
        title={r.receipt_number || "Nový doklad"}
        subtitle={r.supplier?.name}
        actions={
          <Box sx={headerActionsSx}>
            <Button
              component={RouterLink}
              to="/warehouse/receipts"
              variant="outlined"
              color="inherit"
              startIcon={BackIcon}
            >
              Zpět
            </Button>
            <StatusChip
              label={STATUS_LABEL[r.status] ?? r.status}
              color={STATUS_COLOR[r.status] ?? "default"}
            />
            {canOperate && r.status === "DRAFT" && (
              <>
                <Button
                  variant="outlined"
                  color="inherit"
                  onClick={() => navigate(`/warehouse/receipts/${r.id}/edit`)}
                >
                  Upravit
                </Button>
                <Button onClick={handleConfirm} disabled={confirming}>
                  {confirming ? "Potvrzování..." : "Potvrdit"}
                </Button>
                <Button
                  variant="outlined"
                  color="error"
                  onClick={() => setCancelConfirm(true)}
                >
                  Zrušit
                </Button>
              </>
            )}
            {canOperate && r.status === "CONFIRMED" && (
              <Button
                variant="outlined"
                color="error"
                onClick={() => setCancelConfirm(true)}
              >
                Zrušit
              </Button>
            )}
          </Box>
        }
      />

      {/* Basic info */}
      <Card sx={{ mb: 3 }}>
        <Typography variant="subtitle2" sx={{ mb: 2, fontWeight: 600 }}>
          Základní údaje
        </Typography>
        <Box
          sx={{
            display: "grid",
            gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" },
            gap: 2,
          }}
        >
          <Box>
            <Typography variant="caption" color="text.secondary">
              Číslo dokladu
            </Typography>
            <Typography
              variant="body2"
              sx={{
                fontFamily: "'DM Mono', Menlo, monospace",
                fontWeight: 500,
              }}
            >
              {r.receipt_number || "—"}
            </Typography>
          </Box>
          <Box>
            <Typography variant="caption" color="text.secondary">
              Dodavatel
            </Typography>
            <Typography
              variant="body2"
              sx={{
                fontFamily: "'DM Mono', Menlo, monospace",
                fontWeight: 500,
              }}
            >
              {r.supplier?.name || "—"}
            </Typography>
          </Box>
          <Box>
            <Typography variant="caption" color="text.secondary">
              Číslo dodacího listu
            </Typography>
            <Typography
              variant="body2"
              sx={{ fontFamily: "'DM Mono', Menlo, monospace" }}
            >
              {r.delivery_note_number || "—"}
            </Typography>
          </Box>
          <Box>
            <Typography variant="caption" color="text.secondary">
              Datum dodacího listu
            </Typography>
            <Typography
              variant="body2"
              sx={{ fontFamily: "'DM Mono', Menlo, monospace" }}
            >
              {formatDate(r.delivery_note_date)}
            </Typography>
          </Box>
          <Box>
            <Typography variant="caption" color="text.secondary">
              Přijal
            </Typography>
            <Typography
              variant="body2"
              sx={{
                fontFamily: "'DM Mono', Menlo, monospace",
                fontWeight: 500,
              }}
            >
              {r.received_by_user
                ? `${r.received_by_user.first_name} ${r.received_by_user.last_name}`
                : "—"}
            </Typography>
          </Box>
          <Box>
            <Typography variant="caption" color="text.secondary">
              Vytvořeno
            </Typography>
            <Typography
              variant="body2"
              sx={{ fontFamily: "'DM Mono', Menlo, monospace" }}
            >
              {formatDate(r.created_at)}
            </Typography>
          </Box>
          {r.notes && (
            <Box sx={{ gridColumn: { sm: "1 / -1" } }}>
              <Typography variant="caption" color="text.secondary">
                Poznámky
              </Typography>
              <Typography variant="body2" sx={{ whiteSpace: "pre-wrap" }}>
                {r.notes}
              </Typography>
            </Box>
          )}
        </Box>
      </Card>

      {/* Lines table */}
      <Card sx={{ mb: 3 }}>
        <Typography variant="subtitle2" sx={{ mb: 2, fontWeight: 600 }}>
          Položky
        </Typography>
        <DataTable<WarehouseReceiptItem>
          columns={itemColumns}
          rows={items}
          rowKey={(row) => row.id}
          empty={<EmptyState title="Žádné řádky" />}
        />
      </Card>

      {/* Attachments */}
      <Card sx={{ mb: 3 }}>
        <Typography variant="subtitle2" sx={{ mb: 2, fontWeight: 600 }}>
          Přílohy
        </Typography>
        <DataTable<WarehouseReceiptAttachment>
          columns={attachmentColumns}
          rows={attachments}
          rowKey={(att) => att.id}
          empty={<EmptyState title="Žádné přílohy" />}
        />
      </Card>

      {/* Cancel confirmation dialog */}
      <ConfirmDialog
        isOpen={cancelConfirm}
        onClose={() => setCancelConfirm(false)}
        onConfirm={handleCancel}
        title="Zrušit doklad"
        message={`Opravdu chcete zrušit příjmový doklad „${r.receipt_number || r.id}"?`}
        confirmText="Zrušit doklad"
        confirmVariant="danger"
        loading={cancelling}
      />
    </PageEnter>
  );
}
