import { useEffect, useMemo, useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { DndContext, PointerSensor, useSensor, useSensors } from '@dnd-kit/core';
import { apiClient } from '../lib/apiClient';
import { useTasks } from '../hooks/useTasks';
import { useBoardReferenceDate } from '../hooks/useBoardReferenceDate';
import { DashboardHeader } from '../components/dashboard/DashboardHeader';
import { DummyDepartmentColumn } from '../components/dummy/DummyDepartmentColumn';
import { HubColumn } from '../components/dashboard/HubColumn';
import { BoardConnectors } from '../components/dashboard/BoardConnectors';
import { isProjectTask, isRoutineTask } from '../lib/taskType';
import { hasVisibleIssue } from '../lib/taskIssues';
import {
  DEFAULT_STATUS_FILTERS,
  taskMatchesStatusFilters,
  toggleAllFilter,
  toggleCoreFilter,
  type CoreStatusFilter,
} from '../lib/statusFilters';
import { LEGACY_COLUMN_KEYS, SECTIONS } from '../lib/sections';
import {
  BOARD_SLOT_ORDER,
  BOARD_SLOTS,
  getBoardSlot,
  slotSectionLabel,
  taskBelongsToBoardSlot,
} from '../lib/boardLayout';
import '../styles/dummy-board.css';

function mergeCardOrders(primary: string | null | undefined, extras: (string | null | undefined)[]): string[] {
  const merged: string[] = [];
  const push = (raw: string | null | undefined) => {
    if (!raw) return;
    try {
      const ids = JSON.parse(raw) as string[];
      for (const id of ids) {
        if (!merged.includes(id)) merged.push(id);
      }
    } catch {
      /* ignore */
    }
  };
  push(primary);
  extras.forEach(push);
  return merged;
}

export default function DummyDashboardPage() {
  const [activeFilters, setActiveFilters] = useState<string[]>([...DEFAULT_STATUS_FILTERS]);
  const [filtersBeforeIssue, setFiltersBeforeIssue] = useState<string[]>([...DEFAULT_STATUS_FILTERS]);
  const [issueFilterActive, setIssueFilterActive] = useState(false);
  const [teamPanelOpen, setTeamPanelOpen] = useState(false);
  const [columnOrders, setColumnOrders] = useState<Record<string, string[]>>({});
  const {
    referenceDate,
    referenceWeekMonday,
    quarter,
    weekLensActive,
    selectWeek,
    selectQuarter,
    returnToCurrentQuarter,
  } = useBoardReferenceDate();

  const issueVisibility = useMemo(
    () => (weekLensActive ? { weekMonday: referenceWeekMonday } : undefined),
    [weekLensActive, referenceWeekMonday],
  );

  const { data: tasks = [], isLoading } = useTasks({ quarter });

  const { data: colConfigs } = useQuery({
    queryKey: ['columns', 'all', ...SECTIONS],
    queryFn: async () => {
      const results = await Promise.all(
        SECTIONS.map(async (s) => {
          const main = await apiClient.get(`/columns/${encodeURIComponent(s)}`).then((r) => r.data);
          const legacy = await Promise.all(
            LEGACY_COLUMN_KEYS[s].map((key) =>
              apiClient.get(`/columns/${encodeURIComponent(key)}`).then((r) => r.data).catch(() => null),
            ),
          );
          const cardOrder = JSON.stringify(
            mergeCardOrders(main.cardOrder, legacy.map((l) => l?.cardOrder)),
          );
          return { key: s, ...main, cardOrder };
        }),
      );
      return results;
    },
    staleTime: 0,
  });

  useEffect(() => {
    if (!colConfigs) return;
    setColumnOrders((prev) => {
      const next = { ...prev };
      BOARD_SLOTS.forEach((slot) => {
        const label = slotSectionLabel(slot);
        if (next[label]) return;
        if (!slot.sectionKey) return;
        const cfg = colConfigs.find((c) => c.key === slot.sectionKey);
        if (cfg?.cardOrder) {
          try {
            next[label] = JSON.parse(cfg.cardOrder);
          } catch {
            /* ignore */
          }
        }
      });
      return next;
    });
  }, [colConfigs]);

  useEffect(() => {
    BOARD_SLOTS.forEach((slot) => {
      const label = slotSectionLabel(slot);
      const ids = tasks.filter((t) => taskBelongsToBoardSlot(t, slot)).map((t) => t.id);
      setColumnOrders((prev) => {
        const existing = prev[label] ?? [];
        const merged = [
          ...existing.filter((id) => ids.includes(id)),
          ...ids.filter((id) => !existing.includes(id)),
        ];
        if (JSON.stringify(merged) === JSON.stringify(existing)) return prev;
        return { ...prev, [label]: merged };
      });
    });
  }, [tasks]);

  const filtered = tasks.filter((t) => {
    if (issueFilterActive) return hasVisibleIssue(t, issueVisibility);
    return taskMatchesStatusFilters(t, activeFilters);
  });

  const boardProjectTasks = useMemo(
    () =>
      filtered.filter(
        (t) =>
          isProjectTask(t.taskType) &&
          BOARD_SLOTS.some((slot) => taskBelongsToBoardSlot(t, slot)),
      ),
    [filtered],
  );

  const stats = useMemo(
    () => ({
      total: boardProjectTasks.length,
      inProgress: boardProjectTasks.filter((t) => t.status === 'IN_PROGRESS').length,
      review: boardProjectTasks.filter(
        (t) => t.status === 'REVIEW' || t.status === 'CANCELLED' || t.status === 'TODO',
      ).length,
      done: boardProjectTasks.filter((t) => t.status === 'DONE').length,
      issues: boardProjectTasks.filter((t) => hasVisibleIssue(t, issueVisibility)).length,
    }),
    [boardProjectTasks, issueVisibility],
  );

  const routineTasks = useMemo(
    () => filtered.filter((t) => isRoutineTask(t.taskType)),
    [filtered],
  );

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 9999 } }),
  );

  const renderDeptSlot = (slotId: typeof BOARD_SLOT_ORDER[number]) => {
    const slot = getBoardSlot(slotId);
    const label = slotSectionLabel(slot);
    return (
      <DummyDepartmentColumn
        key={slot.id}
        slot={slot}
        tasks={filtered.filter((t) => taskBelongsToBoardSlot(t, slot))}
        orderedIds={columnOrders[label] ?? []}
      />
    );
  };

  if (isLoading) {
    return (
      <div className="flex h-screen items-center justify-center bg-[#e9eef2]">
        <div className="text-lg text-gray-400">데이터를 불러오는 중...</div>
      </div>
    );
  }

  return (
    <div className="app-shell dummy-board-page dummy-board-page--2slots">
      <div className="app-main relative flex h-screen min-w-0 flex-col overflow-hidden bg-[#e9eef2]">
        <DashboardHeader
          quarter={quarter}
          referenceWeekMonday={referenceWeekMonday}
          weekLensActive={weekLensActive}
          onSelectWeek={selectWeek}
          onSelectQuarter={selectQuarter}
          onReturnToCurrentQuarter={returnToCurrentQuarter}
          stats={stats}
          activeFilters={activeFilters}
          issueFilterActive={issueFilterActive}
          onToggleAll={() => {
            setIssueFilterActive(false);
            setActiveFilters((prev) => toggleAllFilter(prev));
          }}
          onToggleStatus={(key: CoreStatusFilter) => {
            setIssueFilterActive(false);
            setActiveFilters((prev) => toggleCoreFilter(prev, key));
          }}
          onToggleIssue={() => {
            if (issueFilterActive) {
              setIssueFilterActive(false);
              setActiveFilters([...filtersBeforeIssue]);
              return;
            }
            setFiltersBeforeIssue([...activeFilters]);
            setIssueFilterActive(true);
          }}
          onOpenDetailWindow={() => {}}
          onOpenTaskManager={() => {}}
          teamPanelOpen={teamPanelOpen}
          onToggleTeamPanel={() => setTeamPanelOpen((v) => !v)}
        />

        <main className="board-main dummy-board-main dummy-board-main--preview">
          <div className="page-content">
            <DndContext sensors={sensors}>
              <div className="board-layout">
                {renderDeptSlot('hrm')}
                {renderDeptSlot('hrd')}
                <HubColumn routineTasks={routineTasks} quarter={quarter} referenceDate={referenceDate} />
                {renderDeptSlot('ex')}
                {renderDeptSlot('ga')}
                <BoardConnectors style="reference" />
              </div>
            </DndContext>
          </div>
        </main>
      </div>
    </div>
  );
}
