import { useMemo, useRef } from 'react';
import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import type { DraggableAttributes } from '@dnd-kit/core';
import type { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';
import type { Task } from '../../types';
import { DonutGauge } from './DonutGauge';
import { getProjectTitleStatusClass } from '../../lib/taskStatusVisual';
import { getVisibleIssueEntries } from '../../lib/taskIssues';
import { resolveTaskWeekFocus } from '../../lib/milestoneWeekFocus';

function fmtDate(iso: string | null | undefined): string {
  if (!iso) return '';
  const d = new Date(iso);
  return `${d.getFullYear()}.${String(d.getMonth() + 1).padStart(2, '0')}.${String(d.getDate()).padStart(2, '0')}`;
}

function fmtDateRange(task: Task): string {
  if (!task.showDate || (!task.startDate && !task.dueDate)) return '';
  const start = task.startDate ? fmtDate(task.startDate) : '?';
  const end = task.dueDate ? fmtDate(task.dueDate) : '?';
  return `${start} ~ ${end}`;
}

function overviewTextForCard(text: string | null | undefined): string {
  if (!text?.trim()) return '';
  return text
    .split('\n')
    .map((l) => l.replace(/^[•·\-]\s*/, '').trim())
    .filter(Boolean)
    .join(' ');
}

function firstDescriptionLine(text: string | null | undefined): string {
  if (!text) return '';
  const line = text.split('\n').map((l) => l.replace(/^[•·\-]\s*/, '').trim()).find(Boolean);
  return line ?? '';
}

type SectionOption = { value: string; label: string };

export function SortableTaskCard({
  task,
  variant = 'project',
  onSelect,
  referenceWeekMonday,
}: {
  task: Task;
  variant?: 'project' | 'routine';
  sectionOptions?: SectionOption[];
  accent?: string;
  onSelect?: (task: Task) => void;
  referenceWeekMonday?: Date;
}) {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: task.id });
  const pointerStart = useRef<{ x: number; y: number } | null>(null);

  const handlePointerDown = (e: React.PointerEvent) => {
    if (e.button !== 0) return;
    pointerStart.current = { x: e.clientX, y: e.clientY };
    listeners?.onPointerDown?.(e);
  };

  const handlePointerUp = (e: React.PointerEvent) => {
    if (e.button !== 0 || !pointerStart.current) return;
    const dx = e.clientX - pointerStart.current.x;
    const dy = e.clientY - pointerStart.current.y;
    pointerStart.current = null;
    if (!isDragging && Math.hypot(dx, dy) < 8) {
      onSelect?.(task);
    }
  };

  return (
    <TaskCard
      task={task}
      variant={variant}
      referenceWeekMonday={referenceWeekMonday}
      dragRef={setNodeRef}
      dragStyle={{
        transform: CSS.Transform.toString(transform),
        transition,
        opacity: isDragging ? 0.35 : 1,
      }}
      dragAttributes={attributes}
      dragListeners={listeners}
      onPointerDown={handlePointerDown}
      onPointerUp={handlePointerUp}
    />
  );
}

export function TaskCard({
  task,
  variant = 'project',
  referenceWeekMonday,
  dragRef,
  dragStyle,
  dragAttributes,
  dragListeners,
  onPointerDown,
  onPointerUp,
}: {
  task: Task;
  variant?: 'project' | 'routine';
  referenceWeekMonday?: Date;
  dragRef?: (node: HTMLElement | null) => void;
  dragStyle?: React.CSSProperties;
  dragAttributes?: DraggableAttributes;
  dragListeners?: SyntheticListenerMap;
  onPointerDown?: (e: React.PointerEvent) => void;
  onPointerUp?: (e: React.PointerEvent) => void;
}) {
  const dragHandlers = {
    onPointerDown: (e: React.PointerEvent) => {
      onPointerDown?.(e);
    },
    onPointerUp: (e: React.PointerEvent) => {
      onPointerUp?.(e);
    },
    onKeyDown: dragListeners?.onKeyDown as React.KeyboardEventHandler<HTMLDivElement> | undefined,
  };

  if (variant === 'routine') {
    const descLine = firstDescriptionLine(task.description);
    return (
      <div
        ref={dragRef}
        style={dragStyle}
        {...dragAttributes}
        data-task-card="true"
        data-task-id={task.id}
        className="board-routine-item"
        {...dragHandlers}
      >
        <span className="board-project-title">{task.title}</span>
        {descLine && <p className="board-project-desc">• {descLine}</p>}
      </div>
    );
  }

  const dateRange = fmtDateRange(task);
  const overviewText = task.showDescription ? overviewTextForCard(task.description) : '';
  const showProgress = task.showProgress !== false;
  const issueVisibility = referenceWeekMonday ? { weekMonday: referenceWeekMonday } : undefined;
  const visibleIssues = getVisibleIssueEntries(task, issueVisibility);
  const hasVisibleIssue = visibleIssues.length > 0;

  const weekFocus = useMemo(
    () => (referenceWeekMonday ? resolveTaskWeekFocus(task, referenceWeekMonday) : null),
    [task, referenceWeekMonday],
  );

  const progressTask = useMemo(() => {
    if (!weekFocus) return task;
    if (weekFocus.progress >= 100) return { status: 'DONE' as const, progress: 100 };
    return { status: 'IN_PROGRESS' as const, progress: weekFocus.progress };
  }, [task, weekFocus]);

  return (
    <article
      ref={dragRef}
      style={dragStyle}
      {...dragAttributes}
      data-task-card="true"
      data-task-id={task.id}
      className="project-sub-card"
      {...dragHandlers}
    >
      <div className="project-sub-body">
        <div className="project-fields">
          <div className={`project-sub-title ${getProjectTitleStatusClass(task, issueVisibility)}`}>
            <span className="project-sub-title-text">{task.title}</span>
          </div>
          {referenceWeekMonday ? (
            weekFocus ? (
              <>
                <div className="project-field project-field--week-focus">
                  <span className="project-field-label">진행 단계</span>
                  <span className="project-field-value">{weekFocus.milestoneTitle}</span>
                </div>
                <div className="project-field project-field--week-period">
                  <span className="project-field-label">수행 기간</span>
                  <span className="project-field-value">{weekFocus.periodLabel}</span>
                </div>
              </>
            ) : (
              <div className="project-field project-field--week-empty">
                <span className="project-field-value">해당 주 업무 없음</span>
              </div>
            )
          ) : (
            <>
              {dateRange && (
                <div className="project-field">
                  <span className="project-field-label">수행 기간</span>
                  <span className="project-field-value">{dateRange}</span>
                </div>
              )}
              {overviewText && (
                <div
                  className={`project-field project-field--overview${hasVisibleIssue ? '' : ' project-field--overview-expanded'}`}
                >
                  <span className="project-field-label">개요</span>
                  <span className="project-field-value">{overviewText}</span>
                </div>
              )}
            </>
          )}
          {visibleIssues.map((entry) => (
            <div key={entry.id} className="project-field project-field--issue">
              <span className="project-issue-icon" aria-label="이슈" title="이슈">
                <svg viewBox="0 0 24 24" aria-hidden="true">
                  <path d="M12 7v6" />
                  <path d="M12 17h.01" />
                </svg>
              </span>
              <span className="project-field-value project-field-value--issue">{entry.text}</span>
            </div>
          ))}
        </div>
        {showProgress && (
          <>
            <div className="project-sub-divider" aria-hidden="true" />
            <div className="progress-col">
              <DonutGauge task={progressTask} />
            </div>
          </>
        )}
      </div>
    </article>
  );
}
