/* global React, ReactDOM,
   Sidebar, Topbar, BoardHeader, TaskCard, KanbanColumn, TaskModal, CommandMenu,
   INITIAL_BOARDS, INITIAL_COLUMNS, INITIAL_CARDS */
const { useState, useEffect, useRef, useMemo, useCallback } = React;

const THEME_KEY = "tarefas:theme";

function App() {
  const [theme, setTheme] = useState(() => {
    try {
      const stored = localStorage.getItem(THEME_KEY);
      if (stored === "light" || stored === "dark") return stored;
    } catch (e) {}
    return "light";
  });

  const [boards] = useState(INITIAL_BOARDS);
  const [columns, setColumns] = useState(INITIAL_COLUMNS);
  const [cards, setCards] = useState(INITIAL_CARDS);
  const [activeBoardId, setActiveBoardId] = useState("product");
  const [openCardId, setOpenCardId] = useState(null);
  const [cmdkOpen, setCmdkOpen] = useState(false);
  const [sidebarOpen, setSidebarOpen] = useState(false); // mobile
  const [sidebarCollapsed, setSidebarCollapsed] = useState(false); // desktop
  const [draggingId, setDraggingId] = useState(null);
  const [dragOverCol, setDragOverCol] = useState(null);
  const [dragOverIndex, setDragOverIndex] = useState(null);
  const [freshCardId, setFreshCardId] = useState(null);

  const activeBoard = boards[activeBoardId];

  // Apply theme on root + persist
  useEffect(() => {
    document.documentElement.setAttribute("data-theme", theme);
    try { localStorage.setItem(THEME_KEY, theme); } catch (e) {}
  }, [theme]);

  const toggleTheme = useCallback(() => {
    setTheme((t) => (t === "light" ? "dark" : "light"));
  }, []);

  // Keyboard shortcuts
  useEffect(() => {
    const onKey = (e) => {
      const mod = e.metaKey || e.ctrlKey;
      if (mod && e.key.toLowerCase() === "k") { e.preventDefault(); setCmdkOpen(true); }
      if (mod && e.key.toLowerCase() === "d") {
        e.preventDefault();
        toggleTheme();
      }
      if (e.key === "Escape" && !cmdkOpen && !openCardId) {
        setSidebarOpen(false);
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [cmdkOpen, openCardId, toggleTheme]);

  const handleDragStart = (e, cardId) => {
    setDraggingId(cardId);
    e.dataTransfer.effectAllowed = "move";
    try { e.dataTransfer.setData("text/plain", cardId); } catch (err) {}
    const ghost = e.currentTarget.cloneNode(true);
    ghost.style.position = "absolute";
    ghost.style.top = "-1000px";
    ghost.style.width = e.currentTarget.offsetWidth + "px";
    ghost.style.transform = "rotate(1.5deg)";
    ghost.style.boxShadow = "0 18px 42px -10px rgba(0,0,0,0.25)";
    document.body.appendChild(ghost);
    e.dataTransfer.setDragImage(ghost, 20, 20);
    setTimeout(() => ghost.remove(), 0);
  };

  const handleDragOver = (colId, idx) => {
    setDragOverCol((prev) => (prev !== colId ? colId : prev));
    setDragOverIndex((prev) => (prev !== idx ? idx : prev));
  };
  const handleDragLeave = () => {};
  const handleDrop = (colId, dropIdx) => {
    if (!draggingId) {
      setDragOverCol(null);
      setDragOverIndex(null);
      return;
    }
    setColumns((prev) => {
      let sourceColId = null;
      for (const k of Object.keys(prev)) {
        if (prev[k].cards.includes(draggingId)) {
          sourceColId = k;
          break;
        }
      }
      if (!sourceColId) return prev;

      const targetCards = prev[colId].cards;
      const insertAt = dropIdx == null ? targetCards.length : Math.max(0, Math.min(dropIdx, targetCards.length));

      if (sourceColId === colId) {
        const sourceIdx = targetCards.indexOf(draggingId);
        if (insertAt === sourceIdx || insertAt === sourceIdx + 1) return prev;
        const filtered = targetCards.filter((id) => id !== draggingId);
        const adjusted = insertAt > sourceIdx ? insertAt - 1 : insertAt;
        const newCards = [...filtered.slice(0, adjusted), draggingId, ...filtered.slice(adjusted)];
        return { ...prev, [colId]: { ...prev[colId], cards: newCards } };
      }

      const fromCards = prev[sourceColId].cards.filter((id) => id !== draggingId);
      const newTo = [...targetCards.slice(0, insertAt), draggingId, ...targetCards.slice(insertAt)];
      return {
        ...prev,
        [sourceColId]: { ...prev[sourceColId], cards: fromCards },
        [colId]: { ...prev[colId], cards: newTo },
      };
    });
    setDraggingId(null);
    setDragOverCol(null);
    setDragOverIndex(null);
  };

  useEffect(() => {
    const stop = () => { setDraggingId(null); setDragOverCol(null); setDragOverIndex(null); };
    window.addEventListener("dragend", stop);
    return () => window.removeEventListener("dragend", stop);
  }, []);

  const handleAddCard = (colId, title) => {
    const id = "n" + Date.now();
    const newCard = {
      id, title, desc: "",
      tags: [], priority: "med", due: null,
      assignees: ["João Pereira"],
      comments: 0, attachments: 0, checklist: null, completed: false,
    };
    setCards((prev) => ({ ...prev, [id]: newCard }));
    setColumns((prev) => ({ ...prev, [colId]: { ...prev[colId], cards: [...prev[colId].cards, id] } }));
    setFreshCardId(id);
    setTimeout(() => setFreshCardId(null), 400);
  };

  const handleUpdateCard = (id, patch) => {
    setCards((prev) => ({ ...prev, [id]: { ...prev[id], ...patch } }));
  };

  const totalCards = activeBoard.columns.reduce((acc, cid) => acc + (columns[cid]?.cards.length || 0), 0);
  const doneCards = activeBoard.columns.reduce((acc, cid) => {
    return acc + (columns[cid]?.cards.filter(cardId => cards[cardId]?.completed).length || 0);
  }, 0);

  const openCard = openCardId ? cards[openCardId] : null;
  const openCardCol = openCardId ? Object.values(columns).find(c => c.cards.includes(openCardId)) : null;

  const showSidebarOpen = sidebarOpen;
  const sidebarMode = window.matchMedia("(max-width: 900px)").matches
    ? (showSidebarOpen ? "open" : "closed")
    : (sidebarCollapsed ? "collapsed" : "expanded");

  const handleToggleSidebar = () => {
    if (window.matchMedia("(max-width: 900px)").matches) setSidebarOpen(o => !o);
    else setSidebarCollapsed(c => !c);
  };

  return (
    <div className="app" data-sidebar={sidebarMode}>
      <div className="scrim-mobile" onClick={() => setSidebarOpen(false)} />
      <Sidebar
        boards={boards}
        activeBoard={activeBoardId}
        onSelectBoard={setActiveBoardId}
        onClose={() => setSidebarOpen(false)}
      />
      <main className="main">
        <Topbar
          boardName={activeBoard.name}
          onToggleSidebar={handleToggleSidebar}
          onOpenCmdK={() => setCmdkOpen(true)}
          onNew={() => handleAddCard(activeBoard.columns[0], "Nova tarefa")}
          sidebarCollapsed={sidebarCollapsed}
        />
        <BoardHeader
          board={activeBoard}
          totalCards={totalCards}
          doneCards={doneCards}
          onFilter={() => setCmdkOpen(true)}
        />
        <section className="board" data-board-id={activeBoard.id}>
          {activeBoard.columns.map((colId) => {
            const col = columns[colId];
            if (!col) return null;
            const cardObjs = col.cards.map(id => cards[id]).filter(Boolean);
            return (
              <KanbanColumn
                key={colId}
                column={col}
                cards={cardObjs}
                dragOver={dragOverCol === colId}
                dragOverIndex={dragOverCol === colId ? dragOverIndex : null}
                draggingId={draggingId}
                onDragOver={handleDragOver}
                onDragLeave={handleDragLeave}
                onDrop={handleDrop}
                onCardClick={(id) => setOpenCardId(id)}
                onCardDragStart={handleDragStart}
                onAddCard={handleAddCard}
                freshCardId={freshCardId}
              />
            );
          })}
          {activeBoard.columns.length === 0 && (
            <div style={{
              flex: 1, display: "grid", placeItems: "center",
              color: "var(--text-tertiary)", fontSize: 13.5,
            }}>
              <div style={{ textAlign: "center" }}>
                <div style={{ marginBottom: 8 }}>Este board está vazio.</div>
                <button className="btn">Criar primeira coluna</button>
              </div>
            </div>
          )}
          {activeBoard.columns.length > 0 && (
            <button className="add-column-btn" title="Adicionar coluna">
              <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round"><path d="M12 5v14M5 12h14"/></svg>
            </button>
          )}
        </section>
      </main>

      {openCard && (
        <TaskModal
          card={openCard}
          columnName={openCardCol?.name || ""}
          onClose={() => setOpenCardId(null)}
          onUpdate={(patch) => handleUpdateCard(openCard.id, patch)}
        />
      )}

      {cmdkOpen && (
        <CommandMenu
          onClose={() => setCmdkOpen(false)}
          boards={boards}
          cards={cards}
          onSelectBoard={setActiveBoardId}
          onOpenCard={setOpenCardId}
          onToggleTheme={toggleTheme}
        />
      )}
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
