import { useState, useEffect, useRef, useId } from "react";
import { useParams, useNavigate, useLocation, Link } from "react-router-dom";
import { useQuery } from "@tanstack/react-query";
import { useAlert } from "../context/AlertContext";
import { useAuth } from "../context/AuthContext";
import Forbidden from "../components/Forbidden";
import { motion } from "framer-motion";
import FormField from "../components/FormField";
import WarehouseMovementTable, {
  type MovementItem,
} from "../components/warehouse/WarehouseMovementTable";

import { warehouseIssueDetailOptions } from "../lib/queries/warehouse";
import { projectListOptions, type Project } from "../lib/queries/projects";
import { useApiMutation } from "../lib/queries/mutations";

interface IssueForm {
  project_id: number | null;
  notes: string;
}

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

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

  // Pre-fill data from reservation ("Create výdej" button)
  const prefill = location.state as {
    reservationId?: number;
    itemId?: number;
    projectId?: number;
    quantity?: number;
    itemName?: string;
  } | null;

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

  const [form, setForm] = useState<IssueForm>({
    project_id: prefill?.projectId ?? null,
    notes: "",
  });
  const [items, setItems] = useState<MovementItem[]>(() =>
    isEdit
      ? []
      : prefill?.itemId
        ? [
            {
              key: nextKey(),
              item_id: prefill.itemId,
              item_name: prefill.itemName,
              quantity: prefill.quantity ?? 0,
              unit_price: 0,
              location_id: null,
              batch_id: null,
              reservation_id: prefill.reservationId ?? null,
              notes: null,
            },
          ]
        : [
            {
              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 formInitialized = useRef(false);

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

  const { data: projectsData } = useQuery(projectListOptions({ perPage: 100 }));
  const projects = projectsData?.data ?? [];

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

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

  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 validate = (): boolean => {
    const newErrors: Record<string, string> = {};
    if (!form.project_id) {
      newErrors.project_id = "Projekt je povinný";
    }
    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 = () => ({
    project_id: form.project_id,
    notes: form.notes.trim() || null,
    items: items
      .filter((l) => l.item_id !== null)
      .map((l) => ({
        item_id: l.item_id!,
        batch_id: l.batch_id,
        quantity: l.quantity,
        location_id: l.location_id,
        reservation_id: l.reservation_id,
        notes: l.notes?.trim() || null,
      })),
  });

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

  const [confirmIssueId, setConfirmIssueId] = useState<number | null>(null);
  const confirmMutation = useApiMutation<void, void>({
    url: () =>
      confirmIssueId
        ? `/api/admin/warehouse/issues/${confirmIssueId}/confirm`
        : "/api/admin/warehouse/issues/0/confirm",
    method: () => "POST",
    invalidate: ["warehouse"],
    onSuccess: () => {
      alert.success("Výdejka byla potvrzena");
    },
  });

  const saveIssue = 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 výdejku",
      );
      return null;
    }
  };

  const confirmIssue = async (issueId: number) => {
    setConfirmIssueId(issueId);
    try {
      await confirmMutation.mutateAsync(undefined);
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    } finally {
      setConfirmIssueId(null);
    }
  };

  const handleSaveDraft = async () => {
    if (!validate()) return;
    setSaving(true);
    try {
      const savedId = await saveIssue();
      if (savedId) {
        alert.success("Výdejka byla uložena jako návrh");
        navigate(`/warehouse/issues/${savedId}`);
      }
    } finally {
      setSaving(false);
    }
  };

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

  if (isEdit && isPending) {
    return (
      <div className="admin-loading">
        <div className="admin-spinner" />
      </div>
    );
  }

  return (
    <div>
      {/* Header */}
      <motion.div
        className="admin-page-header"
        initial={{ opacity: 0, y: 12 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.25 }}
      >
        <div style={{ display: "flex", alignItems: "center", gap: "1rem" }}>
          <Link
            to="/warehouse/issues"
            className="admin-btn-icon"
            title="Zpět na seznam"
            aria-label="Zpět na seznam"
          >
            <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>
          </Link>
          <div>
            <h1 className="admin-page-title">
              {isEdit ? "Upravit výdejku" : "Nová výdejka"}
            </h1>
          </div>
        </div>
        <div className="admin-page-actions">
          <button
            type="button"
            onClick={handleSaveDraft}
            className="admin-btn admin-btn-secondary"
            disabled={saving}
          >
            {saving ? "Ukládání..." : "Uložit jako návrh"}
          </button>
          <button
            type="button"
            onClick={handleSaveAndConfirm}
            className="admin-btn admin-btn-primary"
            disabled={saving}
          >
            {saving ? "Ukládání..." : "Uložit a potvrdit"}
          </button>
        </div>
      </motion.div>

      {/* Header fields */}
      <motion.div
        className="admin-card"
        initial={{ opacity: 0, y: 12 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.25, delay: 0.06 }}
      >
        <div className="admin-card-body">
          <h3 className="admin-card-title">Základní údaje</h3>
          <div className="admin-form">
            <FormField label="Projekt">
              <select
                value={form.project_id ?? ""}
                onChange={(e) =>
                  setForm((prev) => ({
                    ...prev,
                    project_id:
                      e.target.value === "" ? null : Number(e.target.value),
                  }))
                }
                className="admin-form-select"
              >
                <option value="">Vyberte projekt...</option>
                {projects.map((p: Project) => (
                  <option key={p.id} value={p.id}>
                    {p.project_number} – {p.name}
                  </option>
                ))}
              </select>
              {errors.project_id && (
                <div className="admin-form-error">{errors.project_id}</div>
              )}
            </FormField>
            <FormField label="Poznámky">
              <textarea
                value={form.notes}
                onChange={(e) =>
                  setForm((prev) => ({ ...prev, notes: e.target.value }))
                }
                className="admin-form-input"
                rows={3}
                placeholder="Volitelné poznámky"
              />
            </FormField>
          </div>
        </div>
      </motion.div>

      {/* Lines */}
      <motion.div
        className="admin-card"
        initial={{ opacity: 0, y: 12 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.25, delay: 0.08 }}
      >
        <div className="admin-card-body">
          <h3 className="admin-card-title">Položky</h3>
          {errors.items && (
            <div
              className="admin-form-error"
              style={{ marginBottom: "0.75rem" }}
            >
              {errors.items}
            </div>
          )}
          <WarehouseMovementTable
            items={items}
            onChange={setItems}
            mode="issue"
          />
        </div>
      </motion.div>
    </div>
  );
}
