/*
 * 전시 일정 관리 표시 데이터 (SCR-15 · M1·M6).
 * ★ 경계면(부분 실 + 부분 샘플):
 *   - 행사(Event) 목록·기간·배정 홀은 실 API 가능(Event 엔티티 존재).
 *     현재는 인증 응답 workspaces(WorkspaceDto)를 실 원천으로 사용하며, 없으면 크롤링 데이터로 폴백한다.
 *   - 폴백 원천: kintex.com 크롤링 10년치(2016~2026, 1,098건) — kintexEvents.ts (백엔드 V10 시드와 동일).
 *   - estVisitors·카테고리는 추정치(샘플). 홀 가동률·캘린더 점유는 크롤링 데이터 기반 계산.
 */
import type { FlowStatus } from '../../components/ui/Badge';
import { KINTEX_EVENT_ROWS, type KxCategory } from './kintexEvents';

export type EventCategory = KxCategory;
export type EventStatus = 'ongoing' | 'upcoming' | 'ended';

export interface ScheduleEvent {
  id: string;
  title: string;
  category: EventCategory;
  /** category 가 DB 실값이 아니라 기본값('exhibition')으로 대체됐는지(R15-02 시각 표기용). */
  categoryDefaulted?: boolean;
  status: EventStatus;
  period: string; // "2026.09.05–09.08"
  start: string; // "2026-09-05"
  end: string; // "2026-09-08"
  halls: string; // "홀 4, 5"
  estVisitors: string; // "25,000명"
  designStatus?: FlowStatus;
  thumbIdx: number; // 로컬 mock 썸네일 인덱스
}

export const CATEGORY_LABEL: Record<EventCategory, string> = {
  exhibition: '전시',
  culture: '문화·예술',
  trade: '무역·산업',
  tech: '기술',
};
export const STATUS_LABEL: Record<EventStatus, string> = {
  ongoing: '진행중',
  upcoming: '예정',
  ended: '종료',
};

const TODAY_YMD = '2026-07-11'; // currentDate 고정(데모) — ExhibitionSchedulePage.TODAY 와 정합

function statusOf(start: string, end: string): EventStatus {
  if (end < TODAY_YMD) return 'ended';
  if (start > TODAY_YMD) return 'upcoming';
  return 'ongoing';
}

/** "2016-01-28","2016-01-31" → "2016.01.28–01.31" */
function periodLabel(start: string, end: string): string {
  const s = start.split('-').join('.');
  const e = end.split('-').join('.');
  return e.startsWith(s.slice(0, 5)) ? `${s}–${e.slice(5)}` : `${s}–${e}`;
}

// 진행중 데모 표시용 설계 상태(샘플) — 진행중·임박 행사에만 부여
const DESIGN_CYCLE: FlowStatus[] = ['building', 'submitted', 'draft', 'inspected'];

/** 크롤링 10년치 전체 (1,098건, 시작일 오름차순). */
export const ALL_EVENTS: ScheduleEvent[] = KINTEX_EVENT_ROWS.map((r, i) => {
  const [id, title, start, end, halls, category, visitors] = r;
  const status = statusOf(start, end);
  return {
    id,
    title,
    category,
    status,
    period: periodLabel(start, end),
    start,
    end,
    halls,
    estVisitors: `${visitors.toLocaleString()}명`,
    designStatus: status !== 'ended' ? DESIGN_CYCLE[i % DESIGN_CYCLE.length] : undefined,
    thumbIdx: i % 3,
  };
});

/** 데이터에 존재하는 연도 내림차순 목록 (연도 필터용). */
export const EVENT_YEARS: number[] = [...new Set(ALL_EVENTS.map((e) => Number(e.start.slice(0, 4))))].sort(
  (a, b) => b - a,
);

/** 하위 호환: 기존 SAMPLE_EVENTS — 오늘 기준 진행중·예정 상위 목록. */
export const SAMPLE_EVENTS: ScheduleEvent[] = ALL_EVENTS.filter((e) => e.status !== 'ended').slice(0, 12);

/** 해당 월에 행사가 있는 날짜 집합 — key: 'YYYY-M-D' (미니 캘린더 하이라이트). */
export function eventDaysFor(year: number, month0: number, events: ScheduleEvent[] = ALL_EVENTS): Set<string> {
  const days = new Set<string>();
  const last = new Date(year, month0 + 1, 0).getDate();
  const mStart = `${year}-${String(month0 + 1).padStart(2, '0')}-01`;
  const mEnd = `${year}-${String(month0 + 1).padStart(2, '0')}-${String(last).padStart(2, '0')}`;
  for (const e of events) {
    if (e.end < mStart || e.start > mEnd) continue;
    const from = e.start > mStart ? Number(e.start.slice(8, 10)) : 1;
    const to = e.end < mEnd ? Number(e.end.slice(8, 10)) : last;
    for (let d = from; d <= to; d++) days.add(`${year}-${month0 + 1}-${d}`);
  }
  return days;
}

/** 해당 월 날짜(YYYY-MM-DD) → 그 날 진행 중인 행사 목록 (WISE 달력 월 그리드용). */
export function eventsByDateFor(year: number, month0: number, events: ScheduleEvent[] = ALL_EVENTS): Map<string, ScheduleEvent[]> {
  const map = new Map<string, ScheduleEvent[]>();
  const last = new Date(year, month0 + 1, 0).getDate();
  const mm = String(month0 + 1).padStart(2, '0');
  for (const e of events) {
    if (e.end < `${year}-${mm}-01` || e.start > `${year}-${mm}-${String(last).padStart(2, '0')}`) continue;
    const from = e.start.slice(0, 7) === `${year}-${mm}` ? Number(e.start.slice(8, 10)) : 1;
    const to = e.end.slice(0, 7) === `${year}-${mm}` ? Number(e.end.slice(8, 10)) : last;
    for (let d = from; d <= to; d++) {
      const key = `${year}-${mm}-${String(d).padStart(2, '0')}`;
      const arr = map.get(key) ?? [];
      arr.push(e);
      map.set(key, arr);
    }
  }
  return map;
}

export interface HallUtilRow {
  label: string;
  pct: number;
}

const HALL_GROUPS: { label: string; lo: number; hi: number }[] = [
  { label: '홀 1-3', lo: 1, hi: 3 },
  { label: '홀 4-5', lo: 4, hi: 5 },
  { label: '홀 6-8', lo: 6, hi: 8 },
  { label: '홀 9-10', lo: 9, hi: 10 },
];

function hallNums(halls: string): number[] {
  return (halls.match(/\d+/g) ?? []).map(Number).filter((n) => n >= 1 && n <= 10);
}

/** 크롤링 데이터 기반 월별 홀 그룹 가동률 — (그룹 홀에 행사가 있는 날 수)/(월 일수). */
export function hallUtilizationFor(year: number, month0: number): HallUtilRow[] {
  const last = new Date(year, month0 + 1, 0).getDate();
  const mm = String(month0 + 1).padStart(2, '0');
  const mStart = `${year}-${mm}-01`;
  const mEnd = `${year}-${mm}-${String(last).padStart(2, '0')}`;
  return HALL_GROUPS.map((g) => {
    const busy = new Set<number>();
    for (const e of ALL_EVENTS) {
      if (e.end < mStart || e.start > mEnd) continue;
      if (!hallNums(e.halls).some((n) => n >= g.lo && n <= g.hi)) continue;
      const from = e.start > mStart ? Number(e.start.slice(8, 10)) : 1;
      const to = e.end < mEnd ? Number(e.end.slice(8, 10)) : last;
      for (let d = from; d <= to; d++) busy.add(d);
    }
    return { label: g.label, pct: Math.round((busy.size / last) * 100) };
  });
}

/** 하위 호환: 2026-08 기준 가동률. */
export const HALL_UTILIZATION: HallUtilRow[] = hallUtilizationFor(2026, 7);

/** 하위 호환: 미니 캘린더 하이라이트(2026-08). */
export const EVENT_DAYS = eventDaysFor(2026, 7);
