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

import apiFetch from "../utils/api";
import {
  warehouseReceiptDetailOptions,
  warehouseSupplierListOptions,
  warehouseLocationListOptions,
  type WarehouseSupplier,
  type WarehouseLocation,
} from "../lib/queries/warehouse";
import { useApiMutation } from "../lib/queries/mutations";
import {
  Button,
  Card,
  TextField,
  Select,
  DateField,
  Field,
  LoadingState,
  PageEnter,
} from "../ui";

interface ReceiptForm {
  supplier_id: number | null;
  delivery_note_number: string;
  delivery_note_date: string;
  notes: string;
}

interface MovementItem {
  key: string;
  item_id: number | null;
  item_name?: string;
  quantity: number;
  unit_price: number;
  location_id: number | null;
  batch_id: number | null;
  reservation_id: number | null;
  notes: string | null;
}

function parseDecimal(raw: string): number {
  const cleaned = raw.replace(/[eE+-]/g, "");
  const n = Number(cleaned);
  return Number.isFinite(n) ? n : 0;
}

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 RemoveIcon = (
  <svg
    width="16"
    height="16"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
    strokeLinecap="round"
    strokeLinejoin="round"
  >
    <line x1="18" y1="6" x2="6" y2="18" />
    <line x1="6" y1="6" x2="18" y2="18" />
  </svg>
);

const PlusIcon = (
  <svg
    width="16"
    height="16"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <line x1="12" y1="5" x2="12" y2="19" />
    <line x1="5" y1="12" x2="19" y2="12" />
  </svg>
);

const UploadIcon = (
  <svg
    width="32"
    height="32"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="1.5"
    strokeLinecap="round"
    strokeLinejoin="round"
  >
    <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
    <polyline points="17 8 12 3 7 8" />
    <line x1="12" y1="3" x2="12" y2="15" />
  </svg>
);

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

  const isEdit = id !== undefined && id !== "new";

  const baseId = useId();
  const counterRef = useRef(0);
  const nextKey = useCallback(
    () => `${baseId}-item-${counterRef.current++}`,
    [baseId],
  );

  const [form, setForm] = useState<ReceiptForm>({
    supplier_id: null,
    delivery_note_number: "",
    delivery_note_date: "",
    notes: "",
  });
  const [items, setItems] = useState<MovementItem[]>(() =>
    isEdit
      ? []
      : [
          {
            key: nextKey(),
            item_id: null,
            quantity: 0,
            unit_price: 0,
            location_id: null,
            batch_id: null,
            reservation_id: null,
            notes: null,
          },
        ],
  );
  const [errors, setErrors] = useState<Record<string, string>>({});
  const [saving, setSaving] = useState(false);
  const [uploadingFiles, setUploadingFiles] = useState(false);

  const formInitialized = useRef(false);

  const { data: receipt, isPending } = useQuery(
    warehouseReceiptDetailOptions(isEdit ? id : undefined),
  );

  const { data: suppliersData } = useQuery(
    warehouseSupplierListOptions({ perPage: 100 }),
  );
  const suppliers: WarehouseSupplier[] = suppliersData?.data ?? [];

  const { data: locations } = useQuery(warehouseLocationListOptions());

  useEffect(() => {
    formInitialized.current = false;
  }, [id]);

  useEffect(() => {
    if (isEdit && receipt && !formInitialized.current) {
      setForm({
        supplier_id: receipt.supplier_id,
        delivery_note_number: receipt.delivery_note_number || "",
        delivery_note_date: receipt.delivery_note_date
          ? receipt.delivery_note_date.split("T")[0]
          : "",
        notes: receipt.notes || "",
      });
      if (receipt.items && receipt.items.length > 0) {
        setItems(
          receipt.items.map((item) => ({
            key: nextKey(),
            item_id: item.item_id,
            item_name: item.item?.name,
            quantity: Number(item.quantity),
            unit_price: Number(item.unit_price),
            location_id: item.location_id,
            batch_id: null,
            reservation_id: null,
            notes: item.notes,
          })),
        );
      }
      formInitialized.current = true;
    }
  }, [isEdit, receipt, nextKey]);

  const saveMutation = useApiMutation<
    ReturnType<typeof buildPayload>,
    { id?: number }
  >({
    url: () =>
      isEdit
        ? `/api/admin/warehouse/receipts/${id}`
        : "/api/admin/warehouse/receipts",
    method: () => (isEdit ? "PUT" : "POST"),
    invalidate: ["warehouse"],
  });

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

  const handleFileUpload = useCallback(
    async (files: FileList | File[]) => {
      if (!isEdit || !id) return;
      setUploadingFiles(true);
      try {
        for (const file of files) {
          const formData = new FormData();
          formData.append("file", file);
          const response = await apiFetch(
            `/api/admin/warehouse/receipts/${id}/attachments`,
            {
              method: "POST",
              body: formData,
            },
          );
          const result = await response.json();
          if (!result.success) {
            alert.error(
              result.error || `Nepodařilo se nahrát soubor ${file.name}`,
            );
          }
        }
        queryClient.invalidateQueries({ queryKey: ["warehouse"] });
        alert.success("Soubory byly nahrány");
      } catch {
        alert.error("Chyba připojení");
      } finally {
        setUploadingFiles(false);
      }
    },
    [id, isEdit, alert, queryClient],
  );

  const handleDrop = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault();
      if (e.dataTransfer.files.length > 0) {
        handleFileUpload(e.dataTransfer.files);
      }
    },
    [handleFileUpload],
  );

  const handleDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault();
  }, []);

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

  const addItem = () => {
    setItems((prev) => [
      ...prev,
      {
        key: nextKey(),
        item_id: null,
        quantity: 0,
        unit_price: 0,
        location_id: null,
        batch_id: null,
        reservation_id: null,
        notes: null,
      },
    ]);
  };

  const removeItem = (index: number) => {
    setItems((prev) => prev.filter((_, i) => i !== index));
  };

  const updateItem = (
    index: number,
    field: keyof MovementItem,
    value: unknown,
  ) => {
    setItems((prev) => {
      const updated = [...prev];
      updated[index] = { ...updated[index], [field]: value };
      return updated;
    });
  };

  const validate = (): boolean => {
    const newErrors: Record<string, string> = {};
    const validItems = items.filter((l) => l.item_id !== null);
    if (validItems.length === 0) {
      newErrors.items = "Přidejte alespoň jednu položku";
    }
    for (const item of validItems) {
      if (item.quantity <= 0) {
        newErrors.items = "Množství musí být větší než 0";
        break;
      }
    }
    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };

  const buildPayload = () => ({
    supplier_id: form.supplier_id,
    delivery_note_number: form.delivery_note_number.trim() || null,
    delivery_note_date: form.delivery_note_date || null,
    notes: form.notes.trim() || null,
    items: items
      .filter((l) => l.item_id !== null)
      .map((l) => ({
        item_id: l.item_id!,
        quantity: l.quantity,
        unit_price: l.unit_price,
        location_id: l.location_id,
        notes: l.notes?.trim() || null,
      })),
  });

  const saveReceipt = async (): Promise<number | null> => {
    try {
      const data = await saveMutation.mutateAsync(buildPayload());
      return data?.id ?? Number(id);
    } catch (e) {
      alert.error(
        e instanceof Error ? e.message : "Nepodařilo se uložit doklad",
      );
      return null;
    }
  };

  const confirmReceipt = async (receiptId: number) => {
    try {
      await confirmMutation.mutateAsync(receiptId);
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    }
  };

  const handleSaveDraft = async () => {
    if (!validate()) return;
    setSaving(true);
    try {
      const savedId = await saveReceipt();
      if (savedId) {
        alert.success("Doklad byl uložen jako návrh");
        navigate(`/warehouse/receipts/${savedId}`);
      }
    } finally {
      setSaving(false);
    }
  };

  const handleSaveAndConfirm = async () => {
    if (!validate()) return;
    setSaving(true);
    try {
      const savedId = await saveReceipt();
      if (savedId) {
        await confirmReceipt(savedId);
        navigate(`/warehouse/receipts/${savedId}`);
      }
    } finally {
      setSaving(false);
    }
  };

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

  const supplierOptions = [
    { value: "", label: "-- bez dodavatele --" },
    ...suppliers.map((s) => ({
      value: String(s.id),
      label: `${s.name}${s.ico ? ` (${s.ico})` : ""}`,
    })),
  ];

  const locationOptions = [
    { value: "", label: "-- bez lokace --" },
    ...(locations ?? []).map((loc: WarehouseLocation) => ({
      value: String(loc.id),
      label: `${loc.code} - ${loc.name}`,
    })),
  ];

  return (
    <PageEnter>
      {/* Header */}
      <Box
        sx={{
          display: "flex",
          alignItems: "flex-start",
          justifyContent: "space-between",
          flexWrap: "wrap",
          gap: 2,
          mb: 3,
        }}
      >
        <Box sx={{ display: "flex", alignItems: "center", gap: 1.5 }}>
          <IconButton
            component={RouterLink}
            to="/warehouse/receipts"
            title="Zpět na seznam"
            aria-label="Zpět na seznam"
          >
            {BackIcon}
          </IconButton>
          <Typography variant="h4">
            {isEdit ? "Upravit příjmový doklad" : "Nový příjmový doklad"}
          </Typography>
        </Box>
        <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
          <Button
            variant="outlined"
            color="inherit"
            onClick={handleSaveDraft}
            disabled={saving}
          >
            {saving ? "Ukládání..." : "Uložit jako návrh"}
          </Button>
          <Button onClick={handleSaveAndConfirm} disabled={saving}>
            {saving ? "Ukládání..." : "Uložit a potvrdit"}
          </Button>
        </Box>
      </Box>

      {/* Header fields */}
      <Card sx={{ mb: 3 }}>
        <Typography variant="subtitle2" sx={{ mb: 2, fontWeight: 600 }}>
          Základní údaje
        </Typography>
        <Field label="Dodavatel">
          <Select
            value={form.supplier_id === null ? "" : String(form.supplier_id)}
            onChange={(val) =>
              setForm((prev) => ({
                ...prev,
                supplier_id: val ? Number(val) : null,
              }))
            }
            options={supplierOptions}
          />
        </Field>
        <Box
          sx={{
            display: "grid",
            gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" },
            gap: 2,
          }}
        >
          <Field label="Číslo dodacího listu">
            <TextField
              value={form.delivery_note_number}
              onChange={(e) =>
                setForm((prev) => ({
                  ...prev,
                  delivery_note_number: e.target.value,
                }))
              }
              placeholder="Např. DL-2024-001"
            />
          </Field>
          <Field label="Datum dodacího listu">
            <DateField
              value={form.delivery_note_date}
              onChange={(val) =>
                setForm((prev) => ({
                  ...prev,
                  delivery_note_date: val,
                }))
              }
            />
          </Field>
        </Box>
        <Field label="Poznámky">
          <TextField
            multiline
            minRows={3}
            value={form.notes}
            onChange={(e) =>
              setForm((prev) => ({ ...prev, notes: e.target.value }))
            }
            placeholder="Volitelné poznámky"
          />
        </Field>
      </Card>

      {/* Lines */}
      <Card sx={{ mb: 3 }}>
        <Typography variant="subtitle2" sx={{ mb: 2, fontWeight: 600 }}>
          Položky
        </Typography>
        {errors.items && (
          <Typography
            variant="caption"
            color="error"
            sx={{ display: "block", mb: 1.5 }}
          >
            {errors.items}
          </Typography>
        )}
        <Box sx={{ display: "flex", flexDirection: "column", gap: 1.5 }}>
          {items.map((item, index) => (
            <Box
              key={item.key}
              sx={{
                display: "grid",
                gridTemplateColumns: {
                  xs: "1fr",
                  md: "minmax(180px, 2fr) 110px 110px minmax(140px, 1.2fr) minmax(140px, 1.5fr) auto",
                },
                gap: 1,
                alignItems: "start",
              }}
            >
              <ItemPicker
                value={item.item_id}
                itemName={item.item_name}
                onChange={(id) => updateItem(index, "item_id", id)}
              />
              <TextField
                type="number"
                value={item.quantity || ""}
                onChange={(e) =>
                  updateItem(index, "quantity", parseDecimal(e.target.value))
                }
                inputProps={{
                  min: 0,
                  step: 0.001,
                  inputMode: "decimal",
                  pattern: "[0-9]+([\\.,][0-9]+)?",
                  "aria-label": `Množství, řádek ${index + 1}`,
                }}
                placeholder="Množství"
              />
              <TextField
                type="number"
                value={item.unit_price || ""}
                onChange={(e) =>
                  updateItem(index, "unit_price", parseDecimal(e.target.value))
                }
                inputProps={{
                  min: 0,
                  step: 0.01,
                  inputMode: "decimal",
                  pattern: "[0-9]+([\\.,][0-9]+)?",
                  "aria-label": `Cena za kus, řádek ${index + 1}`,
                }}
                placeholder="Cena/ks"
              />
              <Select
                value={
                  item.location_id === null ? "" : String(item.location_id)
                }
                onChange={(val) =>
                  updateItem(index, "location_id", val ? Number(val) : null)
                }
                options={locationOptions}
              />
              <TextField
                value={item.notes ?? ""}
                onChange={(e) => updateItem(index, "notes", e.target.value)}
                placeholder="Poznámka"
              />
              <IconButton
                color="error"
                onClick={() => removeItem(index)}
                title="Odebrat řádek"
                aria-label="Odebrat řádek"
                sx={{ justifySelf: { xs: "start", md: "center" } }}
              >
                {RemoveIcon}
              </IconButton>
            </Box>
          ))}
        </Box>
        <Button
          variant="outlined"
          color="inherit"
          startIcon={PlusIcon}
          onClick={addItem}
          sx={{ mt: 2 }}
        >
          Přidat položku
        </Button>
      </Card>

      {/* File upload — only in edit mode for existing receipts */}
      {isEdit && (
        <Card sx={{ mb: 3 }}>
          <Typography variant="subtitle2" sx={{ mb: 2, fontWeight: 600 }}>
            Přílohy
          </Typography>
          <Box
            onDrop={handleDrop}
            onDragOver={handleDragOver}
            onClick={() => {
              const input = document.createElement("input");
              input.type = "file";
              input.multiple = true;
              input.onchange = () => {
                if (input.files && input.files.length > 0) {
                  handleFileUpload(input.files);
                }
              };
              input.click();
            }}
            sx={{
              display: "flex",
              flexDirection: "column",
              alignItems: "center",
              justifyContent: "center",
              gap: 1,
              p: 4,
              border: "2px dashed",
              borderColor: "divider",
              borderRadius: 1,
              color: "text.secondary",
              cursor: "pointer",
              opacity: uploadingFiles ? 0.6 : 1,
              transition: "border-color .2s, background-color .2s",
              "&:hover": {
                borderColor: "primary.main",
                bgcolor: "action.hover",
              },
            }}
          >
            {uploadingFiles ? (
              <>
                <CircularProgress size={28} />
                <Typography variant="body2">Nahrávání...</Typography>
              </>
            ) : (
              <>
                {UploadIcon}
                <Typography variant="body2">
                  Přetáhněte soubory sem nebo klikněte pro výběr
                </Typography>
                <Typography variant="caption" color="text.secondary">
                  Dodací listy, faktury a další dokumenty
                </Typography>
              </>
            )}
          </Box>
        </Card>
      )}
    </PageEnter>
  );
}
