/**
 * ============================================================
 * 이메일 워처 (v2.2.271) — /email 을 안 쳐도 알아서 축적·추적·알림.
 *
 * 주기(기본 60분)마다:
 *   1. Outlook(+Gmail 연결 시) 최근 메일 증분 수집
 *   2. 주제별 스레드 묶음 → `.astra/email_state.json` 에 병합 (수집 창 밖
 *      미회신도 계속 보존 — GTD Waiting-For)
 *   3. 임계(기본 24h) 초과 미회신 전이 감지 → 텔레그램 1회 알림
 *      (매수시그널과 같은 전이 방식 — waitingSince 당 1회, 중복 없음)
 *
 * stocksWatcher 패턴 준수: 단계별 독립 try/catch, dispose 로 정리,
 * 설정 `g1nation.email.watcherEnabled` 로 on/off.
 * ============================================================
 */

import * as vscode from 'vscode';
import { logError, logInfo } from '../../utils';
import { TelegramHttpClient } from '../../integrations/telegram/telegramClient';
import { TELEGRAM_TOKEN_SECRET_KEY } from '../../extension/telegramCommands';
import { collectRecentMails } from './emailCollect';
import { groupThreads, isAutomated } from './emailBrief';
import { readEmailState, writeEmailState, syncThreads, detectOverdue, waitingHours, type ThreadState } from './emailState';

let _timer: NodeJS.Timeout | undefined;
let _disposed = false;
let _running = false;

function cfgNum(key: string, def: number): number {
    const v = vscode.workspace.getConfiguration('g1nation').get<number>(key, def);
    return Number.isFinite(v) ? (v as number) : def;
}

function pickChatId(): number | null {
    const cfg = vscode.workspace.getConfiguration('g1nation');
    const allowed = cfg.get<number[]>('telegram.allowedChatIds', []) || [];
    if (allowed.length > 0 && Number.isFinite(allowed[0]) && allowed[0] !== 0) return allowed[0];
    return null;
}

function fmtWaiting(t: ThreadState, now: Date): string {
    const h = waitingHours(t, now);
    return h >= 48 ? `${(h / 24).toFixed(1)}일째` : `${Math.round(h)}시간째`;
}

export function buildOverdueAlertText(overdue: ThreadState[], thresholdHours: number, now: Date = new Date()): string {
    // v2.2.284: 중앙 포맷(messageFormat.renderTelegram) — 모든 텔레그램 메시지 포맷 통일.
    const { renderTelegram, tgWho, tgSubject } = require('../../integrations/telegram/messageFormat') as typeof import('../../integrations/telegram/messageFormat');
    return renderTelegram({
        emoji: '📧', title: `미회신 ${thresholdHours}h 초과`, count: overdue.length,
        sections: [{
            count: overdue.length,
            maxItems: 5,
            items: overdue.map(t => ({
                main: tgSubject(t.subject),
                sub: `${tgWho(t.participants[0] || '-')} · ${fmtWaiting(t, now)}${t.hasUnread ? ' · 🔵' : ''}`,
            })),
        }],
        footer: '처리했으면 `/email done O번호`',
    });
}

async function sendOverdueAlert(context: vscode.ExtensionContext, overdue: ThreadState[], thresholdHours: number): Promise<void> {
    const chatId = pickChatId();
    if (chatId === null) { logInfo('Email watcher: 텔레그램 chatId 미설정 — 알림 skip.'); return; }
    const token = (await context.secrets.get(TELEGRAM_TOKEN_SECRET_KEY)) || '';
    if (!token.trim()) { logInfo('Email watcher: 텔레그램 토큰 없음 — 알림 skip.'); return; }
    const client = new TelegramHttpClient({ getToken: () => token });
    try {
        await client.sendMessage({ chatId, text: buildOverdueAlertText(overdue, thresholdHours), parseMode: 'Markdown' });
        logInfo('Email watcher: 미회신 알림 발송.', { count: overdue.length });
    } catch (e: any) {
        logError('Email watcher: 알림 발송 실패.', { error: e?.message ?? String(e) });
    }
}

/** 한 사이클 — 수집 → 상태 병합 → 임계 초과 알림. 수동 실행(/email 등)과 공유 가능. */
export async function emailWatcherFireOnce(context: vscode.ExtensionContext): Promise<void> {
    if (_running) return; // 수집 겹침 방지 (COM/네트워크 느릴 때)
    _running = true;
    try {
        const days = Math.max(1, Math.min(30, cfgNum('email.syncDays', 7)));
        const collected = await collectRecentMails(days, context, { gmailThreads: 12 });
        if (collected.outlookError && collected.inbox.length === 0) {
            logInfo('Email watcher: 수집 실패 — skip.', { outlook: collected.outlookError, gmail: collected.gmailError });
            return;
        }
        const threads = groupThreads(collected.inbox, collected.sent);
        const store = syncThreads(readEmailState(), threads);

        // v2.2.283: 기본 0(끔) — 미회신 정리는 09:30 데일리 브리핑이 담당 (하루 1회, 정돈된 형식).
        // 즉시 알림을 원할 때만 시간(예: 24) 설정.
        const threshold = cfgNum('email.overdueAlertHours', 0);
        const overdue = detectOverdue(store, threshold)
            // 자동발신 재필터 — 필터 규칙이 갱신돼도 과거 상태의 낡은 automated 플래그에 안 속게.
            .filter(t => !t.ccOnly && !isAutomated(t.participants[0] || '', t.subject));
        writeEmailState(store);
        logInfo('Email watcher: 사이클 완료.', {
            observed: threads.length, stored: store.threads.length, overdue: overdue.length,
        });
        if (overdue.length > 0) await sendOverdueAlert(context, overdue, threshold);
    } catch (e: any) {
        logError('Email watcher: 사이클 예외.', { error: e?.message ?? String(e) });
    } finally {
        _running = false;
    }
}

function scheduleNext(context: vscode.ExtensionContext, first: boolean): void {
    if (_disposed) return;
    const intervalMin = Math.max(10, Math.min(24 * 60, cfgNum('email.watchIntervalMinutes', 60)));
    // 첫 실행은 기동 3분 뒤 (VS Code 시작 직후 부하 회피), 이후 설정 주기.
    const ms = first ? 3 * 60_000 : intervalMin * 60_000;
    _timer = setTimeout(async () => {
        await emailWatcherFireOnce(context);
        scheduleNext(context, false);
    }, ms);
}

export function startEmailWatcher(context: vscode.ExtensionContext): vscode.Disposable {
    const enabled = vscode.workspace.getConfiguration('g1nation').get<boolean>('email.watcherEnabled', true);
    if (!enabled) {
        logInfo('Email watcher: 비활성 (g1nation.email.watcherEnabled=false).');
        return { dispose: () => {} };
    }
    _disposed = false;
    scheduleNext(context, true);
    logInfo('Email watcher: 시작됨.');
    return {
        dispose: () => {
            _disposed = true;
            if (_timer) { clearTimeout(_timer); _timer = undefined; }
        },
    };
}
