import { createPortal } from 'react-dom';
import { useMemo, useState } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import type { Task } from '../../types';
import { apiClient, getApiErrorMessage } from '../../lib/apiClient';
import { useHubConfig, type HubConfig, type HubScheduleItem } from '../../lib/hubConfig';
import { useRoutineCategoryMilestones } from '../../hooks/useRoutineCategoryMilestones';
import { quarterDateBounds, sortScheduleItems, todayIso } from '../../lib/hubSchedule';
import { HubScheduleCarousel } from './HubScheduleCarousel';
import { HubRoutineFocusPanel } from './HubRoutineFocusPanel';
import { ContextMenu } from '../common/ContextMenu';
import { invalidateTaskCaches } from '../../lib/taskQueryCache';
import { routineCategoryShellPayload } from '../../lib/taskFormPayload';

import {
  ROUTINE_CATEGORIES,
  pickRoutineCategoryTask,
  type RoutineCategory,
} from '../../lib/routineCategories';

type HubEditSection = 'schedule';

function ModalShell({
  title,
  onClose,
  children,
  onSubmit,
}: {
  title: string;
  onClose: () => void;
  children: React.ReactNode;
  onSubmit: (e: React.FormEvent) => void;
}) {
  return createPortal(
    <div className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/50" onClick={onClose}>
      <div
        className="bg-white rounded-2xl shadow-2xl w-[min(480px,92vw)] max-h-[90vh] overflow-y-auto p-6"
        onClick={(e) => e.stopPropagation()}
      >
        <div className="flex items-center justify-between mb-5">
          <h2 className="text-xl font-black text-gray-800">{title}</h2>
          <button type="button" onClick={onClose} className="text-gray-400 hover:text-gray-600 text-2xl leading-none">✕</button>
        </div>
        <form onSubmit={onSubmit} className="space-y-4">
          {children}
          <div className="flex justify-end gap-2 pt-1">
            <button type="button" onClick={onClose} className="px-5 py-2.5 rounded-xl border border-gray-200 text-gray-600 font-semibold hover:bg-gray-50">
              취소
            </button>
            <button type="submit" className="px-6 py-2.5 rounded-xl bg-emerald-700 text-white font-bold hover:bg-emerald-800">
              저장
            </button>
          </div>
        </form>
      </div>
    </div>,
    document.body,
  );
}

function ScheduleEditModal({
  config,
  quarter,
  onSave,
  onClose,
}: {
  config: HubConfig;
  quarter: string;
  onSave: (patch: Pick<HubConfig, 'scheduleTitle' | 'scheduleItems'>) => void;
  onClose: () => void;
}) {
  const { min, max } = quarterDateBounds(quarter);
  const [title, setTitle] = useState(config.scheduleTitle);
  const [items, setItems] = useState<HubScheduleItem[]>(() => structuredClone(config.scheduleItems));

  const updateItem = (id: string, patch: Partial<HubScheduleItem>) => {
    setItems((prev) => prev.map((item) => (item.id === id ? { ...item, ...patch } : item)));
  };

  const addItem = () => {
    setItems((prev) => [...prev, { id: String(Date.now()), date: todayIso(), text: '' }]);
  };

  const removeItem = (id: string) => {
    setItems((prev) => (prev.length <= 1 ? prev : prev.filter((item) => item.id !== id)));
  };

  return (
    <ModalShell
      title="분기 주요 일정 수정"
      onClose={onClose}
      onSubmit={(e) => {
        e.preventDefault();
        const valid = items.filter((item) => item.date && item.text.trim());
        onSave({
          scheduleTitle: title.trim() || '분기 주요 일정',
          scheduleItems: sortScheduleItems(valid),
        });
        onClose();
      }}
    >
      <div>
        <label className="block text-sm font-bold text-gray-500 mb-1.5">제목</label>
        <input
          value={title}
          onChange={(e) => setTitle(e.target.value)}
          className="w-full border border-gray-200 rounded-xl px-4 py-2.5 outline-none focus:border-emerald-400"
        />
      </div>
      <div className="space-y-2">
        <label className="block text-sm font-bold text-gray-500">일정 항목 (날짜 · 내용)</label>
        {items.map((item) => (
          <div key={item.id} className="flex gap-2 items-center">
            <input
              type="date"
              value={item.date}
              min={min}
              max={max}
              onChange={(e) => updateItem(item.id, { date: e.target.value })}
              className="shrink-0 w-[140px] border border-gray-200 rounded-lg px-2 py-2 text-sm"
              required
            />
            <input
              value={item.text}
              onChange={(e) => updateItem(item.id, { text: e.target.value })}
              className="flex-1 min-w-0 border border-gray-200 rounded-lg px-3 py-2 text-sm"
              placeholder="일정 내용"
            />
            <button
              type="button"
              onClick={() => removeItem(item.id)}
              className="shrink-0 px-2 text-gray-400 hover:text-red-500"
              title="항목 삭제"
            >
              ✕
            </button>
          </div>
        ))}
        <button
          type="button"
          onClick={addItem}
          className="text-sm font-semibold text-emerald-700 hover:text-emerald-800"
        >
          + 항목 추가
        </button>
      </div>
    </ModalShell>
  );
}

function openSectionContextMenu(
  e: React.MouseEvent,
  section: HubEditSection,
  setCtxMenu: (menu: { x: number; y: number; section: HubEditSection } | null) => void,
) {
  e.preventDefault();
  e.stopPropagation();
  setCtxMenu({ x: e.clientX, y: e.clientY, section });
}

interface HubColumnProps {
  routineTasks: Task[];
  quarter?: string;
  referenceDate?: Date;
  onSelectRoutine?: (task: Task) => void;
  onSelectRoutineMilestone?: (taskId: string, milestoneId: string) => void;
}

export function HubColumn({
  routineTasks,
  quarter = '2026-Q2',
  referenceDate,
  onSelectRoutine,
  onSelectRoutineMilestone,
}: HubColumnProps) {
  const { config, setConfig } = useHubConfig();
  const queryClient = useQueryClient();
  const [editSection, setEditSection] = useState<HubEditSection | null>(null);
  const [ctxMenu, setCtxMenu] = useState<{ x: number; y: number; section: HubEditSection } | null>(null);
  const [routineOpening, setRoutineOpening] = useState(false);
  const [activeCategoryIndex, setActiveCategoryIndex] = useState(0);

  const categoryFocus = useRoutineCategoryMilestones(routineTasks);

  const hubSlots = useMemo((): { task: Task | null; label: RoutineCategory }[] => {
    return ROUTINE_CATEGORIES.map((label) => ({
      label,
      task: pickRoutineCategoryTask(routineTasks, label),
    }));
  }, [routineTasks]);

  const openRoutineCategory = async (label: RoutineCategory, task: Task | null) => {
    if (routineOpening) return;
    if (task) {
      onSelectRoutine?.(task);
      return;
    }
    setRoutineOpening(true);
    try {
      const { data: created } = await apiClient.post<Task>(
        '/tasks',
        routineCategoryShellPayload(label, quarter),
      );
      await invalidateTaskCaches(queryClient, created.id);
      onSelectRoutine?.(created);
    } catch (err: unknown) {
      alert(getApiErrorMessage(err, `"${label}" 업무를 준비하지 못했습니다.`));
    } finally {
      setRoutineOpening(false);
    }
  };

  const handleFocusMilestoneClick = async (milestoneId: string) => {
    const entry = categoryFocus[activeCategoryIndex];
    const label = ROUTINE_CATEGORIES[activeCategoryIndex];
    if (entry?.task) {
      onSelectRoutineMilestone?.(entry.task.id, milestoneId);
      return;
    }
    if (routineOpening) return;
    setRoutineOpening(true);
    try {
      const { data: created } = await apiClient.post<Task>(
        '/tasks',
        routineCategoryShellPayload(label, quarter),
      );
      await invalidateTaskCaches(queryClient, created.id);
      onSelectRoutineMilestone?.(created.id, milestoneId);
    } catch (err: unknown) {
      alert(getApiErrorMessage(err, `"${label}" 업무를 준비하지 못했습니다.`));
    } finally {
      setRoutineOpening(false);
    }
  };

  return (
    <>
      <div className="hub-column" id="hub-column">
        <div
          className="hub-box hub-box--focus"
          onContextMenu={(e) => openSectionContextMenu(e, 'schedule', setCtxMenu)}
        >
          <div className="hub-schedule-planner">
            <div className="hub-schedule-head">
              <span className="hub-schedule-icon" aria-hidden="true">
                <svg viewBox="0 0 24 24">
                  <rect x="3" y="4" width="18" height="18" rx="2" />
                  <path d="M16 2v4" />
                  <path d="M8 2v4" />
                  <path d="M3 10h18" />
                </svg>
              </span>
              <div className="board-project-title">{config.scheduleTitle}</div>
            </div>
            <HubScheduleCarousel items={config.scheduleItems} focusDate={referenceDate} />
          </div>
        </div>

        <div className="hub-diamond-wrap" id="hub-diamond-wrap">
          <div className="hub-diamond" id="hub-diamond">
            <div className="hub-diamond-inner">
              <div className="hub-diamond-head">
                <span className="hub-diamond-icon" aria-hidden="true">
                  <svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
                    <path d="M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" />
                    <path d="M3 3v5h5" />
                    <path d="M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16" />
                    <path d="M21 21 v-5 h-5" />
                  </svg>
                </span>
                <div className="board-project-title">상시업무</div>
              </div>
              <div className="hub-diamond-divider" aria-hidden="true" />
              <div className="hub-routine-grid">
                {hubSlots.map(({ label, task }, i) => (
                  <button
                    key={task?.id ?? `cat-${i}`}
                    type="button"
                    className={`hub-routine-item${activeCategoryIndex === i ? ' is-active' : ''}`}
                    disabled={routineOpening}
                    onMouseEnter={() => setActiveCategoryIndex(i)}
                    onFocus={() => setActiveCategoryIndex(i)}
                    onClick={() => openRoutineCategory(label, task)}
                    onContextMenu={(e) => e.stopPropagation()}
                  >
                    {label}
                  </button>
                ))}
              </div>
            </div>
          </div>
        </div>

        <div className="hub-box hub-box--message hub-box--routine-focus">
          <HubRoutineFocusPanel
            activeIndex={activeCategoryIndex}
            onActiveIndexChange={setActiveCategoryIndex}
            categories={categoryFocus}
            onSelectMilestone={handleFocusMilestoneClick}
          />
        </div>
      </div>

      {ctxMenu && (
        <ContextMenu
          x={ctxMenu.x}
          y={ctxMenu.y}
          onClose={() => setCtxMenu(null)}
          items={[{
            icon: '✏',
            label: '수정',
            onClick: () => setEditSection(ctxMenu.section),
          }]}
        />
      )}

      {editSection === 'schedule' && (
        <ScheduleEditModal
          config={config}
          quarter={quarter}
          onSave={(patch) => setConfig((prev) => ({ ...prev, ...patch }))}
          onClose={() => setEditSection(null)}
        />
      )}
    </>
  );
}
