"use strict";
/**
 * Model Configuration - Interactive model selection for CLI Proxy providers
 *
 * Handles first-run configuration and explicit --config flag.
 * Persists user selection to ~/.ccs/{provider}.settings.json
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.showCurrentConfig = exports.configureProviderModel = exports.getCurrentModel = exports.hasUserSettings = void 0;
const fs = __importStar(require("fs"));
const os = __importStar(require("os"));
const prompt_1 = require("../../utils/prompt");
const model_catalog_1 = require("../model-catalog");
const config_generator_1 = require("./config-generator");
const ui_1 = require("../../utils/ui");
const model_id_normalizer_1 = require("../ai-providers/model-id-normalizer");
const config_loader_facade_1 = require("../../config/config-loader-facade");
function canonicalizeModelForProvider(provider, model) {
    return (0, model_id_normalizer_1.normalizeModelIdForProvider)(model, provider);
}
/**
 * Check if provider has user settings configured
 */
function hasUserSettings(provider) {
    const settingsPath = (0, config_generator_1.resolveProviderSettingsPath)(provider);
    return fs.existsSync(settingsPath);
}
exports.hasUserSettings = hasUserSettings;
/**
 * Get current model from user settings
 * @param provider CLIProxy provider
 * @param customSettingsPath Optional custom settings path for CLIProxy variants
 */
function getCurrentModel(provider, customSettingsPath) {
    const settingsPath = customSettingsPath
        ? customSettingsPath.replace(/^~/, os.homedir())
        : (0, config_generator_1.resolveProviderSettingsPath)(provider);
    if (!fs.existsSync(settingsPath))
        return undefined;
    try {
        const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
        const model = settings.env?.ANTHROPIC_MODEL;
        return typeof model === 'string' ? canonicalizeModelForProvider(provider, model) : model;
    }
    catch {
        return undefined;
    }
}
exports.getCurrentModel = getCurrentModel;
/**
 * Format model entry for display in selection list
 */
function formatModelOption(model) {
    // Tier badge: ultra/pro indicate paid tiers
    const tierBadge = model.tier === 'ultra'
        ? (0, ui_1.color)(' [Ultra]', 'warning')
        : model.tier === 'pro'
            ? (0, ui_1.color)(' [Pro]', 'warning')
            : '';
    const brokenBadge = model.broken ? (0, ui_1.color)(' [BROKEN]', 'error') : '';
    const deprecatedBadge = model.deprecated ? (0, ui_1.color)(' [DEPRECATED]', 'warning') : '';
    return `${model.name}${tierBadge}${brokenBadge}${deprecatedBadge}`;
}
/**
 * Format model entry for detailed display (with description)
 */
function formatModelDetailed(model, isCurrent) {
    const marker = isCurrent ? (0, ui_1.color)('>', 'success') : ' ';
    const name = isCurrent ? (0, ui_1.bold)(model.name) : model.name;
    const tierBadge = model.tier === 'ultra'
        ? (0, ui_1.color)(' [Ultra]', 'warning')
        : model.tier === 'pro'
            ? (0, ui_1.color)(' [Pro]', 'warning')
            : '';
    const brokenBadge = model.broken ? (0, ui_1.color)(' [BROKEN]', 'error') : '';
    const deprecatedBadge = model.deprecated ? (0, ui_1.color)(' [DEPRECATED]', 'warning') : '';
    const desc = model.description ? (0, ui_1.dim)(` - ${model.description}`) : '';
    return `  ${marker} ${name}${tierBadge}${brokenBadge}${deprecatedBadge}${desc}`;
}
/**
 * Configure model for provider (interactive)
 *
 * @param provider CLIProxy provider (agy, gemini)
 * @param force Force reconfiguration even if settings exist
 * @param customSettingsPath Optional custom settings path for CLIProxy variants
 * @returns true if configuration was performed, false if skipped
 */
async function configureProviderModel(provider, force = false, customSettingsPath) {
    // Check if provider supports model configuration
    if (!(0, model_catalog_1.supportsModelConfig)(provider)) {
        return false;
    }
    const catalog = (0, model_catalog_1.getProviderCatalog)(provider);
    if (!catalog)
        return false;
    // Use custom settings path for CLIProxy variants, otherwise use default provider path
    const settingsPath = customSettingsPath
        ? customSettingsPath.replace(/^~/, os.homedir())
        : (0, config_generator_1.resolveProviderSettingsPath)(provider);
    // Skip if already configured with a model (unless --config flag).
    // A settings file can exist without model env keys (e.g., hook-only writes).
    if (!force && getCurrentModel(provider, customSettingsPath)?.trim()) {
        return false;
    }
    // Initialize UI for colors/gradient
    await (0, ui_1.initUI)();
    // Build options list
    const options = catalog.models.map((m) => ({
        id: m.id,
        label: formatModelOption(m),
    }));
    // Find default index - use current model if configured, otherwise catalog default
    const currentModel = getCurrentModel(provider, customSettingsPath);
    const targetModel = currentModel
        ? canonicalizeModelForProvider(provider, currentModel)
        : catalog.defaultModel;
    const defaultIdx = catalog.models.findIndex((m) => m.id === targetModel);
    const safeDefaultIdx = defaultIdx >= 0 ? defaultIdx : 0;
    // Show header with context (gradient like ccs doctor)
    console.error('');
    console.error((0, ui_1.header)(`Configure ${catalog.displayName} Model`));
    console.error('');
    console.error((0, ui_1.dim)('    Select which model to use for this provider.'));
    console.error((0, ui_1.dim)('    Models marked [Pro]/[Ultra] require a paid provider plan.'));
    console.error((0, ui_1.dim)('    Models marked [DEPRECATED] are not recommended for use.'));
    console.error('');
    // Interactive selection
    const selectedModel = await prompt_1.InteractivePrompt.selectFromList('Select model:', options, {
        defaultIndex: safeDefaultIdx,
    });
    // Get base env vars for defaults
    const baseEnv = (0, config_generator_1.getClaudeEnvVars)(provider);
    const selectedDefaultModel = canonicalizeModelForProvider(provider, selectedModel);
    const selectedOpusModel = canonicalizeModelForProvider(provider, selectedModel);
    const selectedSonnetModel = canonicalizeModelForProvider(provider, selectedModel);
    const selectedHaikuModel = canonicalizeModelForProvider(provider, baseEnv.ANTHROPIC_DEFAULT_HAIKU_MODEL || selectedModel);
    // Read existing settings to preserve user customizations
    let existingSettings = {};
    let existingEnv = {};
    if (fs.existsSync(settingsPath)) {
        try {
            existingSettings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
            existingEnv = existingSettings.env || {};
        }
        catch {
            // Invalid JSON - start fresh
        }
    }
    // Build settings with selective merge:
    // - Preserve ALL user settings (top-level and env vars)
    // - Only update CCS-controlled fields (model selection)
    // CCS-controlled env vars (always override with our values)
    const ccsControlledEnv = {
        ANTHROPIC_BASE_URL: baseEnv.ANTHROPIC_BASE_URL || '',
        ANTHROPIC_AUTH_TOKEN: baseEnv.ANTHROPIC_AUTH_TOKEN || '',
        ANTHROPIC_MODEL: selectedDefaultModel,
        ANTHROPIC_DEFAULT_OPUS_MODEL: selectedOpusModel,
        ANTHROPIC_DEFAULT_SONNET_MODEL: selectedSonnetModel,
        ANTHROPIC_DEFAULT_HAIKU_MODEL: selectedHaikuModel,
    };
    // Merge: user env vars (preserved) + CCS controlled (override)
    const mergedEnv = {
        ...existingEnv,
        ...ccsControlledEnv,
    };
    // Build final settings: preserve user top-level settings + update env
    const settings = {
        ...existingSettings,
        env: mergedEnv,
    };
    // Ensure CCS directory exists
    const ccsDir = (0, config_loader_facade_1.getCcsDir)();
    if (!fs.existsSync(ccsDir)) {
        fs.mkdirSync(ccsDir, { recursive: true });
    }
    // Write settings file
    fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
    // Find display name
    const selectedEntry = catalog.models.find((m) => m.id === selectedModel);
    const displayName = selectedEntry?.name || selectedModel;
    console.error('');
    console.error((0, ui_1.ok)(`Model set to: ${(0, ui_1.bold)(displayName)}`));
    console.error((0, ui_1.dim)(`     Config saved: ${settingsPath}`));
    // Show deprecation warning if model is deprecated
    if (selectedEntry?.deprecated) {
        console.error('');
        console.error((0, ui_1.color)('[!] DEPRECATION WARNING', 'warning'));
        const reason = selectedEntry.deprecationReason || 'This model is deprecated';
        console.error((0, ui_1.dim)(`     ${reason}`));
        console.error((0, ui_1.dim)('     Consider using a non-deprecated model for better compatibility.'));
    }
    console.error('');
    return true;
}
exports.configureProviderModel = configureProviderModel;
/**
 * Show current model configuration
 */
async function showCurrentConfig(provider) {
    if (!(0, model_catalog_1.supportsModelConfig)(provider)) {
        console.error((0, ui_1.info)(`Provider ${provider} does not support model configuration`));
        return;
    }
    const catalog = (0, model_catalog_1.getProviderCatalog)(provider);
    if (!catalog)
        return;
    // Initialize UI for colors/gradient
    await (0, ui_1.initUI)();
    const currentModel = getCurrentModel(provider);
    const settingsPath = (0, config_generator_1.resolveProviderSettingsPath)(provider);
    const normalizedCurrentModel = currentModel
        ? canonicalizeModelForProvider(provider, currentModel)
        : undefined;
    console.error('');
    console.error((0, ui_1.header)(`${catalog.displayName} Model Configuration`));
    console.error('');
    if (currentModel) {
        const entry = catalog.models.find((m) => m.id === normalizedCurrentModel);
        const displayName = entry?.name || 'Unknown';
        console.error(`  ${(0, ui_1.bold)('Current:')} ${(0, ui_1.color)(displayName, 'success')} ${(0, ui_1.dim)(`(${currentModel})`)}`);
        console.error(`  ${(0, ui_1.bold)('Config:')}  ${(0, ui_1.dim)(settingsPath)}`);
    }
    else {
        console.error(`  ${(0, ui_1.bold)('Current:')} ${(0, ui_1.dim)('(using defaults)')}`);
        console.error(`  ${(0, ui_1.bold)('Default:')} ${catalog.defaultModel}`);
    }
    console.error('');
    console.error((0, ui_1.bold)('Available models:'));
    console.error((0, ui_1.dim)('  [Pro]/[Ultra] = Requires a paid provider plan'));
    console.error((0, ui_1.dim)('  [DEPRECATED] = Not recommended for use'));
    console.error('');
    catalog.models.forEach((m) => {
        const isCurrent = m.id === normalizedCurrentModel;
        console.error(formatModelDetailed(m, isCurrent));
    });
    console.error('');
    console.error((0, ui_1.dim)(`Run "ccs ${provider} --config" to change`));
    console.error('');
}
exports.showCurrentConfig = showCurrentConfig;
//# sourceMappingURL=model-config.js.map