import { Router } from 'express';
import axios from 'axios';
import { validateToken } from '../middleware/auth.js';
import { getAiConfigService } from '../services/cc-switch-sdk.js';
import { buildToolSpecificAiConfig, } from '@cc-switch/sdk';
import { createLogger } from '../utils/logger.js';
const log = createLogger('ai-sources');
export const aiSourcesRouter = Router();
function normalizeListedModels(payload) {
    if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
        return [];
    }
    const payloadRecord = payload;
    const data = Array.isArray(payloadRecord.data) ? payloadRecord.data : [];
    const ids = new Set();
    for (const item of data) {
        if (!item || typeof item !== 'object' || Array.isArray(item)) {
            continue;
        }
        const id = String(item.id || '').trim();
        if (id) {
            ids.add(id);
        }
    }
    return [...ids];
}
async function fetchRemoteModelList(baseUrl, apiKey) {
    const normalizedBaseUrl = baseUrl.replace(/\/+$/, '');
    const openAiCandidates = normalizedBaseUrl.endsWith('/v1')
        ? [`${normalizedBaseUrl}/models`]
        : [`${normalizedBaseUrl}/models`, `${normalizedBaseUrl}/v1/models`];
    for (const candidate of openAiCandidates) {
        try {
            const response = await axios.get(candidate, {
                headers: {
                    Authorization: `Bearer ${apiKey}`,
                },
                timeout: 10000,
            });
            const models = normalizeListedModels(response.data);
            if (models.length > 0) {
                return models;
            }
        }
        catch {
            // continue probing next compatible endpoint
        }
    }
    const anthropicCandidate = `${normalizedBaseUrl.endsWith('/v1') ? normalizedBaseUrl : `${normalizedBaseUrl}/v1`}/models`;
    const anthropicResponse = await axios.get(anthropicCandidate, {
        headers: {
            'x-api-key': apiKey,
            'anthropic-version': '2023-06-01',
        },
        timeout: 10000,
    });
    return normalizeListedModels(anthropicResponse.data);
}
aiSourcesRouter.post('/cc-switch/apply-ai-sources', validateToken, async (req, res) => {
    const { agentId, template, claudecodeTemplateId, codexTemplateId, opencodeTemplateId, claudecode, codex, opencode, } = req.body || {};
    if (!agentId) {
        res.status(400).json({ error: 'agentId is required' });
        return;
    }
    try {
        const aiConfigService = getAiConfigService();
        const generatedConfig = template ? buildToolSpecificAiConfig({
            baseUrl: String(template?.baseUrl || ''),
            apiKey: String(template?.apiKey || ''),
            model: String(template?.model || ''),
            models: Array.isArray(template?.models)
                ? template.models.map((item) => String(item || '').trim()).filter(Boolean)
                : undefined,
        }) : null;
        const claudeSource = generatedConfig?.claudecode || claudecode;
        const codexSource = generatedConfig?.codex || codex;
        const opencodeSource = generatedConfig?.opencode || opencode;
        let mergedClaude = null;
        let mergedCodex = null;
        let mergedOpencode = null;
        if (claudeSource && typeof claudeSource === 'object') {
            mergedClaude = await aiConfigService.applyClaudeCodeConfig(claudeSource);
        }
        if (codexSource && typeof codexSource === 'object') {
            mergedCodex = await aiConfigService.applyCodexConfig(codexSource);
        }
        if (opencodeSource && typeof opencodeSource === 'object') {
            mergedOpencode = await aiConfigService.applyOpenCodeConfig(opencodeSource);
        }
        res.json({
            ok: true,
            agentId: String(agentId),
            claudecodeTemplateId: String(claudecodeTemplateId || ''),
            codexTemplateId: String(codexTemplateId || ''),
            opencodeTemplateId: String(opencodeTemplateId || ''),
            generatedFromUnifiedTemplate: Boolean(generatedConfig),
            applied: {
                claudecode: claudeSource && typeof claudeSource === 'object' ? Object.keys(claudeSource) : [],
                codex: codexSource && typeof codexSource === 'object' ? Object.keys(codexSource) : [],
                opencode: opencodeSource && typeof opencodeSource === 'object' ? Object.keys(opencodeSource) : [],
            },
        });
    }
    catch (error) {
        const err = error;
        log.error('Failed to apply AI sources', {
            error: err?.message,
            agentId: String(agentId || ''),
        });
        res.status(400).json({ error: err?.message || 'apply ai sources failed' });
    }
});
aiSourcesRouter.post('/cc-switch/list-ai-models', validateToken, async (req, res) => {
    const { baseUrl, apiKey } = req.body || {};
    const normalizedBaseUrl = String(baseUrl || '').trim();
    const normalizedApiKey = String(apiKey || '').trim();
    if (!normalizedBaseUrl || !normalizedApiKey) {
        res.status(400).json({ error: 'baseUrl and apiKey are required' });
        return;
    }
    try {
        const models = await fetchRemoteModelList(normalizedBaseUrl, normalizedApiKey);
        res.json({
            ok: true,
            models,
        });
    }
    catch (error) {
        const err = error;
        log.error('Failed to list remote AI models', {
            error: err?.message,
            baseUrl: normalizedBaseUrl,
        });
        res.status(400).json({ error: err?.message || 'list ai models failed' });
    }
});
