/**
 * <u> 태그 제거 스크립트
 *
 * Firestore documents 컬렉션의 특정 문서에서 <u> / </u> 태그를
 * 모두 제거합니다. 태그 사이의 텍스트는 그대로 보존됩니다.
 *
 * 대상 문서: documents/80ivTX4TSdnbPtC6X5ut (AI시대 영업의 품격 (260402))
 *
 * 사용법:
 *   npx ts-node scripts/strip-underline-tags.ts            # dry-run (기본값)
 *   npx ts-node scripts/strip-underline-tags.ts --dry-run  # dry-run (명시)
 *   npx ts-node scripts/strip-underline-tags.ts --fix      # 실제 수정 적용
 *
 * task-1349.2: <u> 태그 46쌍 제거
 * 생성일: 2026-04-02
 */

import * as admin from 'firebase-admin';
import * as path from 'path';
import * as fs from 'fs';

// ============================================================
// Firebase Admin 초기화
// ============================================================
if (!admin.apps.length) {
    const localKeyPath = path.resolve(__dirname, '../temp.j2h/insuwiki-j2h-902be7d0b6f5.json');
    if (fs.existsSync(localKeyPath)) {
        try {
            const serviceAccount = JSON.parse(fs.readFileSync(localKeyPath, 'utf8'));
            admin.initializeApp({
                credential: admin.credential.cert(serviceAccount),
                projectId: 'insuwiki-j2h',
            });
        } catch {
            admin.initializeApp();
            console.warn('서비스 계정 키 파싱 실패 — 기본 인증 사용');
        }
    } else {
        admin.initializeApp();
        console.log('서비스 계정 키 없음 — 기본 인증 사용 (gcloud auth)');
    }
}

const db = admin.firestore();

// ============================================================
// 상수
// ============================================================
const TARGET_COLLECTION = 'documents';
const TARGET_DOC_ID = '80ivTX4TSdnbPtC6X5ut';

// ============================================================
// <u> 태그 제거 함수
// ============================================================

/**
 * <u> 열림 / </u> 닫힘 태그 수를 셉니다. (대소문자 무시)
 */
function countUnderlineTags(content: string): { open: number; close: number } {
    const open = (content.match(/<u>/gi) ?? []).length;
    const close = (content.match(/<\/u>/gi) ?? []).length;
    return { open, close };
}

/**
 * content 문자열에서 <u> 와 </u> 태그를 모두 제거합니다.
 * 태그 사이의 텍스트는 보존합니다. (대소문자 무시)
 */
function stripUnderlineTags(content: string): string {
    // <u> 열림 태그 제거 (대소문자 무시)
    let result = content.replace(/<u>/gi, '');
    // </u> 닫힘 태그 제거 (대소문자 무시)
    result = result.replace(/<\/u>/gi, '');
    return result;
}

// ============================================================
// 변경된 줄만 보여주는 diff 출력
// ============================================================
function printLineDiff(before: string, after: string): void {
    const beforeLines = before.split('\n');
    const afterLines = after.split('\n');

    const maxLen = Math.max(beforeLines.length, afterLines.length);
    let changedLineCount = 0;

    for (let i = 0; i < maxLen; i++) {
        const b = beforeLines[i] ?? '';
        const a = afterLines[i] ?? '';
        if (b !== a) {
            changedLineCount++;
            // 줄이 너무 길면 앞부분만 표시
            const maxPreview = 120;
            const bPreview = b.length > maxPreview ? b.slice(0, maxPreview) + '…' : b;
            const aPreview = a.length > maxPreview ? a.slice(0, maxPreview) + '…' : a;
            console.log(`    L${i + 1} - ${JSON.stringify(bPreview)}`);
            console.log(`    L${i + 1} + ${JSON.stringify(aPreview)}`);
        }
    }

    if (changedLineCount === 0) {
        console.log(`    (변경된 줄 없음 — before/after 길이: ${before.length} → ${after.length})`);
    } else {
        console.log(`\n    총 변경 줄 수: ${changedLineCount}`);
    }
}

// ============================================================
// 메인
// ============================================================
async function main(dryRun: boolean): Promise<void> {
    const mode = dryRun ? 'DRY-RUN' : '실제 수정';

    console.log(`\n${'='.repeat(60)}`);
    console.log(`<u> 태그 제거 스크립트 — ${mode} 모드`);
    console.log(`대상 문서: ${TARGET_COLLECTION}/${TARGET_DOC_ID}`);
    console.log(`${'='.repeat(60)}\n`);

    // 문서 가져오기
    const docRef = db.collection(TARGET_COLLECTION).doc(TARGET_DOC_ID);
    const docSnap = await docRef.get();

    if (!docSnap.exists) {
        console.error(`오류: 문서 ${TARGET_COLLECTION}/${TARGET_DOC_ID} 를 찾을 수 없습니다.`);
        process.exit(1);
    }

    const data = docSnap.data()!;
    const content: unknown = data['content'];

    if (typeof content !== 'string') {
        console.error(`오류: content 필드가 문자열이 아닙니다. (타입: ${typeof content})`);
        process.exit(1);
    }

    // 태그 수 확인
    const { open, close } = countUnderlineTags(content);
    console.log(`문서 제목: ${data['title'] ?? '(없음)'}`);
    console.log(`content 길이: ${content.length}자`);
    console.log(`<u> 열림 태그: ${open}개`);
    console.log(`</u> 닫힘 태그: ${close}개`);
    console.log(`_content_backup 존재 여부: ${data['_content_backup'] !== undefined ? '있음' : '없음'}`);

    if (open === 0 && close === 0) {
        console.log('\n제거할 <u>/<u> 태그가 없습니다. 종료합니다.');
        return;
    }

    // 태그 제거
    const fixed = stripUnderlineTags(content);

    console.log(`\n변경 후 content 길이: ${fixed.length}자`);
    console.log(`제거된 문자 수: ${content.length - fixed.length}자`);

    // diff 출력 (변경된 줄만)
    console.log('\n[변경된 줄 diff]');
    printLineDiff(content, fixed);

    if (dryRun) {
        console.log(`\n${'='.repeat(60)}`);
        console.log('DRY-RUN 완료 — 실제 변경 없음');
        console.log('실제 수정을 적용하려면:');
        console.log('  npx ts-node scripts/strip-underline-tags.ts --fix');
        console.log(`${'='.repeat(60)}\n`);
        return;
    }

    // 실제 수정 적용
    await docRef.update({
        content: fixed,
        _content_backup: content,   // 원본 백업
        updatedAt: admin.firestore.FieldValue.serverTimestamp(),
    });

    console.log(`\n${'='.repeat(60)}`);
    console.log('수정 완료');
    console.log(`  * <u> 열림 태그 ${open}개, </u> 닫힘 태그 ${close}개 제거`);
    console.log('  * 원본 content는 _content_backup 필드에 백업되었습니다.');
    console.log(`${'='.repeat(60)}\n`);
}

// ============================================================
// 실행 진입점
// ============================================================
const args = process.argv.slice(2);
const isFix = args.includes('--fix');
const isDryRun = !isFix; // --fix 가 없으면 dry-run이 기본값

main(isDryRun)
    .then(() => process.exit(0))
    .catch(err => {
        console.error('\n스크립트 실패:', err);
        process.exit(1);
    });
