export interface MilestonePeriodEntry {
  id: string;
  startDate?: string | null;
  dueDate?: string | null;
  note?: string | null;
}

function parseDay(iso: string): Date {
  const d = new Date(iso);
  return new Date(d.getFullYear(), d.getMonth(), d.getDate());
}

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() || null : null;
    const dueDate = typeof row.dueDate === 'string' ? row.dueDate.trim() || null : null;
    const note = typeof row.note === 'string' ? row.note.trim() || null : null;
    if (!startDate && !dueDate && !note) continue;
    entries.push({
      id: typeof row.id === 'string' && row.id ? row.id : `period-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
      startDate,
      dueDate,
      note,
    });
  }
  return entries;
}

export function deriveMilestoneDatesFromPeriods(entries: MilestonePeriodEntry[]): {
  startDate: Date | null;
  dueDate: Date | null;
} {
  const times: number[] = [];
  for (const entry of entries) {
    if (entry.startDate) times.push(parseDay(entry.startDate).getTime());
    if (entry.dueDate) times.push(parseDay(entry.dueDate).getTime());
  }
  if (times.length === 0) return { startDate: null, dueDate: null };
  return {
    startDate: new Date(Math.min(...times)),
    dueDate: new Date(Math.max(...times)),
  };
}

export function resolveMilestonePeriodPayload(body: Record<string, unknown>): {
  periodEntries: MilestonePeriodEntry[] | undefined;
  startDate: Date | null | undefined;
  dueDate: Date | null | undefined;
} {
  if (body.periodEntries !== undefined) {
    const periodEntries = normalizePeriodEntries(body.periodEntries);
    const { startDate, dueDate } = deriveMilestoneDatesFromPeriods(periodEntries);
    return {
      periodEntries,
      startDate,
      dueDate,
    };
  }

  const hasLegacyStart = body.startDate !== undefined;
  const hasLegacyDue = body.dueDate !== undefined;
  if (!hasLegacyStart && !hasLegacyDue) {
    return { periodEntries: undefined, startDate: undefined, dueDate: undefined };
  }

  const startDate = body.startDate ? new Date(String(body.startDate)) : null;
  const dueDate = body.dueDate ? new Date(String(body.dueDate)) : null;
  const periodEntries =
    startDate || dueDate
      ? normalizePeriodEntries([
          {
            id: `period-legacy-${Date.now()}`,
            startDate: startDate ? startDate.toISOString().slice(0, 10) : null,
            dueDate: dueDate ? dueDate.toISOString().slice(0, 10) : null,
            note: null,
          },
        ])
      : [];

  return { periodEntries, startDate, dueDate };
}

function toDateInput(d: Date | null | undefined): string | null {
  return d ? d.toISOString().slice(0, 10) : null;
}

/** 레거시 description(@overview: 포함) → 기간1 note 본문 */
export function legacyDescriptionNote(description: string | null | undefined): string {
  if (!description?.trim()) return '';
  if (description.startsWith('@overview:')) {
    const rest = description.slice('@overview:'.length);
    const nl = rest.indexOf('\n');
    if (nl === -1) return rest.trim();
    const body = rest.slice(nl + 1).trim();
    if (body) return body;
    return rest.slice(0, nl).trim();
  }
  return description.trim();
}

/** 공통업무내용(description)을 periodEntries[0].note로 이관 */
export function migrateDescriptionToPeriodEntries(input: {
  id?: string;
  periodEntries: unknown;
  startDate: Date | null;
  dueDate: Date | null;
  description: string | null;
}): { periodEntries: MilestonePeriodEntry[] | null; migrated: boolean } {
  const legacyNote = legacyDescriptionNote(input.description);
  if (!legacyNote) {
    return { periodEntries: normalizePeriodEntries(input.periodEntries), migrated: false };
  }

  const existing = normalizePeriodEntries(input.periodEntries);
  if (existing.length > 0) {
    if (existing.some((e) => e.note?.trim())) {
      return { periodEntries: existing, migrated: false };
    }
    const updated = [...existing];
    updated[0] = { ...updated[0], note: legacyNote };
    return { periodEntries: updated, migrated: true };
  }

  const id = input.id ? `period-legacy-${input.id}` : `period-legacy-${Date.now()}`;
  return {
    periodEntries: [
      {
        id,
        startDate: toDateInput(input.startDate),
        dueDate: toDateInput(input.dueDate),
        note: legacyNote,
      },
    ],
    migrated: true,
  };
}
