import type { Milestone, MilestonePeriodEntry } from '../types';
import { routineStageBody } from './routineMilestone';

export type { MilestonePeriodEntry };

export function newPeriodEntry(): MilestonePeriodEntry {
  return {
    id: `period-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
    startDate: '',
    dueDate: '',
    note: '',
  };
}

function toDateInput(iso: string | null | undefined) {
  if (!iso) return '';
  return new Date(iso).toISOString().slice(0, 10);
}

export function normalizePeriodEntries(raw: unknown): MilestonePeriodEntry[] {
  if (!Array.isArray(raw)) return [];
  const entries: MilestonePeriodEntry[] = [];
  for (const item of raw) {
    if (!item || typeof item !== 'object') continue;
    const row = item as Record<string, unknown>;
    const startDate = typeof row.startDate === 'string' ? row.startDate.trim() : '';
    const dueDate = typeof row.dueDate === 'string' ? row.dueDate.trim() : '';
    const note = typeof row.note === 'string' ? row.note : '';
    if (!startDate && !dueDate && !note.trim()) continue;
    entries.push({
      id: typeof row.id === 'string' && row.id ? row.id : newPeriodEntry().id,
      startDate,
      dueDate,
      note,
    });
  }
  return entries;
}

function legacyDescriptionNote(description: string | null | undefined): string {
  return routineStageBody(description).trim();
}

export function parseMilestonePeriods(
  milestone: Pick<Milestone, 'id' | 'periodEntries' | 'startDate' | 'dueDate' | 'description'> | null | undefined,
): MilestonePeriodEntry[] {
  if (!milestone) return [];
  const legacyNote = legacyDescriptionNote(milestone.description);
  const fromJson = normalizePeriodEntries(milestone.periodEntries);
  if (fromJson.length > 0) {
    if (legacyNote && !fromJson.some((p) => p.note.trim())) {
      return fromJson.map((p, i) => (i === 0 ? { ...p, note: legacyNote } : p));
    }
    return fromJson;
  }
  if (milestone.startDate || milestone.dueDate || legacyNote) {
    return [
      {
        id: milestone.id ? `period-legacy-${milestone.id}` : newPeriodEntry().id,
        startDate: toDateInput(milestone.startDate),
        dueDate: toDateInput(milestone.dueDate),
        note: legacyNote,
      },
    ];
  }
  return [];
}

export function serializePeriodEntries(entries: MilestonePeriodEntry[]): MilestonePeriodEntry[] {
  return entries
    .map((entry) => ({
      id: entry.id,
      startDate: entry.startDate.trim(),
      dueDate: entry.dueDate.trim(),
      note: entry.note.trim(),
    }))
    .filter((entry) => entry.startDate || entry.dueDate || entry.note);
}

export function fmtPeriodRange(entry: Pick<MilestonePeriodEntry, 'startDate' | 'dueDate'>) {
  const fmt = (iso: string) => {
    const d = new Date(iso);
    return `${String(d.getMonth() + 1).padStart(2, '0')}/${String(d.getDate()).padStart(2, '0')}`;
  };
  if (entry.startDate && entry.dueDate) return `${fmt(entry.startDate)} ~ ${fmt(entry.dueDate)}`;
  if (entry.dueDate) return fmt(entry.dueDate);
  if (entry.startDate) return `${fmt(entry.startDate)} ~`;
  return '';
}

/** 업무내용 기간 선택 — MM.DD~MM.DD (연도 생략) */
export function fmtPeriodPickerLabel(
  entry: Pick<MilestonePeriodEntry, 'startDate' | 'dueDate'>,
  index: number,
): string {
  const fmt = (iso: string) => {
    const d = new Date(iso);
    return `${String(d.getMonth() + 1).padStart(2, '0')}.${String(d.getDate()).padStart(2, '0')}`;
  };
  if (entry.startDate && entry.dueDate) return `${fmt(entry.startDate)}~${fmt(entry.dueDate)}`;
  if (entry.dueDate) return fmt(entry.dueDate);
  if (entry.startDate) return `${fmt(entry.startDate)}~`;
  return `기간 ${index + 1}`;
}

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

/** 최신 기간 우선 — 종료일·시작일 내림차순 */
export function sortPeriodsByRecent(periods: MilestonePeriodEntry[]): MilestonePeriodEntry[] {
  return [...periods].sort((a, b) => {
    const ta = a.dueDate || a.startDate || '';
    const tb = b.dueDate || b.startDate || '';
    if (ta && tb) return tb.localeCompare(ta);
    if (tb) return 1;
    if (ta) return -1;
    return 0;
  });
}

export function pickLatestPeriodId(periods: MilestonePeriodEntry[]): string | null {
  return sortPeriodsByRecent(periods)[0]?.id ?? null;
}

/** 목록·카드용 — 최신(마지막) 기간 또는 요약 */
export function fmtMilestonePeriodSummary(
  milestone: Pick<Milestone, 'periodEntries' | 'startDate' | 'dueDate'>,
): string {
  const periods = parseMilestonePeriods(milestone);
  if (periods.length === 0) return '';
  if (periods.length === 1) return fmtPeriodRange(periods[0]) || '';
  const last = periods[periods.length - 1];
  const lastLabel = fmtPeriodRange(last);
  return lastLabel ? `${lastLabel} 외 ${periods.length - 1}건` : `기간 ${periods.length}건`;
}

export interface MilestoneContentBlock {
  key: string;
  label: string;
  lines: string[];
}

/** @deprecated MilestoneContentList에서 기간 선택 UI로 대체 */
export function buildMilestoneContentBlocks(
  milestone: Pick<Milestone, 'id' | 'periodEntries' | 'startDate' | 'dueDate' | 'description'> | null | undefined,
): MilestoneContentBlock[] {
  if (!milestone) return [];

  const blocks: MilestoneContentBlock[] = [];
  const periods = sortPeriodsByRecent(parseMilestonePeriods(milestone)).reverse();

  periods.forEach((period, index) => {
    const lines = parsePeriodNoteLines(period.note);
    if (lines.length === 0) return;
    blocks.push({
      key: period.id,
      label: fmtPeriodPickerLabel(period, index),
      lines,
    });
  });

  return blocks;
}
