import { writeFileSync, existsSync, readFileSync } from "fs";
import * as cheerio from "cheerio";

const CACHE_FILE = "./temp/scheduleCache.json";

const URLS = {
  section1:
    "https://isangjeong.icems.kr/schdList.do?section=1&m=021101&s=isangjeong",
  section2:
    "https://isangjeong.icems.kr/schdList.do?section=2&m=021101&s=isangjeong",
};

const MONTH_XPATH_MAP: Record<
  string,
  { section: keyof typeof URLS; divIndex: number }
> = {
  "03": { section: "section1", divIndex: 2 },
  "04": { section: "section1", divIndex: 3 },
  "05": { section: "section1", divIndex: 4 },
  "06": { section: "section1", divIndex: 5 },
  "07": { section: "section1", divIndex: 6 },
  "08": { section: "section1", divIndex: 7 },
  "09": { section: "section2", divIndex: 2 },
  "10": { section: "section2", divIndex: 3 },
  "11": { section: "section2", divIndex: 4 },
  "12": { section: "section2", divIndex: 5 },
  "01": { section: "section2", divIndex: 6 },
  "02": { section: "section2", divIndex: 7 },
};

async function fetchSectionSchedule(
  url: string,
  divIndexes: { month: string; index: number }[]
): Promise<Record<string, { date: string; desc: string }[]>> {
  const res = await fetch(url, {
    headers: {
      "User-Agent": "Mozilla/5.0 (compatible; today.isangjeong/1.0)",
    },
  });

  const html = await res.text();
  const $ = cheerio.load(html);

  const sectionSchedule: Record<string, { date: string; desc: string }[]> = {};

  for (const { month, index } of divIndexes) {
    const selector = `#all-scroll > div > form > div > div:nth-of-type(2) > div:nth-of-type(${index}) > dl > dd > ul`;
    const items: { date: string; desc: string }[] = [];

    $(selector).find("li").each((_, li) => {
      const text = $(li).text().trim().replace(/\u00A0/g, " ");
      if (text) {
        const [date, desc] = text.split(" : ");
        if (date && desc) {
          items.push({ date: date.trim(), desc: desc.trim() });
        }
      }
    });

    sectionSchedule[month] = items;
  }

  return sectionSchedule;
}

export async function getAllSchedules(
  refresh = false
): Promise<Record<string, { date: string; desc: string }[]>> {
  if (!refresh && existsSync(CACHE_FILE)) {
    const cached = readFileSync(CACHE_FILE, "utf-8");
    return JSON.parse(cached);
  }

  const sectionMap: Record<keyof typeof URLS, { month: string; index: number }[]> = {
    section1: [],
    section2: [],
  };

  for (const [month, { section, divIndex }] of Object.entries(MONTH_XPATH_MAP)) {
    sectionMap[section].push({ month, index: divIndex });
  }

  // 병렬로 section1, section2 요청
  const promises = (Object.keys(sectionMap) as (keyof typeof URLS)[]).map(
    async (section) => {
      const url = URLS[section];
      try {
        const sectionSchedule = await fetchSectionSchedule(url, sectionMap[section]);
        console.log(`✅ ${section} 완료`);
        return sectionSchedule;
      } catch (err) {
        console.error(`❌ ${section} 실패:`, err);
        return Object.fromEntries(sectionMap[section].map(({ month }) => [month, []]));
      }
    }
  );

  const results = await Promise.all(promises);

  const schedule = Object.assign({}, ...results);

  writeFileSync(CACHE_FILE, JSON.stringify(schedule, null, 2), "utf-8");
  console.log(`📦 캐시 저장됨 → ${CACHE_FILE}`);
  return schedule;
}
