import * as vscode from 'vscode';
import { TelegramHttpClient } from '../../integrations/telegram/telegramClient';
import { TELEGRAM_TOKEN_SECRET_KEY } from '../../extension/telegramCommands';
import { logError, logInfo } from '../../utils';
import { readStocksStore } from './stocksStore';
import { classifyAll } from './signalClassifier';
import type { ClassifiedStock } from './types';

/**
 * 09:00 / 15:00 KST 정기 보고서 — Telegram 으로 발송.
 *
 * 사용자 결정 (q2=A): chatId 는 `g1nation.telegram.allowedChatIds[0]` 자동 사용.
 * 없으면 fallback 으로 `g1nation.stocks.telegramChatId` 별도 설정. 둘 다 없으면 skip + 로그.
 * 토큰은 telegramCommands 의 SecretStorage 키와 공유.
 */

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

/** 한 카테고리 (스윙/장기/저평가) 의 종목 리스트를 텔레그램 Markdown 으로 렌더. */
function renderGroup(label: string, stocks: ClassifiedStock[]): string[] {
    const buyZone = stocks.filter(s => s.signal === 'BUY_ZONE');
    const overvalued = stocks.filter(s => s.signal === 'OVERVALUED');
    const hold = stocks.filter(s => s.signal === 'HOLD');

    const lines: string[] = [`*${label}* (총 ${stocks.length}개)`];
    if (buyZone.length > 0) {
        lines.push(`🚨 매수사정권 (${buyZone.length})`);
        for (const s of buyZone) {
            const cur = s.현재가 ? s.현재가.toLocaleString() : '?';
            lines.push(`  · ${s.이름} (${s.심볼}): ${cur} / 권장 ${s.매수권장가 ?? '-'}`);
        }
    }
    if (overvalued.length > 0) {
        lines.push(`⚠️ 가격 조정 감시 (${overvalued.length})`);
        for (const s of overvalued) {
            const cur = s.현재가 ? s.현재가.toLocaleString() : '?';
            lines.push(`  · ${s.이름} (${s.심볼}): ${cur} / 권장 ${s.매수권장가 ?? '-'}`);
        }
    }
    if (hold.length > 0 && buyZone.length === 0 && overvalued.length === 0) {
        // 모두 관망일 때만 그 카운트만 표시 — 종목 일일이 안 나열 (보고서 길이 절약).
        lines.push(`📊 관망 ${hold.length}건`);
    } else if (hold.length > 0) {
        lines.push(`📊 관망 ${hold.length}건 (생략)`);
    }
    return lines;
}

/** 보고서 텍스트 생성 (전송과 분리 — 테스트·로그용). */
export function buildReportText(now: Date = new Date()): string {
    const store = readStocksStore();
    if (store.length === 0) {
        return '⚠️ stocks.json 에 종목 없음 — `/stocks add <심볼> <이름>` 으로 추가하세요.';
    }
    const g = classifyAll(store);
    const kstStr = formatKstTimestamp(now);

    const out: string[] = [`🦅 *Kodari 정기 보고서*  _${kstStr}_`, ''];
    out.push(...renderGroup('스윙/중기', g.swing), '');
    out.push(...renderGroup('장기투자', g.long), '');
    out.push(...renderGroup('저평가우량주', g.ultraLow));

    return out.join('\n');
}

/** Date → "2026-05-25 09:00 KST" 형식. */
function formatKstTimestamp(d: Date): string {
    const fmt = new Intl.DateTimeFormat('ko-KR', {
        timeZone: 'Asia/Seoul',
        year: 'numeric', month: '2-digit', day: '2-digit',
        hour: '2-digit', minute: '2-digit', hour12: false,
    });
    const parts = fmt.formatToParts(d);
    const get = (t: string) => parts.find(p => p.type === t)?.value || '';
    return `${get('year')}-${get('month')}-${get('day')} ${get('hour')}:${get('minute')} KST`;
}

/**
 * 보고서를 텔레그램으로 전송. 토큰 없거나 chatId 없으면 silent skip (warn 로그).
 *
 * 성공/실패 모두 caller (watcher / slash 명령) 가 알 수 있도록 결과 반환.
 */
export async function sendStocksReport(
    context: vscode.ExtensionContext,
): Promise<{ ok: boolean; reason?: string }> {
    const chatId = pickChatId();
    if (chatId === null) {
        const reason = '텔레그램 chatId 미설정 (g1nation.telegram.allowedChatIds 또는 g1nation.stocks.telegramChatId).';
        logInfo(`Stocks report skip: ${reason}`);
        return { ok: false, reason };
    }

    const token = (await context.secrets.get(TELEGRAM_TOKEN_SECRET_KEY)) || '';
    if (!token.trim()) {
        const reason = '텔레그램 봇 토큰 없음 — `Astra: Set Telegram Bot Token` 으로 등록.';
        logInfo(`Stocks report skip: ${reason}`);
        return { ok: false, reason };
    }

    const text = buildReportText();
    const client = new TelegramHttpClient({ getToken: () => token });
    try {
        await client.sendMessage({ chatId, text, parseMode: 'Markdown' });
        logInfo('Stocks report 발송 완료.', { chatId, chars: text.length });
        return { ok: true };
    } catch (e: any) {
        logError('Stocks report 발송 실패.', { chatId, error: e?.message ?? String(e) });
        return { ok: false, reason: e?.message ?? String(e) };
    }
}
