"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.processPendingImageComparisons = exports.triggerImageComparisonAsync = exports.processBulkImageComparison = exports.processImageComparison = exports.storeComparisonResult = exports.callImageComparisonAPI = exports.prepareImageComparisonData = exports.getMaterialVersions = exports.getImageMaterials = exports.isModifiedSubmission = void 0;
var tslib_1 = require("tslib");
var axios_1 = require("axios");
var consts_1 = require("./consts");
var AI_COMPARISON_HOST = process.env.PEPSICO_AI_HOST;
var AI_COMPARISON_API_KEY = process.env.PEPSICO_AI_API_KEY;
var DEFAULT_THRESHOLD = 30;
var DEFAULT_MIN_AREA = 50;
var IMAGE_EXTENSIONS = [
    'jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'tif',
    'svg', 'webp', 'ico', 'heif', 'heic'
];
var isModifiedSubmission = function (approval) {
    return approval.current_step === consts_1.Step.submitter_revisions;
};
exports.isModifiedSubmission = isModifiedSubmission;
var getImageMaterials = function (ctx, approvalId) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
    var materials;
    return tslib_1.__generator(this, function (_a) {
        switch (_a.label) {
            case 0: return [4, ctx.getObject('pepsico_material').find({
                    filters: [
                        ['pepsico_material_approval', '=', approvalId],
                        ['extension_type', 'in', IMAGE_EXTENSIONS],
                        ['void_material', '!=', true],
                        ['is_bypassed', '!=', true]
                    ]
                })];
            case 1:
                materials = _a.sent();
                return [2, materials];
        }
    });
}); };
exports.getImageMaterials = getImageMaterials;
var getMaterialVersions = function (ctx, material) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
    var versions, rootUrl;
    return tslib_1.__generator(this, function (_a) {
        versions = {
            current: material.material,
            previous: null,
            currentUrl: '',
            previousUrl: null
        };
        rootUrl = process.env.ROOT_URL || '';
        versions.currentUrl = "".concat(rootUrl, "/api/v6/files/cfs.files.filerecord/").concat(material.material);
        if (!versions.previous && material.material_original && material.material_original !== material.material) {
            versions.previous = material.material_original;
            versions.previousUrl = "".concat(rootUrl, "/api/v6/files/cfs.files.filerecord/").concat(versions.previous);
        }
        return [2, versions];
    });
}); };
exports.getMaterialVersions = getMaterialVersions;
var prepareImageComparisonData = function (ctx, material, versions, options) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
    var _a, _b;
    return tslib_1.__generator(this, function (_c) {
        return [2, {
                request: {
                    image_url_a: versions.previousUrl,
                    image_url_b: versions.currentUrl,
                    threshold: (_a = options === null || options === void 0 ? void 0 : options.threshold) !== null && _a !== void 0 ? _a : DEFAULT_THRESHOLD,
                    min_area: (_b = options === null || options === void 0 ? void 0 : options.min_area) !== null && _b !== void 0 ? _b : DEFAULT_MIN_AREA
                },
                metadata: {
                    material_id: material._id,
                    approval_id: material.pepsico_material_approval,
                    name: material.name,
                    current_file_id: versions.current,
                    previous_file_id: versions.previous,
                    extension_type: material.extension_type
                }
            }];
    });
}); };
exports.prepareImageComparisonData = prepareImageComparisonData;
var callImageComparisonAPI = function (ctx, imageData) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
    var request, metadata, endpoint, now, result, data, error_1, errorMessage, statusCode;
    var _a, _b, _c, _d, _e;
    return tslib_1.__generator(this, function (_f) {
        switch (_f.label) {
            case 0:
                request = imageData.request, metadata = imageData.metadata;
                endpoint = "".concat(AI_COMPARISON_HOST, "/api/v1/compare_historical_images");
                _f.label = 1;
            case 1:
                _f.trys.push([1, 5, , 8]);
                now = new Date().getTime();
                console.log('[调用 AI 图片对比 API] 开始:', endpoint, {
                    material_id: metadata.material_id,
                    approval_id: metadata.approval_id,
                    threshold: request.threshold,
                    min_area: request.min_area
                }, new Date());
                return [4, axios_1.default.post(endpoint, request, {
                        headers: {
                            'X-API-Key': AI_COMPARISON_API_KEY,
                            'Content-Type': 'application/json'
                        },
                        timeout: 120000
                    })];
            case 2:
                result = _f.sent();
                data = result.data;
                console.log("[\u8C03\u7528 AI \u56FE\u7247\u5BF9\u6BD4 API]-".concat(metadata.material_id), data, "\u8017\u65F6:", new Date().getTime() - now);
                if (!ctx.logger) return [3, 4];
                return [4, ctx.logger.info("[\u8C03\u7528 AI \u56FE\u7247\u5BF9\u6BD4 API]-".concat(metadata.material_id), {
                        data: data,
                        duration: new Date().getTime() - now
                    })];
            case 3:
                _f.sent();
                _f.label = 4;
            case 4: return [2, data];
            case 5:
                error_1 = _f.sent();
                errorMessage = ((_b = (_a = error_1.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.detail) || ((_d = (_c = error_1.response) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.message) || error_1.message;
                statusCode = (_e = error_1.response) === null || _e === void 0 ? void 0 : _e.status;
                console.error("[\u8C03\u7528 AI \u56FE\u7247\u5BF9\u6BD4 API \u5931\u8D25]-".concat(metadata.material_id), "HTTP ".concat(statusCode, ":"), errorMessage, new Date());
                if (!ctx.logger) return [3, 7];
                return [4, ctx.logger.error("[\u8C03\u7528 AI \u56FE\u7247\u5BF9\u6BD4 API \u5931\u8D25]-".concat(metadata.material_id), {
                        endpoint: endpoint,
                        body: request,
                        error: errorMessage,
                        statusCode: statusCode,
                        stack: error_1.stack
                    })];
            case 6:
                _f.sent();
                _f.label = 7;
            case 7: throw error_1;
            case 8: return [2];
        }
    });
}); };
exports.callImageComparisonAPI = callImageComparisonAPI;
var storeComparisonResult = function (ctx, materialId, comparisonResult) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
    var isTooManyDiffs, error_2;
    return tslib_1.__generator(this, function (_a) {
        switch (_a.label) {
            case 0:
                _a.trys.push([0, 4, , 8]);
                isTooManyDiffs = comparisonResult.status === 'too_many_differences';
                return [4, ctx.getObject('pepsico_material').directUpdate(materialId, {
                        result_image: comparisonResult.result_image,
                        image_comparison_result: JSON.stringify({
                            status: comparisonResult.status,
                            result_image: comparisonResult.result_image,
                            diff_regions: comparisonResult.diff_regions || [],
                            ssim_score: comparisonResult.ssim_score,
                            diff_count: comparisonResult.diff_count,
                            message: comparisonResult.message || undefined
                        }),
                        image_comparison_status: isTooManyDiffs ? 'too_many_differences' : 'completed',
                        image_comparison_at: new Date()
                    })];
            case 1:
                _a.sent();
                console.log("[\u5B58\u50A8\u56FE\u7247\u5BF9\u6BD4\u7ED3\u679C\u6210\u529F]-".concat(materialId), {
                    status: comparisonResult.status,
                    diff_count: comparisonResult.diff_count,
                    ssim_score: comparisonResult.ssim_score
                });
                if (!ctx.logger) return [3, 3];
                return [4, ctx.logger.info("[\u5B58\u50A8\u56FE\u7247\u5BF9\u6BD4\u7ED3\u679C\u6210\u529F]-".concat(materialId), {
                        status: comparisonResult.status,
                        diff_count: comparisonResult.diff_count,
                        ssim_score: comparisonResult.ssim_score,
                        has_result_image: !!comparisonResult.result_image
                    })];
            case 2:
                _a.sent();
                _a.label = 3;
            case 3: return [3, 8];
            case 4:
                error_2 = _a.sent();
                console.error("[\u5B58\u50A8\u56FE\u7247\u5BF9\u6BD4\u7ED3\u679C\u5931\u8D25]-".concat(materialId), error_2.message);
                if (!ctx.logger) return [3, 6];
                return [4, ctx.logger.error("[\u5B58\u50A8\u56FE\u7247\u5BF9\u6BD4\u7ED3\u679C\u5931\u8D25]-".concat(materialId), {
                        error: error_2.message
                    })];
            case 5:
                _a.sent();
                _a.label = 6;
            case 6: return [4, ctx.getObject('pepsico_material').directUpdate(materialId, {
                    image_comparison_status: 'failed',
                    image_comparison_error: error_2.message,
                    image_comparison_at: new Date()
                })];
            case 7:
                _a.sent();
                throw error_2;
            case 8: return [2];
        }
    });
}); };
exports.storeComparisonResult = storeComparisonResult;
var processImageComparison = function (ctx, material) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
    var versions, imageData, result, error_3;
    return tslib_1.__generator(this, function (_a) {
        switch (_a.label) {
            case 0:
                _a.trys.push([0, 7, , 8]);
                return [4, (0, exports.getMaterialVersions)(ctx, material)];
            case 1:
                versions = _a.sent();
                if (!!versions.previous) return [3, 3];
                console.log("[\u8DF3\u8FC7\u56FE\u7247\u5BF9\u6BD4]-".concat(material._id, ": \u6CA1\u6709\u5386\u53F2\u7248\u672C"));
                return [4, ctx.getObject('pepsico_material').directUpdate(material._id, {
                        image_comparison_status: 'skipped',
                        image_comparison_reason: 'No previous version found'
                    })];
            case 2:
                _a.sent();
                return [2];
            case 3: return [4, (0, exports.prepareImageComparisonData)(ctx, material, versions)];
            case 4:
                imageData = _a.sent();
                return [4, (0, exports.callImageComparisonAPI)(ctx, imageData)];
            case 5:
                result = _a.sent();
                return [4, (0, exports.storeComparisonResult)(ctx, material._id, result)];
            case 6:
                _a.sent();
                return [2, result];
            case 7:
                error_3 = _a.sent();
                console.error("[\u5904\u7406\u56FE\u7247\u5BF9\u6BD4\u5931\u8D25]-".concat(material._id), error_3.message);
                throw error_3;
            case 8: return [2];
        }
    });
}); };
exports.processImageComparison = processImageComparison;
var processBulkImageComparison = function (ctx, approvalId) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
    var materials, processed, skipped, failed, materials_1, materials_1_1, material, versions, error_4, e_1_1, result, error_5;
    var e_1, _a;
    return tslib_1.__generator(this, function (_b) {
        switch (_b.label) {
            case 0:
                _b.trys.push([0, 16, , 19]);
                return [4, (0, exports.getImageMaterials)(ctx, approvalId)];
            case 1:
                materials = _b.sent();
                console.log("[\u6279\u91CF\u56FE\u7247\u5BF9\u6BD4]-".concat(approvalId, ": \u53D1\u73B0 ").concat(materials.length, " \u4E2A\u56FE\u7247\u7D20\u6750"));
                if (materials.length === 0) {
                    return [2, {
                            total: 0,
                            processed: 0,
                            skipped: 0,
                            failed: 0
                        }];
                }
                processed = 0;
                skipped = 0;
                failed = 0;
                _b.label = 2;
            case 2:
                _b.trys.push([2, 12, 13, 14]);
                materials_1 = tslib_1.__values(materials), materials_1_1 = materials_1.next();
                _b.label = 3;
            case 3:
                if (!!materials_1_1.done) return [3, 11];
                material = materials_1_1.value;
                _b.label = 4;
            case 4:
                _b.trys.push([4, 9, , 10]);
                return [4, (0, exports.getMaterialVersions)(ctx, material)];
            case 5:
                versions = _b.sent();
                if (!!versions.previous) return [3, 7];
                skipped++;
                console.log("[\u8DF3\u8FC7\u56FE\u7247\u5BF9\u6BD4]-".concat(material._id, ": \u6CA1\u6709\u5386\u53F2\u7248\u672C"));
                return [4, ctx.getObject('pepsico_material').directUpdate(material._id, {
                        image_comparison_status: 'skipped',
                        image_comparison_reason: 'No previous version found'
                    })];
            case 6:
                _b.sent();
                return [3, 10];
            case 7: return [4, (0, exports.processImageComparison)(ctx, material)];
            case 8:
                _b.sent();
                processed++;
                return [3, 10];
            case 9:
                error_4 = _b.sent();
                failed++;
                console.error("[\u56FE\u7247\u5BF9\u6BD4\u5931\u8D25]-".concat(material._id), error_4.message);
                return [3, 10];
            case 10:
                materials_1_1 = materials_1.next();
                return [3, 3];
            case 11: return [3, 14];
            case 12:
                e_1_1 = _b.sent();
                e_1 = { error: e_1_1 };
                return [3, 14];
            case 13:
                try {
                    if (materials_1_1 && !materials_1_1.done && (_a = materials_1.return)) _a.call(materials_1);
                }
                finally { if (e_1) throw e_1.error; }
                return [7];
            case 14:
                result = {
                    total: materials.length,
                    processed: processed,
                    skipped: skipped,
                    failed: failed
                };
                console.log("[\u6279\u91CF\u56FE\u7247\u5BF9\u6BD4\u5B8C\u6210]-".concat(approvalId), result);
                return [4, ctx.getObject('pepsico_material_approval').directUpdate(approvalId, {
                        image_comparison_status: failed > 0 ? 'partial' : 'completed',
                        image_comparison_stats: JSON.stringify(result),
                        image_comparison_at: new Date()
                    })];
            case 15:
                _b.sent();
                return [2, result];
            case 16:
                error_5 = _b.sent();
                console.error("[\u6279\u91CF\u56FE\u7247\u5BF9\u6BD4\u5931\u8D25]-".concat(approvalId), error_5.message);
                if (!ctx.logger) return [3, 18];
                return [4, ctx.logger.error("[\u6279\u91CF\u56FE\u7247\u5BF9\u6BD4\u5931\u8D25]-".concat(approvalId), {
                        error: error_5.message
                    })];
            case 17:
                _b.sent();
                _b.label = 18;
            case 18: throw error_5;
            case 19: return [2];
        }
    });
}); };
exports.processBulkImageComparison = processBulkImageComparison;
var triggerImageComparisonAsync = function (ctx, approvalId) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
    var error_6;
    return tslib_1.__generator(this, function (_a) {
        switch (_a.label) {
            case 0:
                _a.trys.push([0, 2, , 3]);
                return [4, ctx.getObject('pepsico_material_approval').directUpdate(approvalId, {
                        image_comparison_status: 'pending',
                        image_comparison_at: new Date()
                    })];
            case 1:
                _a.sent();
                console.log("[\u56FE\u7247\u5BF9\u6BD4\u4EFB\u52A1\u5DF2\u6807\u8BB0\u4E3Apending]-".concat(approvalId));
                return [3, 3];
            case 2:
                error_6 = _a.sent();
                console.error("[\u6807\u8BB0\u56FE\u7247\u5BF9\u6BD4\u4EFB\u52A1\u5931\u8D25]-".concat(approvalId), error_6.message);
                return [3, 3];
            case 3: return [2];
        }
    });
}); };
exports.triggerImageComparisonAsync = triggerImageComparisonAsync;
var processPendingImageComparisons = function (ctx, maxRetries) {
    if (maxRetries === void 0) { maxRetries = 3; }
    return tslib_1.__awaiter(void 0, void 0, void 0, function () {
        var pendingApprovals, pendingApprovals_1, pendingApprovals_1_1, approval, failedCount, error_7, e_2_1, error_8;
        var e_2, _a;
        return tslib_1.__generator(this, function (_b) {
            switch (_b.label) {
                case 0:
                    _b.trys.push([0, 16, , 19]);
                    return [4, ctx.getObject('pepsico_material_approval').find({
                            filters: [
                                ['image_comparison_status', 'in', ['pending', 'failed']]
                            ],
                            top: 10,
                            sort: 'modified desc'
                        })];
                case 1:
                    pendingApprovals = _b.sent();
                    console.log("\u5B9A\u65F6\u4EFB\u52A1[\u56FE\u7247\u5BF9\u6BD4] count: ".concat(pendingApprovals.length), { approvals: pendingApprovals.map(function (a) { return ({ _id: a._id, status: a.image_comparison_status, failedCount: a.image_comparison_failed_count }); }) });
                    _b.label = 2;
                case 2:
                    _b.trys.push([2, 13, 14, 15]);
                    pendingApprovals_1 = tslib_1.__values(pendingApprovals), pendingApprovals_1_1 = pendingApprovals_1.next();
                    _b.label = 3;
                case 3:
                    if (!!pendingApprovals_1_1.done) return [3, 12];
                    approval = pendingApprovals_1_1.value;
                    failedCount = approval.image_comparison_failed_count || 0;
                    if (failedCount >= maxRetries) {
                        console.log("[\u56FE\u7247\u5BF9\u6BD4\u8DF3\u8FC7]-".concat(approval._id, ": \u5DF2\u8FBE\u6700\u5927\u91CD\u8BD5\u6B21\u6570 ").concat(maxRetries));
                        return [3, 11];
                    }
                    _b.label = 4;
                case 4:
                    _b.trys.push([4, 7, , 11]);
                    return [4, ctx.getObject('pepsico_material_approval').directUpdate(approval._id, {
                            image_comparison_status: 'processing'
                        })];
                case 5:
                    _b.sent();
                    return [4, (0, exports.processBulkImageComparison)(ctx, approval._id)];
                case 6:
                    _b.sent();
                    return [3, 11];
                case 7:
                    error_7 = _b.sent();
                    console.error("[\u56FE\u7247\u5BF9\u6BD4\u4EFB\u52A1\u5931\u8D25]-".concat(approval._id), error_7.message);
                    return [4, ctx.getObject('pepsico_material_approval').directUpdate(approval._id, {
                            image_comparison_status: 'failed',
                            $inc: { image_comparison_failed_count: 1 }
                        })];
                case 8:
                    _b.sent();
                    if (!ctx.logger) return [3, 10];
                    return [4, ctx.logger.error("[\u56FE\u7247\u5BF9\u6BD4\u4EFB\u52A1\u5931\u8D25]-".concat(approval._id), {
                            error: error_7.message,
                            failedCount: failedCount + 1
                        })];
                case 9:
                    _b.sent();
                    _b.label = 10;
                case 10: return [3, 11];
                case 11:
                    pendingApprovals_1_1 = pendingApprovals_1.next();
                    return [3, 3];
                case 12: return [3, 15];
                case 13:
                    e_2_1 = _b.sent();
                    e_2 = { error: e_2_1 };
                    return [3, 15];
                case 14:
                    try {
                        if (pendingApprovals_1_1 && !pendingApprovals_1_1.done && (_a = pendingApprovals_1.return)) _a.call(pendingApprovals_1);
                    }
                    finally { if (e_2) throw e_2.error; }
                    return [7];
                case 15: return [3, 19];
                case 16:
                    error_8 = _b.sent();
                    console.error('[定时任务-图片对比] 执行异常:', error_8.message);
                    if (!ctx.logger) return [3, 18];
                    return [4, ctx.logger.error('[定时任务-图片对比] 执行异常', { error: error_8.message })];
                case 17:
                    _b.sent();
                    _b.label = 18;
                case 18: return [3, 19];
                case 19: return [2];
            }
        });
    });
};
exports.processPendingImageComparisons = processPendingImageComparisons;
//# sourceMappingURL=image_comparison.js.map