import * as path from 'path';
import ora from 'ora';
import { success, info } from '../utils/logger.js';
import { outputSuccess, outputError, isPrettyMode } from '../utils/output.js';
import { addEnhancedHelp } from '../utils/helpText.js';
import { getConfigValue } from '../services/config.js';
import { GenerationApiClient, GenerationApiError, imageToBase64DataUrl, downloadResult, } from '../services/generation-api.js';
export function registerTryonCommand(program) {
    const cmd = program
        .command('tryon')
        .description('虚拟试穿 (Virtual Try-On) - 使用 FASHN AI tryon-v1.6')
        .argument('<model_image>', '人物照片路径或 URL')
        .argument('<garment_image>', '服装照片路径或 URL')
        .option('-o, --output <path>', '输出文件路径', '')
        .option('-c, --category <type>', '服装类别: auto, tops, bottoms, one-pieces', 'auto')
        .option('-m, --mode <mode>', '生成模式: performance (~7s), balanced (~9s), quality (~13s)', 'quality')
        .option('--garment-type <type>', '服装照片类型: auto, flat-lay, model', 'auto')
        .option('-n, --num-samples <n>', '生成数量 (1-4)', '1')
        .option('--format <fmt>', '输出格式: png, jpeg', 'png')
        .option('--seed <n>', '随机种子（用于复现）')
        .action(async (modelImage, garmentImage, options) => {
        const pretty = isPrettyMode(options);
        try {
            // 处理图像输入：本地文件转 base64，URL 直接使用
            const resolveImage = async (input) => {
                if (input.startsWith('http://') || input.startsWith('https://')) {
                    return input;
                }
                return imageToBase64DataUrl(input);
            };
            const [modelImg, garmentImg] = await Promise.all([
                resolveImage(modelImage),
                resolveImage(garmentImage),
            ]);
            const numSamples = parseInt(options.numSamples, 10);
            const outputDir = getConfigValue('outputDir') || './gen-output';
            const params = {
                model_image: modelImg,
                garment_image: garmentImg,
                category: options.category,
                mode: options.mode,
                garment_photo_type: options.garmentType,
                num_samples: numSamples,
                output_format: options.format,
                seed: options.seed ? parseInt(options.seed, 10) : undefined,
            };
            const client = new GenerationApiClient();
            const startTime = Date.now();
            if (pretty) {
                const spinner = ora(`正在提交虚拟试穿任务 (${options.mode} 模式)...`).start();
                try {
                    const result = await client.submitAndPoll('tryon', params, {
                        onProgress: (status) => {
                            spinner.text = `虚拟试穿中 (${status})...`;
                        },
                    });
                    if (result.status === 'completed' && result.result_url) {
                        spinner.text = '正在下载结果图像...';
                        // result_url 可能是单个 URL 或 result_meta 里有多个
                        const outputs = [];
                        const urls = result.result_meta?.output_urls || [result.result_url];
                        const ts = Date.now();
                        for (let i = 0; i < urls.length; i++) {
                            const outputPath = options.output && urls.length === 1
                                ? path.resolve(options.output)
                                : path.resolve(outputDir, `tryon_${ts}_${i}.${options.format}`);
                            const dir = path.dirname(outputPath);
                            const filename = path.basename(outputPath);
                            const saved = await downloadResult(urls[i], dir, filename);
                            outputs.push(saved);
                        }
                        const durationMs = Date.now() - startTime;
                        spinner.succeed('虚拟试穿完成！');
                        for (const out of outputs) {
                            success(`输出文件: ${out}`);
                        }
                        info(`模式: ${options.mode}, 类别: ${options.category}, 耗时: ${(durationMs / 1000).toFixed(1)}s`);
                    }
                    else {
                        spinner.info(`任务状态: ${result.status}`);
                        if (result.error_message)
                            info(`错误: ${result.error_message}`);
                        info(`使用 'gen task get ${result.task_id}' 查看最新状态`);
                    }
                }
                catch (err) {
                    spinner.fail(`试穿失败: ${err?.message || err}`);
                    throw err;
                }
            }
            else {
                const result = await client.submitAndPoll('tryon', params);
                if (result.status === 'completed' && result.result_url) {
                    const outputs = [];
                    const urls = result.result_meta?.output_urls || [result.result_url];
                    const ts = Date.now();
                    for (let i = 0; i < urls.length; i++) {
                        const outputPath = options.output && urls.length === 1
                            ? path.resolve(options.output)
                            : path.resolve(outputDir, `tryon_${ts}_${i}.${options.format}`);
                        const dir = path.dirname(outputPath);
                        const filename = path.basename(outputPath);
                        const saved = await downloadResult(urls[i], dir, filename);
                        outputs.push(saved);
                    }
                    const durationMs = Date.now() - startTime;
                    outputSuccess({
                        task_id: result.task_id,
                        outputs,
                        mode: options.mode,
                        category: options.category,
                        numSamples,
                        durationMs,
                    });
                }
                else {
                    // task status != completed → 失败。outputError 让顶层 success:false 并 exit 1，
                    // 否则 Agent 把 failure 当 success（参见 image.ts 同样修复）。
                    const errCode = result.error_code ?? 'GENERATION_FAILED';
                    const errMsg = result.error_message ?? `任务状态: ${result.status}`;
                    outputError(errCode, errMsg, options, {
                        task_id: result.task_id,
                        status: result.status,
                        retryable: result.retryable ?? false,
                        error_class: result.error_class ?? null,
                    });
                }
            }
        }
        catch (err) {
            if (err instanceof GenerationApiError) {
                outputError(err.code, err.message, options);
            }
            else {
                outputError('TRYON_FAILED', `虚拟试穿失败: ${err}`, options);
            }
        }
    });
    addEnhancedHelp(cmd, {
        examples: [
            '# 基本用法 - 本地图片试穿',
            '$ gen tryon person.jpg garment.jpg',
            '',
            '# 使用 URL 图片',
            '$ gen tryon https://example.com/model.jpg https://example.com/dress.jpg',
            '',
            '# 指定服装类别和生成模式',
            '$ gen tryon person.jpg top.jpg -c tops -m performance',
            '',
            '# 生成多张结果',
            '$ gen tryon person.jpg dress.jpg -n 4 -c one-pieces',
            '',
            '# 指定输出路径',
            '$ gen tryon person.jpg garment.jpg -o result.png',
            '',
            '# 使用种子复现结果',
            '$ gen tryon person.jpg garment.jpg --seed 42',
        ],
        outputJson: `{
  "success": true,
  "data": {
    "task_id": "abc123",
    "outputs": ["./gen-output/tryon_1234567890_0.png"],
    "mode": "quality",
    "category": "auto",
    "numSamples": 1,
    "durationMs": 13000
  }
}`,
        relatedCommands: [
            { command: 'image <prompt>', description: '文本生成图像' },
            { command: 'task get <id>', description: '查看任务状态' },
        ],
        notes: [
            '通过 optima-generation 调用 FASHN AI tryon-v1.6 模型',
            '需要 Optima 账号（~/.optima/token.json 或 OPTIMA_TOKEN）',
            '支持本地图片路径和 URL',
            '服装类别: auto (自动检测), tops (上装), bottoms (下装), one-pieces (连体)',
            '生成模式: performance (~7s), balanced (~9s), quality (~13s)',
        ],
    });
}
//# sourceMappingURL=tryon.js.map