import { useEffect, useMemo, useRef, useState, type MouseEvent } from 'react';
import {
  fmtPeriodPickerLabel,
  parseMilestonePeriods,
  parsePeriodNoteLines,
  pickLatestPeriodId,
  sortPeriodsByRecent,
} from '../../lib/milestonePeriods';
import type { Milestone } from '../../types';

interface MilestoneContentListProps {
  milestone: Pick<Milestone, 'id' | 'periodEntries' | 'startDate' | 'dueDate' | 'description'> | null | undefined;
  emptyMessage: string;
  onContextMenu?: (event: MouseEvent) => void;
}

function PeriodPicker({
  periods,
  selectedId,
  onSelect,
}: {
  periods: ReturnType<typeof parseMilestonePeriods>;
  selectedId: string;
  onSelect: (id: string) => void;
}) {
  const [open, setOpen] = useState(false);
  const rootRef = useRef<HTMLDivElement>(null);

  const selected = periods.find((p) => p.id === selectedId) ?? periods[0];
  const selectedIndex = periods.findIndex((p) => p.id === selected?.id);
  const label = selected ? fmtPeriodPickerLabel(selected, selectedIndex >= 0 ? selectedIndex : 0) : '';

  useEffect(() => {
    if (!open) return;
    const onPointerDown = (event: PointerEvent) => {
      if (!rootRef.current?.contains(event.target as Node)) setOpen(false);
    };
    document.addEventListener('pointerdown', onPointerDown);
    return () => document.removeEventListener('pointerdown', onPointerDown);
  }, [open]);

  if (!selected || !label) return null;

  const canPick = periods.length > 1;

  return (
    <div className="milestone-content-period" ref={rootRef}>
      <button
        type="button"
        className={`milestone-content-period__btn${open ? ' is-open' : ''}`}
        aria-haspopup="listbox"
        aria-expanded={open}
        disabled={!canPick}
        onClick={() => canPick && setOpen((v) => !v)}
        title={canPick ? '다른 기간 업무내용 보기' : undefined}
      >
        <span className="milestone-content-period__label">{label}</span>
        {canPick && (
          <svg width="10" height="10" viewBox="0 0 10 10" aria-hidden className="milestone-content-period__chev">
            <path d="M2 3.5 L5 6.5 L8 3.5" fill="none" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" />
          </svg>
        )}
      </button>

      {open && canPick && (
        <ul className="milestone-content-period__menu" role="listbox">
          {periods.map((period, index) => {
            const isActive = period.id === selectedId;
            return (
              <li key={period.id} role="option" aria-selected={isActive}>
                <button
                  type="button"
                  className={`milestone-content-period__option${isActive ? ' is-active' : ''}`}
                  onClick={() => {
                    onSelect(period.id);
                    setOpen(false);
                  }}
                >
                  {fmtPeriodPickerLabel(period, index)}
                </button>
              </li>
            );
          })}
        </ul>
      )}
    </div>
  );
}

export function MilestoneContentList({
  milestone,
  emptyMessage,
  onContextMenu,
}: MilestoneContentListProps) {
  const periods = useMemo(
    () => sortPeriodsByRecent(parseMilestonePeriods(milestone)),
    [milestone],
  );

  const latestId = useMemo(() => pickLatestPeriodId(periods), [periods]);
  const [selectedPeriodId, setSelectedPeriodId] = useState<string | null>(null);

  useEffect(() => {
    setSelectedPeriodId(latestId);
  }, [milestone?.id, latestId]);

  const activePeriod =
    periods.find((p) => p.id === selectedPeriodId) ?? periods[0] ?? null;
  const lines = parsePeriodNoteLines(activePeriod?.note);

  return (
    <>
      <div className="detail-section-head">
        <h3 className="detail-section-label">업무내용</h3>
        {milestone && periods.length > 0 && activePeriod && (
          <PeriodPicker
            periods={periods}
            selectedId={activePeriod.id}
            onSelect={setSelectedPeriodId}
          />
        )}
      </div>

      <ul
        className="min-h-0 flex-1 space-y-2 overflow-y-auto pr-1"
        onContextMenu={onContextMenu}
      >
        {!milestone ? (
          <li className="detail-body-muted">{emptyMessage}</li>
        ) : periods.length === 0 ? (
          <li className="detail-body-muted">{emptyMessage}</li>
        ) : lines.length === 0 ? (
          <li className="detail-body-muted">이 기간에 입력된 업무내용이 없습니다.</li>
        ) : (
          lines.map((line, index) => (
            <li key={`${activePeriod!.id}-${index}`} className="flex gap-2" onContextMenu={onContextMenu}>
              <span className="detail-body-text shrink-0 text-[#4a90d9]">•</span>
              <p className="detail-body-content min-w-0 flex-1 whitespace-pre-wrap break-words">{line}</p>
            </li>
          ))
        )}
      </ul>
    </>
  );
}
