"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.QualityController = void 0;
exports.getQualityController = getQualityController;
const path_1 = require("path");
const logger_js_1 = require("../../utils/logger.js");
const vlm_js_1 = require("../openrouter/vlm.js");
const index_js_1 = require("../data-store/index.js");
const file_ops_js_1 = require("../data-store/file-ops.js");
const logger = (0, logger_js_1.createModuleLogger)('quality-control');
const DEFAULT_THRESHOLD = 7.0;
const DEFAULT_MAX_ATTEMPTS = 3;
class QualityController {
    vlm;
    constructor(vlm) {
        this.vlm = vlm ?? (0, vlm_js_1.createVLMAnalyzer)();
    }
    /**
     * Runs VLM analysis on an image and saves the quality report.
     */
    async checkQuality(imageUrl, characterId, imageId, taskId, threshold = DEFAULT_THRESHOLD) {
        const dna = await index_js_1.dataStore.getCharacter(characterId);
        if (!dna) {
            throw new Error(`Character not found: ${characterId}`);
        }
        const report = await this.vlm.analyzeImage(imageUrl, dna, imageId, taskId, threshold);
        // Save quality report
        const reportsDir = index_js_1.dataStore.getQualityReportsDir(characterId);
        const reportPath = (0, path_1.resolve)(reportsDir, `${imageId}.json`);
        await (0, file_ops_js_1.atomicWriteJSON)(reportPath, report);
        logger.info({ imageId, totalScore: report.totalScore, passed: report.passed }, 'Quality check complete, report saved');
        return report;
    }
    /**
     * Checks quality with auto-retry. If below threshold, calls regenerateFn
     * with VLM feedback and re-checks. Max attempts before marking for manual review.
     */
    async checkWithRetry(imageUrl, characterId, imageId, taskId, regenerateFn, threshold = DEFAULT_THRESHOLD, maxAttempts = DEFAULT_MAX_ATTEMPTS) {
        let currentUrl = imageUrl;
        let currentImageId = imageId;
        let lastReport;
        for (let attempt = 1; attempt <= maxAttempts; attempt++) {
            logger.info({ attempt, maxAttempts, imageId: currentImageId }, 'Quality check attempt');
            const report = await this.checkQuality(currentUrl, characterId, currentImageId, taskId, threshold);
            lastReport = report;
            if (report.passed) {
                logger.info({ attempt, totalScore: report.totalScore }, 'Image passed quality check');
                return report;
            }
            // If not the last attempt, regenerate with feedback
            if (attempt < maxAttempts) {
                logger.info({ attempt, totalScore: report.totalScore, feedback: report.feedback }, 'Image below threshold, requesting regeneration');
                const newUrl = await regenerateFn(report.feedback);
                currentUrl = newUrl;
                currentImageId = `${imageId}_retry${attempt}`;
            }
        }
        // All attempts exhausted — mark for manual review
        logger.warn({ imageId, attempts: maxAttempts, totalScore: lastReport.totalScore }, 'Max attempts reached, marking for manual review');
        const finalReport = {
            ...lastReport,
            passed: false,
            feedback: `[MANUAL_REVIEW_REQUIRED] ${lastReport.feedback}`,
        };
        // Overwrite the last report with manual review flag
        const reportsDir = index_js_1.dataStore.getQualityReportsDir(characterId);
        const reportPath = (0, path_1.resolve)(reportsDir, `${lastReport.imageId}.json`);
        await (0, file_ops_js_1.atomicWriteJSON)(reportPath, finalReport);
        return finalReport;
    }
}
exports.QualityController = QualityController;
let _qualityController = null;
/** Lazy singleton — avoids requiring API keys at import time. */
function getQualityController() {
    if (!_qualityController) {
        _qualityController = new QualityController();
    }
    return _qualityController;
}
//# sourceMappingURL=quality-control.js.map