const assert = require('assert');
const mod = require('../../../src/rests/migrateApprovalCommentsField');

const { matchesApprovalPattern, transformField, processFieldsArray } = mod._helpers;

// ---------------------------------------------------------------------------
// matchesApprovalPattern tests
// ---------------------------------------------------------------------------
const patternCases = [
    { input: '{traces.步骤名}', expected: true },
    { input: '${traces.步骤名}', expected: true },
    { input: '{signature.traces.步骤名}', expected: true },
    { input: '${signature.traces.步骤名}', expected: true },
    { input: '{yijianlan:{step:"步骤名"}}', expected: true },
    { input: '{普通字段}', expected: false },
    { input: null, expected: false },
    { input: undefined, expected: false }
];

// ---------------------------------------------------------------------------
// processFieldsArray: flat (first-level) fields
// ---------------------------------------------------------------------------
const flatFields = [
    {
        type: 'input',
        code: '主管经理意见',
        formula: '{signature.traces.主管经理审核}',
        _id: 'id-1'
    },
    {
        type: 'input',
        code: '普通字段',
        _id: 'id-2'
    }
];

// ---------------------------------------------------------------------------
// processFieldsArray: nested section fields (the bug scenario)
// ---------------------------------------------------------------------------
const nestedFields = [
    {
        type: 'section',
        code: '申请单位意见',
        _id: 'sec-1',
        fields: [
            {
                type: 'input',
                code: '部门负责人意见',
                formula: '{signature.traces.申请单位部门负责人意见}',
                _id: 'id-3'
            }
        ]
    },
    {
        type: 'section',
        code: '财务处意见',
        _id: 'sec-2',
        fields: [
            {
                type: 'input',
                code: '部门负责人意见1',
                name: '部门负责人意见',
                formula: '{signature.traces.财务处部门负责人意见}',
                _id: 'id-4'
            }
        ]
    }
];

// ---------------------------------------------------------------------------
// processFieldsArray: deeply nested (section > section)
// ---------------------------------------------------------------------------
const deeplyNestedFields = [
    {
        type: 'section',
        code: '外层',
        _id: 'sec-outer',
        fields: [
            {
                type: 'panel',
                code: '内层',
                _id: 'panel-inner',
                fields: [
                    {
                        type: 'input',
                        code: '深层签字字段',
                        formula: '{traces.深层步骤}',
                        _id: 'id-deep'
                    }
                ]
            }
        ]
    }
];

// ---------------------------------------------------------------------------
// processFieldsArray: mixed top-level and nested
// ---------------------------------------------------------------------------
const mixedFields = [
    {
        type: 'input',
        code: '顶层签字字段',
        formula: '{signature.traces.顶层步骤}',
        _id: 'id-top'
    },
    {
        type: 'section',
        code: '分组',
        _id: 'sec-mixed',
        fields: [
            {
                type: 'input',
                code: '嵌套签字字段',
                formula: '{signature.traces.嵌套步骤}',
                _id: 'id-nested'
            },
            {
                type: 'input',
                code: '普通嵌套字段',
                _id: 'id-plain-nested'
            }
        ]
    }
];

const run = () => {
    console.log('[migrateApprovalCommentsField] running tests...');

    // --- matchesApprovalPattern ---
    for (const item of patternCases) {
        assert.strictEqual(
            matchesApprovalPattern(item.input),
            item.expected,
            `matchesApprovalPattern("${item.input}") should be ${item.expected}`
        );
    }
    console.log(`  matchesApprovalPattern: ${patternCases.length} assertions passed.`);

    // --- transformField: should transform a matching field ---
    const transformed = transformField(flatFields[0]);
    assert.ok(transformed, 'transformField should return a non-null result for matching field');
    assert.strictEqual(transformed.type, 'steedos-field');
    assert.strictEqual(transformed.__approval_comments_transformed, true);
    assert.strictEqual(transformed.config.steps[0].name, '主管经理审核');
    assert.strictEqual(transformed.config.steps[0].show_image_sign, true);

    // --- transformField: should skip non-matching field ---
    const skipped = transformField(flatFields[1]);
    assert.strictEqual(skipped, null, 'transformField should return null for non-matching field');

    // --- transformField: should skip already-transformed field ---
    const alreadyTransformed = { ...flatFields[0], __approval_comments_transformed: true };
    assert.strictEqual(transformField(alreadyTransformed), null, 'transformField should skip already-transformed fields');
    console.log('  transformField: 4 assertions passed.');

    // --- processFieldsArray: flat fields ---
    const flatResult = processFieldsArray(flatFields, 'current.fields');
    assert.strictEqual(flatResult.updates.length, 1, 'Flat: should transform 1 matching field');
    assert.strictEqual(flatResult.updates[0].path, 'current.fields.0', 'Flat: path should be current.fields.0');
    assert.ok(flatResult.unsets.includes('current.fields.0.formula'), 'Flat: formula should be in unsets');
    console.log('  processFieldsArray (flat): 3 assertions passed.');

    // --- processFieldsArray: nested section fields (the bug regression test) ---
    const nestedResult = processFieldsArray(nestedFields, 'current.fields');
    assert.strictEqual(nestedResult.updates.length, 2,
        'Nested: should transform 2 matching fields inside sections');
    const nestedPaths = nestedResult.updates.map(u => u.path);
    assert.ok(nestedPaths.includes('current.fields.0.fields.0'),
        'Nested: first nested field path should be current.fields.0.fields.0');
    assert.ok(nestedPaths.includes('current.fields.1.fields.0'),
        'Nested: second nested field path should be current.fields.1.fields.0');
    assert.ok(nestedResult.unsets.includes('current.fields.0.fields.0.formula'),
        'Nested: formula unset path should be current.fields.0.fields.0.formula');
    assert.ok(nestedResult.unsets.includes('current.fields.1.fields.0.formula'),
        'Nested: formula unset path should be current.fields.1.fields.0.formula');

    // Verify step names are correct
    const step0 = nestedResult.updates.find(u => u.path === 'current.fields.0.fields.0');
    assert.strictEqual(step0.update.config.steps[0].name, '申请单位部门负责人意见',
        'Nested: step name should match formula');
    const step1 = nestedResult.updates.find(u => u.path === 'current.fields.1.fields.0');
    assert.strictEqual(step1.update.config.steps[0].name, '财务处部门负责人意见',
        'Nested: step name should match formula');
    console.log('  processFieldsArray (nested sections): 7 assertions passed.');

    // --- processFieldsArray: deeply nested (section > panel) ---
    const deepResult = processFieldsArray(deeplyNestedFields, 'current.fields');
    assert.strictEqual(deepResult.updates.length, 1, 'Deep: should transform 1 deeply nested field');
    assert.strictEqual(deepResult.updates[0].path, 'current.fields.0.fields.0.fields.0',
        'Deep: path should reflect full nesting depth');
    assert.ok(deepResult.unsets.includes('current.fields.0.fields.0.fields.0.formula'),
        'Deep: formula unset should use full nested path');
    console.log('  processFieldsArray (deeply nested): 3 assertions passed.');

    // --- processFieldsArray: mixed top-level and nested ---
    const mixedResult = processFieldsArray(mixedFields, 'current.fields');
    assert.strictEqual(mixedResult.updates.length, 2, 'Mixed: should transform 2 fields (1 top + 1 nested)');
    const mixedPaths = mixedResult.updates.map(u => u.path);
    assert.ok(mixedPaths.includes('current.fields.0'), 'Mixed: top-level field path should be current.fields.0');
    assert.ok(mixedPaths.includes('current.fields.1.fields.0'), 'Mixed: nested field path should be current.fields.1.fields.0');
    console.log('  processFieldsArray (mixed): 3 assertions passed.');

    // --- processFieldsArray: historys path prefix ---
    const historyResult = processFieldsArray(nestedFields, 'historys.0.fields');
    assert.strictEqual(historyResult.updates.length, 2, 'History: should transform 2 nested fields');
    const historyPaths = historyResult.updates.map(u => u.path);
    assert.ok(historyPaths.includes('historys.0.fields.0.fields.0'),
        'History: nested field path should use historys prefix');
    assert.ok(historyPaths.includes('historys.0.fields.1.fields.0'),
        'History: nested field path should use historys prefix');
    console.log('  processFieldsArray (historys prefix): 3 assertions passed.');

    console.log('[migrateApprovalCommentsField] All assertions passed.');
};

if (require.main === module) {
    run();
}

module.exports = { run };
