import * as vscode from 'vscode';
import type { TelegramBot } from '../integrations/telegram/telegramBot';
import type { TelegramHttpClient } from '../integrations/telegram/telegramClient';

/** SecretStorage key for the bot token. Shared with Settings panel listener. */
export const TELEGRAM_TOKEN_SECRET_KEY = 'g1nation.telegram.botToken';

/**
 * Single-element token cache shared by extension.ts and this module.
 *
 * `telegramClient` is constructed with `getToken: () => tokenStore.current`,
 * so when this module updates `tokenStore.current` in response to a secrets
 * change the client picks up the new value on its next HTTP call — no need
 * to rebuild the client.
 */
export interface TelegramTokenStore { current: string }

export interface TelegramCommandsDeps {
    telegramBot: TelegramBot;
    telegramClient: TelegramHttpClient;
    tokenStore: TelegramTokenStore;
}

/**
 * Telegram bot 라이프사이클 + 명령 묶음. activate() 안에 inline 으로 있던 58줄
 * (refresh helper + dispose hook + 2 listener + 3 command) 을 한 모듈로 모음.
 *
 * 반환된 disposable 들은 호출자가 `context.subscriptions.push(...)` 로 등록.
 *
 *   - refreshTelegramBot()           — config `telegram.enabled` + token 둘 다 있을 때만 start
 *   - dispose hook                   — 확장 종료 시 bot 정지
 *   - config change listener         — `telegram.enabled` 토글 → refresh
 *   - secrets change listener        — 토큰 외부 변경 → cache 갱신 + refresh
 *   - g1nation.telegram.setBotToken  — InputBox 로 토큰 등록
 *   - g1nation.telegram.clearBotToken
 *   - g1nation.telegram.testConnection — `getMe` 호출로 토큰 유효성 확인
 */
export function registerTelegramCommands(
    context: vscode.ExtensionContext,
    deps: TelegramCommandsDeps,
): vscode.Disposable[] {
    const { telegramBot, telegramClient, tokenStore } = deps;

    const refreshTelegramBot = async () => {
        const enabled = vscode.workspace.getConfiguration('g1nation').get<boolean>('telegram.enabled', false);
        const tokenPresent = !!tokenStore.current.trim();
        if (enabled && tokenPresent) {
            telegramBot.start();
        } else if (telegramBot.isRunning()) {
            await telegramBot.stop();
        }
    };
    void refreshTelegramBot();

    return [
        { dispose: () => { void telegramBot.stop(); } },
        vscode.workspace.onDidChangeConfiguration(async (e) => {
            if (e.affectsConfiguration('g1nation.telegram.enabled')) {
                await refreshTelegramBot();
            }
        }),
        context.secrets.onDidChange(async (e) => {
            if (e.key !== TELEGRAM_TOKEN_SECRET_KEY) return;
            tokenStore.current = (await context.secrets.get(TELEGRAM_TOKEN_SECRET_KEY)) || '';
            await refreshTelegramBot();
        }),
        vscode.commands.registerCommand('g1nation.telegram.setBotToken', async () => {
            const token = await vscode.window.showInputBox({
                prompt: 'Telegram bot token (BotFather에서 발급, 형식: 123456:ABC...)',
                placeHolder: '123456789:AA...',
                password: true,
                ignoreFocusOut: true,
                validateInput: (v) => /^\d+:[A-Za-z0-9_-]{20,}$/.test((v || '').trim())
                    ? null
                    : '형식이 올바르지 않습니다 (숫자ID:문자열).',
            });
            if (!token) return;
            await context.secrets.store(TELEGRAM_TOKEN_SECRET_KEY, token.trim());
            vscode.window.showInformationMessage(
                'Telegram bot token이 저장되었습니다. settings에서 g1nation.telegram.enabled = true 로 켜세요.'
            );
        }),
        vscode.commands.registerCommand('g1nation.telegram.clearBotToken', async () => {
            await context.secrets.delete(TELEGRAM_TOKEN_SECRET_KEY);
            vscode.window.showInformationMessage('Telegram bot token이 삭제되었습니다.');
        }),
        vscode.commands.registerCommand('g1nation.telegram.testConnection', async () => {
            const token = (await context.secrets.get(TELEGRAM_TOKEN_SECRET_KEY)) || '';
            if (!token) {
                vscode.window.showErrorMessage('먼저 "Astra: Set Telegram Bot Token" 명령으로 토큰을 등록하세요.');
                return;
            }
            try {
                const me = await telegramClient.getMe();
                vscode.window.showInformationMessage(
                    `Telegram 연결 성공: @${me.username || me.first_name} (id ${me.id})`
                );
            } catch (e: any) {
                vscode.window.showErrorMessage(`Telegram 연결 실패: ${e?.message ?? e}`);
            }
        }),
    ];
}
