import { useState, useEffect, useRef } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useApiMutation } from "../lib/queries/mutations";
import apiFetch from "../utils/api";
import { useAlert } from "../context/AlertContext";
import { useAuth } from "../context/AuthContext";
import { useParams, useNavigate, Link as RouterLink } from "react-router-dom";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import MenuItem from "@mui/material/MenuItem";

import {
  projectDetailOptions,
  type ProjectNote,
} from "../lib/queries/projects";
import { userListOptions, type User as ApiUser } from "../lib/queries/users";
import Forbidden from "../components/Forbidden";
import ProjectFileManager from "../components/ProjectFileManager";
import NoteCard from "../components/NoteCard";
import {
  Button,
  Card,
  Field,
  TextField,
  Select,
  DateField,
  StatusChip,
  CheckboxField,
  ConfirmDialog,
  LoadingState,
  PageEnter,
  headerActionsSx,
} from "../ui";
import {
  PROJECT_STATUS,
  ORDER_STATUS,
  statusLabel,
  statusColor,
} from "../lib/documentStatus";

const API_BASE = "/api/admin";

const TRANSITION_LABELS: Record<string, string> = {
  dokonceny: "Dokončit projekt",
  zruseny: "Zrušit projekt",
  aktivni: "Obnovit projekt",
};

interface User {
  id: number;
  name: string;
}

interface ProjectForm {
  name: string;
  start_date: string;
  end_date: string;
  responsible_user_id: string;
}

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>
);

export default function ProjectDetail() {
  const { id } = useParams();
  const alert = useAlert();
  const { hasPermission, isAdmin, user } = useAuth();
  const navigate = useNavigate();
  const qc = useQueryClient();

  const [saving, setSaving] = useState(false);
  const [form, setForm] = useState<ProjectForm>({
    name: "",
    start_date: "",
    end_date: "",
    responsible_user_id: "",
  });
  const [statusChanging, setStatusChanging] = useState<string | null>(null);
  const [statusConfirm, setStatusConfirm] = useState<{
    show: boolean;
    status: string | null;
  }>({ show: false, status: null });

  const [deleteConfirm, setDeleteConfirm] = useState(false);
  const [deleting, setDeleting] = useState(false);
  const [deleteFiles, setDeleteFiles] = useState(false);

  // Dynamic notes
  const [newNote, setNewNote] = useState("");
  const [addingNote, setAddingNote] = useState(false);
  const [deletingNoteId, setDeletingNoteId] = useState<number | null>(null);

  const projectQuery = useQuery(projectDetailOptions(id));
  const project = projectQuery.data;
  const isPending = projectQuery.isPending;
  const notes: ProjectNote[] = project?.project_notes || [];

  const { data: usersData } = useQuery(userListOptions("projects.view"));
  // Only active users with projects.view — but keep the project's CURRENT
  // assignee in the list even if they're now inactive, so the select still
  // reflects the saved value (marked "(neaktivní)" so it's clear).
  const assignedUserId = project?.responsible_user_id || "";
  const users: User[] = (usersData ?? [])
    .filter((u: ApiUser) => u.is_active || String(u.id) === assignedUserId)
    .map((u: ApiUser) => ({
      id: u.id,
      name:
        (`${u.first_name || ""} ${u.last_name || ""}`.trim() || u.username) +
        (u.is_active ? "" : " (neaktivní)"),
    }));

  // Reset form sync when navigating to a different project
  const formInitialized = useRef(false);
  useEffect(() => {
    formInitialized.current = false;
  }, [id]);

  // Sync project data to local form state on first load
  useEffect(() => {
    if (project && !formInitialized.current) {
      setForm({
        name: project.name || "",
        start_date: (project.start_date || "").substring(0, 10),
        end_date: (project.end_date || "").substring(0, 10),
        responsible_user_id: project.responsible_user_id || "",
      });
      formInitialized.current = true;
    }
  }, [project]);

  // Navigate away on fetch error
  useEffect(() => {
    if (projectQuery.error) {
      alert.error("Nepodařilo se načíst projekt");
      navigate("/projects");
    }
  }, [projectQuery.error]); // eslint-disable-line react-hooks/exhaustive-deps

  const projectSaveMutation = useApiMutation<
    {
      name: string;
      start_date: string | null;
      end_date: string | null;
      responsible_user_id: string | null;
    },
    unknown
  >({
    url: () => `${API_BASE}/projects/${id}`,
    method: () => "PUT",
    invalidate: ["projects", "warehouse"],
  });

  // Status transitions (header buttons). A project transition may cascade to
  // the linked order (and its documents), so invalidate broadly.
  const statusMutation = useApiMutation<{ status: string }, unknown>({
    url: () => `${API_BASE}/projects/${id}`,
    method: () => "PUT",
    invalidate: ["projects", "orders", "offers", "invoices", "warehouse"],
  });

  const projectDeleteMutation = useApiMutation<
    { delete_files: boolean },
    unknown
  >({
    url: () => `${API_BASE}/projects/${id}`,
    method: () => "DELETE",
    invalidate: ["projects", "warehouse"],
  });

  const projectAddNoteMutation = useApiMutation<{ content: string }, unknown>({
    url: () => `${API_BASE}/projects/${id}/notes`,
    method: () => "POST",
    invalidate: ["projects", "warehouse"],
  });

  const projectDeleteNoteMutation = useApiMutation<number, unknown>({
    url: (noteId) => `${API_BASE}/projects/${id}/notes/${noteId}`,
    method: () => "DELETE",
    invalidate: ["projects", "warehouse"],
  });

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

  const updateForm = (field: keyof ProjectForm, value: string) =>
    setForm((prev) => ({ ...prev, [field]: value }));

  const handleSave = async () => {
    if (!form.name.trim()) {
      alert.error("Název projektu je povinný");
      return;
    }

    setSaving(true);
    try {
      await projectSaveMutation.mutateAsync({
        name: form.name,
        start_date: form.start_date || null,
        end_date: form.end_date || null,
        responsible_user_id: form.responsible_user_id || null,
      });
      alert.success("Projekt byl aktualizován");
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    } finally {
      setSaving(false);
    }
  };

  const handleStatusChange = async () => {
    if (!statusConfirm.status) return;
    const newStatus = statusConfirm.status;
    setStatusChanging(newStatus);
    setStatusConfirm({ show: false, status: null });
    try {
      await statusMutation.mutateAsync({ status: newStatus });
      alert.success("Stav byl změněn");
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    } finally {
      setStatusChanging(null);
    }
  };

  // Confirm message with the cascade note — the linked-order cascade only
  // exists when the project actually has a linked order; reopening never
  // cascades.
  const statusConfirmMessage = (status: string | null): string => {
    if (!status || !project) return "";
    if (status === "aktivni") {
      return (
        'Projekt se vrátí do stavu "Aktivní".' +
        (project.order_id ? " Propojená objednávka zůstane beze změny." : "")
      );
    }
    const base = `Označit projekt "${project.project_number} – ${project.name}" jako ${
      status === "zruseny" ? "zrušený" : "dokončený"
    }?`;
    // The cascade only fires while the order is still open (prijata /
    // v_realizaci) — a terminal order (e.g. after a project reopen) stays
    // untouched, so don't promise a change that won't happen.
    const orderCascades =
      project.order_id &&
      (project.order_status === "prijata" ||
        project.order_status === "v_realizaci");
    if (!orderCascades) return base;
    return (
      base +
      (status === "zruseny"
        ? " Propojená objednávka bude automaticky stornována."
        : " Propojená objednávka bude automaticky dokončena.")
    );
  };

  const handleDelete = async () => {
    setDeleting(true);
    try {
      await projectDeleteMutation.mutateAsync({ delete_files: deleteFiles });
      navigate("/projects");
      setTimeout(() => alert.success("Projekt byl smazán"), 300);
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    } finally {
      setDeleting(false);
    }
  };

  const handleAddNote = async () => {
    if (!newNote.trim()) return;

    setAddingNote(true);
    try {
      await projectAddNoteMutation.mutateAsync({ content: newNote.trim() });
      setNewNote("");
      alert.success("Poznámka byla přidána");
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    } finally {
      setAddingNote(false);
    }
  };

  const handleDeleteNote = async (noteId: number) => {
    setDeletingNoteId(noteId);
    try {
      await projectDeleteNoteMutation.mutateAsync(noteId);
      alert.success("Poznámka byla smazána");
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    } finally {
      setDeletingNoteId(null);
    }
  };

  // Throws on failure so NoteCard keeps its editor open with the draft.
  const saveNoteEdit = async (noteId: number, content: string) => {
    // Raw apiFetch: the body must carry ONLY content (strict schema), the
    // note id lives in the URL — useApiMutation sends its whole input.
    let res: Response;
    try {
      res = await apiFetch(`${API_BASE}/projects/${id}/notes/${noteId}`, {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ content }),
      });
    } catch {
      alert.error("Chyba připojení");
      throw new Error("network");
    }
    const body = await res.json().catch(() => null);
    if (!res.ok) {
      alert.error(body?.error || "Uložení selhalo");
      throw new Error(body?.error || "Uložení selhalo");
    }
    qc.invalidateQueries({ queryKey: ["projects"] });
    alert.success("Poznámka upravena");
  };

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

  if (!project) return null;

  const canEdit = hasPermission("projects.edit");

  return (
    <PageEnter>
      {/* Header */}
      <Box>
        <Box
          sx={{
            display: "flex",
            alignItems: "flex-start",
            justifyContent: "space-between",
            flexWrap: "wrap",
            gap: 2,
            mb: 3,
          }}
        >
          {/* flexWrap: the title must drop below the Zpět button on phones
              instead of being squeezed beside it (mirrors Offer/Invoice
              detail headers). */}
          <Box
            sx={{
              display: "flex",
              alignItems: "center",
              gap: 2,
              flexWrap: "wrap",
            }}
          >
            <Button
              component={RouterLink}
              to="/projects"
              variant="outlined"
              color="inherit"
              startIcon={BackIcon}
            >
              Zpět
            </Button>
            <Box
              sx={{
                display: "flex",
                alignItems: "center",
                gap: 1.5,
                flexWrap: "wrap",
              }}
            >
              <Typography variant="h4">
                Projekt
                <Box
                  component="span"
                  sx={{ color: "text.secondary", ml: 1, fontWeight: 400 }}
                >
                  {project.project_number}
                </Box>
              </Typography>
              <StatusChip
                label={statusLabel(PROJECT_STATUS, project.status)}
                color={statusColor(PROJECT_STATUS, project.status)}
              />
            </Box>
          </Box>
          {canEdit && (
            <Box sx={headerActionsSx}>
              <Button
                onClick={handleSave}
                disabled={saving || statusChanging !== null}
              >
                {saving ? "Ukládání..." : "Uložit"}
              </Button>
              {(project.valid_transitions ?? []).map((status) => (
                <Button
                  key={status}
                  color={status === "zruseny" ? "error" : "primary"}
                  onClick={() => setStatusConfirm({ show: true, status })}
                  disabled={saving || statusChanging !== null}
                >
                  {statusChanging === status
                    ? "Zpracovávám…"
                    : TRANSITION_LABELS[status] || status}
                </Button>
              ))}
              {!project.order_id && (
                <Button
                  variant="outlined"
                  color="error"
                  onClick={() => setDeleteConfirm(true)}
                >
                  Smazat
                </Button>
              )}
            </Box>
          )}
        </Box>
      </Box>

      {/* Basic info form */}
      <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,
          }}
        >
          <Field label="Číslo projektu">
            <TextField value={project.project_number} fullWidth disabled />
          </Field>
          <Field label="Název">
            <TextField
              value={form.name}
              onChange={(e) => updateForm("name", e.target.value)}
              placeholder="Název projektu"
              fullWidth
              disabled={!canEdit}
            />
          </Field>
          <Field label="Zákazník">
            <TextField
              value={project.customer_name || "—"}
              fullWidth
              disabled
            />
          </Field>
          <Field label="Zodpovědná osoba">
            <Select
              value={form.responsible_user_id}
              onChange={(v) => updateForm("responsible_user_id", v)}
              disabled={!canEdit}
            >
              <MenuItem value="">— Nevybráno —</MenuItem>
              {users.map((u) => (
                <MenuItem key={u.id} value={String(u.id)}>
                  {u.name}
                </MenuItem>
              ))}
            </Select>
          </Field>
        </Box>
        <Box
          sx={{
            display: "grid",
            gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" },
            gap: 2,
          }}
        >
          <Field label="Datum zahájení">
            <DateField
              value={form.start_date}
              onChange={(val) => updateForm("start_date", val)}
              disabled={!canEdit}
            />
          </Field>
          <Field label="Datum ukončení">
            <DateField
              value={form.end_date}
              onChange={(val) => updateForm("end_date", val)}
              disabled={!canEdit}
            />
          </Field>
        </Box>
      </Card>

      {/* Notes */}
      <Card sx={{ mb: 3 }}>
        <Typography variant="subtitle2" sx={{ mb: 2, fontWeight: 600 }}>
          Poznámky
        </Typography>

        {/* Add note */}
        <Box sx={{ mb: 3 }}>
          <TextField
            value={newNote}
            onChange={(e) => setNewNote(e.target.value)}
            multiline
            minRows={2}
            placeholder="Napište poznámku..."
            fullWidth
            onKeyDown={(e) => {
              if (e.key === "Enter" && e.ctrlKey && newNote.trim()) {
                handleAddNote();
              }
            }}
          />
          <Box sx={{ mt: 1 }}>
            <Button
              variant="outlined"
              color="inherit"
              onClick={handleAddNote}
              disabled={addingNote || !newNote.trim()}
            >
              {addingNote ? "Přidávání..." : "Přidat poznámku"}
            </Button>
          </Box>
        </Box>

        {/* Legacy notes (read-only) */}
        {project.notes && (
          <Box
            sx={{
              p: 1.5,
              bgcolor: "action.hover",
              borderRadius: 2,
              mb: 1,
            }}
          >
            <Typography
              variant="caption"
              color="text.secondary"
              sx={{ display: "block", mb: 0.5 }}
            >
              Starší poznámka (před zavedením systému)
            </Typography>
            <Typography
              variant="body2"
              color="text.secondary"
              sx={{ whiteSpace: "pre-wrap" }}
            >
              {project.notes}
            </Typography>
          </Box>
        )}

        {/* Notes list */}
        {notes.length === 0 && !project.notes && (
          <Typography
            variant="body2"
            color="text.secondary"
            sx={{ textAlign: "center", py: 2 }}
          >
            Zatím žádné poznámky
          </Typography>
        )}
        {(notes.length > 0 || project.notes) && (
          <Box sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
            {notes.map((note) => (
              <NoteCard
                key={note.id}
                authorName={note.user_name}
                createdAt={note.created_at}
                editedAt={note.edited_at}
                content={note.content || ""}
                canEdit={user?.id === note.user_id}
                canDelete={isAdmin}
                deleting={deletingNoteId === note.id}
                onSave={(content) => saveNoteEdit(note.id, content)}
                onDelete={() => handleDeleteNote(note.id)}
              />
            ))}
          </Box>
        )}
      </Card>

      {/* Project File Manager */}
      <Box sx={{ mb: 2 }}>
        <ProjectFileManager
          projectId={project.id}
          projectNumber={project.project_number}
          hasPermission={hasPermission}
          hasNasFolder={project.has_nas_folder ?? false}
        />
      </Box>

      {/* Links */}
      <Card sx={{ mb: 3 }}>
        <Typography variant="subtitle2" sx={{ mb: 2, fontWeight: 600 }}>
          Propojení
        </Typography>
        <Box
          sx={{
            display: "grid",
            gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" },
            gap: 2,
          }}
        >
          <Box>
            <Typography variant="caption" color="text.secondary">
              Objednávka
            </Typography>
            <Typography
              variant="body2"
              component="div"
              sx={{
                display: "flex",
                alignItems: "center",
                gap: 1,
                flexWrap: "wrap",
              }}
            >
              {project.order_id ? (
                <>
                  <Box
                    component={RouterLink}
                    to={`/orders/${project.order_id}`}
                    sx={{
                      color: "primary.main",
                      textDecoration: "none",
                      "&:hover": { textDecoration: "underline" },
                    }}
                  >
                    {project.order_number}
                  </Box>
                  {project.order_status && (
                    <StatusChip
                      label={statusLabel(ORDER_STATUS, project.order_status)}
                      color={statusColor(ORDER_STATUS, project.order_status)}
                    />
                  )}
                </>
              ) : (
                "—"
              )}
            </Typography>
          </Box>
          <Box>
            <Typography variant="caption" color="text.secondary">
              Nabídka
            </Typography>
            <Typography variant="body2">
              {project.quotation_id ? (
                <Box
                  component={RouterLink}
                  to={`/offers/${project.quotation_id}`}
                  sx={{
                    color: "primary.main",
                    textDecoration: "none",
                    "&:hover": { textDecoration: "underline" },
                  }}
                >
                  {project.quotation_number}
                </Box>
              ) : (
                "—"
              )}
            </Typography>
          </Box>
        </Box>
      </Card>

      {/* Status change confirmation */}
      <ConfirmDialog
        isOpen={statusConfirm.show}
        onClose={() => setStatusConfirm({ show: false, status: null })}
        onConfirm={handleStatusChange}
        title="Změnit stav projektu"
        message={statusConfirmMessage(statusConfirm.status)}
        confirmText={
          TRANSITION_LABELS[statusConfirm.status || ""] || "Potvrdit"
        }
        confirmVariant={
          statusConfirm.status === "zruseny" ? "danger" : "primary"
        }
        cancelText="Zrušit"
      />

      <ConfirmDialog
        isOpen={deleteConfirm}
        onClose={() => {
          setDeleteConfirm(false);
          setDeleteFiles(false);
        }}
        onConfirm={handleDelete}
        title="Smazat projekt"
        message={`Opravdu chcete smazat projekt „${project.project_number} – ${project.name}"? Tato akce je nevratná.`}
        confirmText="Smazat"
        confirmVariant="danger"
        loading={deleting}
      >
        {project.has_nas_folder && (
          <CheckboxField
            label="Smazat i soubory na disku"
            checked={deleteFiles}
            onChange={setDeleteFiles}
          />
        )}
      </ConfirmDialog>
    </PageEnter>
  );
}
