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

const { processFieldsArrayForRollback } = mod._helpers;

let suitePassed = 0;
let suiteFailed = 0;

function runSuite(name, fn) {
    let passed = 0;
    let failed = 0;
    const suiteAssert = {
        strictEqual(a, b, msg) {
            try {
                assert.strictEqual(a, b, msg);
                passed++;
            } catch (e) {
                failed++;
                console.error(`  FAIL: ${msg || e.message}`);
            }
        },
        ok(val, msg) {
            try {
                assert.ok(val, msg);
                passed++;
            } catch (e) {
                failed++;
                console.error(`  FAIL: ${msg || e.message}`);
            }
        }
    };
    fn(suiteAssert);
    suitePassed += passed;
    suiteFailed += failed;
    if (failed === 0) {
        console.log(`  ${name}: ${passed} assertions passed.`);
    } else {
        console.log(`  ${name}: ${passed} passed, ${failed} FAILED.`);
    }
}

console.log('[test_rollbackApprovalCommentsField] running tests...');

// ---------------------------------------------------------------------------
// Flat (first-level) transformed field
// ---------------------------------------------------------------------------
runSuite('processFieldsArrayForRollback (flat)', (t) => {
    const fields = [
        {
            code: 'mgr_comments',
            type: 'steedos-field',
            __approval_comments_transformed: true,
            __approval_comments_original_type: 'input',
            __approval_comments_original_formula: '{traces.主管审核}',
            config: { type: 'approval_comments' }
        },
        { code: 'plain_field', type: 'text' }  // not transformed
    ];
    const { updates, unsets, fieldCount } = processFieldsArrayForRollback(
        fields, 'current.fields', 'form1', 'TestForm'
    );

    t.strictEqual(fieldCount, 1, 'fieldCount should be 1');
    t.ok(updates.some(u => u.path === 'current.fields.0.type' && u.value === 'input'),
        'type path and value restored');
    t.ok(updates.some(u => u.path === 'current.fields.0.formula' && u.value === '{traces.主管审核}'),
        'formula path and value restored');
    t.ok(unsets.includes('current.fields.0.__approval_comments_transformed'),
        '__approval_comments_transformed unset');
    t.ok(unsets.includes('current.fields.0.config'), 'config unset');
    t.ok(unsets.includes('current.fields.0.__approval_comments_original_type'),
        '__approval_comments_original_type backup removed');
    t.ok(unsets.includes('current.fields.0.__approval_comments_original_formula'),
        '__approval_comments_original_formula backup removed');
});

// ---------------------------------------------------------------------------
// Nested (section container) — primary regression scenario
// ---------------------------------------------------------------------------
runSuite('processFieldsArrayForRollback (nested sections)', (t) => {
    const fields = [
        { code: 'plain_top', type: 'text' },  // index 0, not transformed
        {
            code: 'section_a',
            type: 'section',
            fields: [
                { code: 'nested_plain', type: 'text' },  // index 0, not transformed
                {
                    code: 'dept_comments',
                    type: 'steedos-field',
                    __approval_comments_transformed: true,
                    __approval_comments_original_type: 'input',
                    __approval_comments_original_formula: '{traces.部门审核}',
                    config: { type: 'approval_comments' }
                }  // index 1
            ]
        }  // index 1
    ];
    const { updates, unsets, fieldCount } = processFieldsArrayForRollback(
        fields, 'current.fields', 'form1', 'TestForm'
    );

    t.strictEqual(fieldCount, 1, 'fieldCount should be 1 (only nested field)');
    t.ok(updates.some(u => u.path === 'current.fields.1.fields.1.type' && u.value === 'input'),
        'nested type restored at correct path');
    t.ok(updates.some(u => u.path === 'current.fields.1.fields.1.formula'),
        'nested formula restored at correct path');
    t.ok(unsets.includes('current.fields.1.fields.1.__approval_comments_transformed'),
        'nested: __approval_comments_transformed unset at correct path');
    t.ok(unsets.includes('current.fields.1.fields.1.config'),
        'nested: config unset at correct path');
    t.ok(unsets.includes('current.fields.1.fields.1.__approval_comments_original_type'),
        'nested: original_type backup removed');
    t.ok(unsets.includes('current.fields.1.fields.1.__approval_comments_original_formula'),
        'nested: original_formula backup removed');
});

// ---------------------------------------------------------------------------
// Deeply nested (section > panel)
// ---------------------------------------------------------------------------
runSuite('processFieldsArrayForRollback (deeply nested)', (t) => {
    const fields = [
        {
            code: 'section1', type: 'section',
            fields: [
                {
                    code: 'panel1', type: 'panel',
                    fields: [
                        {
                            code: 'deep_field',
                            type: 'steedos-field',
                            __approval_comments_transformed: true,
                            __approval_comments_original_type: 'textarea',
                            config: {}
                        }
                    ]
                }
            ]
        }
    ];
    const { updates, fieldCount } = processFieldsArrayForRollback(
        fields, 'current.fields', 'form1', 'TestForm'
    );

    t.strictEqual(fieldCount, 1, 'deep: fieldCount=1');
    t.ok(updates.some(u => u.path === 'current.fields.0.fields.0.fields.0.type' && u.value === 'textarea'),
        'deeply nested type restored at correct path');
    t.ok(!updates.some(u => u.path === 'current.fields.0.type'),
        'section container itself not touched');
});

// ---------------------------------------------------------------------------
// Mixed: top-level and nested transformed fields
// ---------------------------------------------------------------------------
runSuite('processFieldsArrayForRollback (mixed top-level and nested)', (t) => {
    const fields = [
        {
            code: 'top_comments',
            type: 'steedos-field',
            __approval_comments_transformed: true,
            __approval_comments_original_type: 'input',
            config: {}
        },
        {
            code: 'section_b', type: 'section',
            fields: [
                {
                    code: 'nested_comments',
                    type: 'steedos-field',
                    __approval_comments_transformed: true,
                    __approval_comments_original_type: 'input',
                    config: {}
                }
            ]
        }
    ];
    const { updates, fieldCount } = processFieldsArrayForRollback(
        fields, 'current.fields', 'form1', 'TestForm'
    );

    t.strictEqual(fieldCount, 2, 'mixed: fieldCount=2 (one top-level, one nested)');
    t.ok(updates.some(u => u.path === 'current.fields.0.type'), 'top-level type restored');
    t.ok(updates.some(u => u.path === 'current.fields.1.fields.0.type'), 'nested type restored');
});

// ---------------------------------------------------------------------------
// historys prefix
// ---------------------------------------------------------------------------
runSuite('processFieldsArrayForRollback (historys prefix)', (t) => {
    const fields = [
        {
            code: 'hist_comments',
            type: 'steedos-field',
            __approval_comments_transformed: true,
            __approval_comments_original_type: 'input',
            config: {}
        }
    ];
    const { updates, fieldCount } = processFieldsArrayForRollback(
        fields, 'historys.0.fields', 'form1', 'TestForm'
    );

    t.strictEqual(fieldCount, 1, 'historys: fieldCount=1');
    t.ok(updates.some(u => u.path === 'historys.0.fields.0.type'), 'historys prefix in path');
});

// ---------------------------------------------------------------------------
// Non-transformed fields not touched
// ---------------------------------------------------------------------------
runSuite('processFieldsArrayForRollback (non-transformed skipped)', (t) => {
    const fields = [
        { code: 'f1', type: 'text' },
        { code: 'section', type: 'section', fields: [
            { code: 'f2', type: 'input' }
        ]}
    ];
    const { updates, unsets, fieldCount } = processFieldsArrayForRollback(
        fields, 'current.fields', 'form1', 'TestForm'
    );

    t.strictEqual(fieldCount, 0, 'non-transformed: fieldCount=0');
    t.strictEqual(updates.length, 0, 'non-transformed: no updates');
    t.strictEqual(unsets.length, 0, 'non-transformed: no unsets');
});

// ---------------------------------------------------------------------------
// Summary
// ---------------------------------------------------------------------------
if (suiteFailed === 0) {
    console.log('[test_rollbackApprovalCommentsField] All assertions passed.');
    process.exit(0);
} else {
    console.error(`[test_rollbackApprovalCommentsField] ${suiteFailed} assertions FAILED.`);
    process.exit(1);
}
