import type { RealEstateArticle } from "../generated/prisma";
import type { NaverRealEstate } from "./naver.service";
import { prisma } from "../../lib/prisma";
import pLimit from "p-limit";

export class RankingService {
  private naver: NaverRealEstate;
  constructor(naver: NaverRealEstate) {
    this.naver = naver;
  }
  async updateRanking(articles: RealEstateArticle[], checkDate: Date) {
    const { token, cookie } = await this.naver.getRankingToken();

    for (let i = 0; i < articles.length; i += 20) {
      const batch = articles.slice(i, i + 20);

      console.log(`🚀 ${i + 1} ~ ${i + batch.length}번 매물 처리 시작`);

      const tasks = batch.map(async (article) => {
        try {
          // cortarNo, lgeo 확인
          if (!article.cortarNo || !article.lgeo) {
            const { cortarNo, lgeo } = await this.updateCortarNoAndLgeo(
              article
            );
            article.cortarNo = cortarNo;
            article.lgeo = lgeo;
          }

          // 랭킹 조회
          const ranking = await this.naver.getRanking(article, token, cookie);

          // DB 업데이트
          await prisma.realEstateArticle.update({
            where: { id: article.id },
            data: {
              ranking,
              rankCheckDate: checkDate.toISOString(),
            },
          });

          console.log(`✅ ${article.articleNumber} - 랭킹 완료 : ${ranking}`);
        } catch (err) {
          console.error(`❌ 오류: ${article.articleNumber}`, err);
        }
      });

      // **이 10개(또는 마지막 batch)가 모두 끝날 때까지 기다림**
      await Promise.allSettled(tasks);

      // 다음 배치가 남아있다면 딜레이
      if (i + 20 < articles.length) {
        console.log(`⏸ 10개 처리 완료 → 10초 휴식`);
        await Bun.sleep(5000);
      }
    }

    console.log("🎉 전체 랭킹 업데이트 완료!");
    await Bun.sleep(100);
  }

  async updateCortarNoAndLgeo(article: RealEstateArticle): Promise<{
    cortarNo: string | null;
    lgeo: string | null;
  }> {
    try {
      const { cortarNo, lgeo } = await this.naver.getCortarNoAndLgeo(article);

      await prisma.realEstateArticle.update({
        where: { id: article.id },
        data: { cortarNo: cortarNo ?? null, lgeo: lgeo ?? null },
      });
      return { cortarNo: cortarNo ?? null, lgeo: lgeo ?? null };
    } catch (error) {
      console.error(`❌ 오류 발생:`, error);
      return { cortarNo: null, lgeo: null };
    }
  }
}
