/**
 * 리트윗 데이터 재수집 스크립트
 * 원본 작성자의 타임라인에서 매칭되는 트윗을 찾아 이미지와 내용을 복구합니다.
 *
 * 사용법: node scripts/refetch-retweets.js [scheduleId1,scheduleId2,...]
 */
import mysql from 'mysql2/promise';
import { fetchAllTweets, fetchSingleTweet, extractTitle } from '../src/services/x/scraper.js';

const NITTER_URL = process.env.NITTER_URL || 'http://nitter:8080';

const pool = mysql.createPool({
  host: process.env.DB_HOST || 'mariadb',
  port: parseInt(process.env.DB_PORT || '3306'),
  user: process.env.DB_USER || 'fromis9',
  password: process.env.DB_PASSWORD || 'fromis9',
  database: process.env.DB_NAME || 'fromis9',
});

// 간단한 로거
const log = {
  info: (msg) => console.log(msg),
  error: (msg) => console.error(msg),
};

// 타임라인 캐시 (같은 작성자의 반복 조회 방지)
const timelineCache = new Map();

/**
 * 원본 작성자의 타임라인에서 매칭되는 트윗 찾기
 */
async function findOriginalTweet(username, content, date) {
  // 캐시 확인
  if (!timelineCache.has(username)) {
    console.log(`  @${username} 타임라인 수집 중...`);
    const tweets = await fetchAllTweets(NITTER_URL, username, log, { includeRetweets: false });
    timelineCache.set(username, tweets);
    console.log(`  -> ${tweets.length}개 트윗 수집 완료`);
  }

  const tweets = timelineCache.get(username);

  // 내용의 첫 30자로 매칭 (완전 일치는 포맷 차이로 어려움)
  const contentStart = content.substring(0, 30).trim();

  for (const tweet of tweets) {
    if (tweet.text.startsWith(contentStart)) {
      return tweet;
    }
  }

  // 날짜 기반 유사 매칭 시도
  const targetDate = date?.split('T')[0];
  if (targetDate) {
    for (const tweet of tweets) {
      const tweetDate = tweet.time?.toISOString().split('T')[0];
      if (tweetDate === targetDate && tweet.text.includes(contentStart.substring(0, 15))) {
        return tweet;
      }
    }
  }

  return null;
}

async function main() {
  const argIds = process.argv[2]?.split(',').map(Number).filter(Boolean);

  let rows;
  if (argIds && argIds.length > 0) {
    [rows] = await pool.query(
      `SELECT sx.schedule_id, sx.post_id, sx.username, sx.content, sx.image_urls, s.date
       FROM schedule_x sx JOIN schedules s ON sx.schedule_id = s.id
       WHERE sx.schedule_id IN (?)`,
      [argIds]
    );
  } else {
    // 이미지가 없는 리트윗 또는 content에 문제가 있는 것
    [rows] = await pool.query(
      `SELECT sx.schedule_id, sx.post_id, sx.username, sx.content, sx.image_urls, s.date
       FROM schedule_x sx JOIN schedules s ON sx.schedule_id = s.id
       WHERE sx.content LIKE 'RT @%'
          OR sx.content LIKE '%nitter%t.co%'
          OR (sx.image_urls IS NULL AND sx.username != 'realfromis_9')`
    );
  }

  console.log(`대상: ${rows.length}건\n`);
  if (rows.length === 0) {
    await pool.end();
    return;
  }

  let updated = 0;
  let failed = 0;

  for (const row of rows) {
    try {
      const username = row.username || 'realfromis_9';
      console.log(`[${row.schedule_id}] @${username} post_id=${row.post_id}`);

      // 1단계: 먼저 개별 페이지에서 시도 (RT prefix 제거)
      let newContent = row.content || '';
      let newImageUrls = null;
      let newPostId = row.post_id;

      // RT @ 프리픽스가 있으면 제거
      const rtPrefixMatch = newContent.match(/^RT @\w+:\s*/);
      if (rtPrefixMatch) {
        newContent = newContent.slice(rtPrefixMatch[0].length);
      }
      newContent = newContent.replace(/…$/, '').trim();

      // nitter t.co 링크 수정
      newContent = newContent.replace(/https?:\/\/nitter[^/]*\/t\.co\/(\S+)/g, 'https://t.co/$1');

      // 2단계: 이미지가 없으면 원본 작성자 타임라인에서 찾기
      if (!row.image_urls) {
        const original = await findOriginalTweet(username, newContent, row.date);
        if (original) {
          newContent = original.text;
          newPostId = original.id;
          if (original.imageUrls.length > 0) {
            newImageUrls = JSON.stringify(original.imageUrls);
          }
          console.log(`  -> 원본 발견! id=${original.id}, images=${original.imageUrls.length}`);
        } else {
          console.log(`  -> 원본 미발견, 텍스트만 수정`);
        }
      }

      const newTitle = extractTitle(newContent);

      // DB 업데이트
      await pool.query('UPDATE schedules SET title = ? WHERE id = ?', [newTitle, row.schedule_id]);
      await pool.query(
        'UPDATE schedule_x SET post_id = ?, username = ?, content = ?, image_urls = ? WHERE schedule_id = ?',
        [newPostId, username, newContent, newImageUrls, row.schedule_id]
      );

      console.log(`  -> title: ${newTitle.substring(0, 60)} | images: ${newImageUrls ? JSON.parse(newImageUrls).length : 0}`);
      updated++;
    } catch (err) {
      console.error(`  -> 실패: ${err.message}`);
      failed++;
    }
  }

  console.log(`\n완료: ${updated}건 수정, ${failed}건 실패`);
  await pool.end();
}

main().catch(err => {
  console.error(err);
  process.exit(1);
});
