/**
 * 中介黑名单弹窗优化功能测试脚本
 *
 * 测试目标：
 * 1. 新增模式下的类型选择卡片交互
 * 2. 个人类型表单验证和提交
 * 3. 机构类型表单验证和提交
 * 4. 机构类型证件号与统一社会信用代码同步
 * 5. 修改模式下的表单锁定和编辑
 *
 * 运行环境：Node.js
 * 依赖：axios
 *
 * 使用方法：
 * node test_intermediary_dialog.js
 */

const axios = require('axios');

// 配置
const CONFIG = {
    baseURL: 'http://localhost:8080',
    testUser: {
        username: 'admin',
        password: 'admin123'
    }
};

// 创建axios实例
const api = axios.create({
    baseURL: CONFIG.baseURL,
    timeout: 10000,
    headers: {
        'Content-Type': 'application/json'
    }
});

// 存储测试数据
let authToken = null;
let testIndivId = null;
let testCorpId = null;

// 颜色输出
const colors = {
    reset: '\x1b[0m',
    bright: '\x1b[1m',
    red: '\x1b[31m',
    green: '\x1b[32m',
    yellow: '\x1b[33m',
    blue: '\x1b[34m',
    cyan: '\x1b[36m'
};

function log(message, color = 'reset') {
    console.log(`${colors[color]}${message}${colors.reset}`);
}

function logSection(title) {
    console.log('\n' + '='.repeat(60));
    log(title, 'bright');
    console.log('='.repeat(60));
}

function logTest(name, passed, details = '') {
    const status = passed ? '✓ 通过' : '✗ 失败';
    const color = passed ? 'green' : 'red';
    log(`${status} - ${name}`, color);
    if (details) {
        log(`  ${details}`, 'yellow');
    }
}

// ==================== 测试用例 ====================

/**
 * 测试1：登录获取Token
 */
async function testLogin() {
    logSection('测试1：登录系统');
    try {
        const response = await api.post('/login', {
            username: CONFIG.testUser.username,
            password: CONFIG.testUser.password
        });

        if (response.data.code === 200) {
            authToken = response.data.token;
            api.defaults.headers.common['Authorization'] = `Bearer ${authToken}`;
            logTest('登录成功', true, `Token: ${authToken.substring(0, 20)}...`);
            return true;
        } else {
            logTest('登录失败', false, response.data.msg);
            return false;
        }
    } catch (error) {
        logTest('登录异常', false, error.message);
        return false;
    }
}

/**
 * 测试2：新增个人中介 - 验证必填字段
 */
async function testAddIndividualRequired() {
    logSection('测试2：新增个人中介 - 验证必填字段');

    const testCases = [
        {
            name: '空姓名',
            data: {
                intermediaryType: '1',
                certificateNo: '123456789012345678'
            },
            shouldFail: true
        },
        {
            name: '空证件号',
            data: {
                intermediaryType: '1',
                name: '测试个人'
            },
            shouldFail: true
        },
        {
            name: '完整必填字段',
            data: {
                intermediaryType: '1',
                name: '张三',
                certificateNo: '123456789012345678'
            },
            shouldFail: false
        }
    ];

    for (const testCase of testCases) {
        try {
            const response = await api.post('/dpc/intermediary', testCase.data);
            const passed = testCase.shouldFail ? response.data.code !== 200 : response.data.code === 200;

            if (!testCase.shouldFail && response.data.code === 200) {
                testIndivId = response.data.data; // 假设返回ID
            }

            logTest(testCase.name, passed,
                testCase.shouldFail ? '应该被拒绝' : `成功创建，ID: ${response.data.data || 'N/A'}`);
        } catch (error) {
            logTest(testCase.name, testCase.shouldFail, `异常: ${error.response?.data?.msg || error.message}`);
        }
    }
}

/**
 * 测试3：新增个人中介 - 验证字段长度限制
 */
async function testAddIndividualMaxLength() {
    logSection('测试3：新增个人中介 - 验证字段长度限制');

    const testCases = [
        {
            name: '姓名超过100字符',
            data: {
                intermediaryType: '1',
                name: 'A'.repeat(101),
                certificateNo: '123456789012345678'
            },
            shouldFail: true
        },
        {
            name: '证件号超过50字符',
            data: {
                intermediaryType: '1',
                name: '李四',
                certificateNo: 'B'.repeat(51)
            },
            shouldFail: true
        },
        {
            name: '备注超过500字符',
            data: {
                intermediaryType: '1',
                name: '王五',
                certificateNo: '123456789012345678',
                remark: 'R'.repeat(501)
            },
            shouldFail: true
        }
    ];

    for (const testCase of testCases) {
        try {
            const response = await api.post('/dpc/intermediary', testCase.data);
            const passed = response.data.code !== 200;
            logTest(testCase.name, passed, `响应: ${response.data.msg || 'N/A'}`);
        } catch (error) {
            logTest(testCase.name, true, `正确拒绝: ${error.response?.data?.msg || '字段验证失败'}`);
        }
    }
}

/**
 * 测试4：新增机构中介 - 验证证件号同步
 */
async function testAddCorpSync() {
    logSection('测试4：新增机构中介 - 验证证件号同步');

    const creditCode = '91110000123456789X';

    const testData = {
        intermediaryType: '2',
        name: '测试机构有限公司',
        certificateNo: creditCode, // 这个值应该同步到 corpCreditCode
        corpType: '1',
        corpNature: '1'
    };

    try {
        const response = await api.post('/dpc/intermediary', testData);

        if (response.data.code === 200) {
            testCorpId = response.data.data;
            logTest('机构创建成功', true, `证件号: ${creditCode}, ID: ${testCorpId}`);

            // 验证获取详情时证件号是否同步
            const detailResponse = await api.get(`/dpc/intermediary/${testCorpId}`);
            if (detailResponse.data.code === 200) {
                const data = detailResponse.data.data;
                const synced = data.certificateNo === creditCode && data.corpCreditCode === creditCode;
                logTest('证件号同步验证', synced,
                    `certificateNo: ${data.certificateNo}, corpCreditCode: ${data.corpCreditCode}`);
            }
        } else {
            logTest('机构创建失败', false, response.data.msg);
        }
    } catch (error) {
        logTest('机构创建异常', false, error.message);
    }
}

/**
 * 测试5：新增机构中介 - 验证统一社会信用代码长度
 */
async function testAddCorpCreditCodeLength() {
    logSection('测试5：新增机构中介 - 验证统一社会信用代码长度');

    const testCases = [
        {
            name: '统一社会信用代码17位',
            data: {
                intermediaryType: '2',
                name: '测试机构A',
                certificateNo: '91110000123456789'
            },
            shouldFail: false // 前端验证是18位，但后端可能接受
        },
        {
            name: '统一社会信用代码18位',
            data: {
                intermediaryType: '2',
                name: '测试机构B',
                certificateNo: '91110000123456789X'
            },
            shouldFail: false
        },
        {
            name: '统一社会信用代码19位',
            data: {
                intermediaryType: '2',
                name: '测试机构C',
                certificateNo: '91110000123456789XX'
            },
            shouldFail: false // 前端会限制为18位
        }
    ];

    for (const testCase of testCases) {
        try {
            const response = await api.post('/dpc/intermediary', testCase.data);
            const length = testCase.data.certificateNo.length;
            logTest(`${testCase.name} (实际${length}位)`, response.data.code === 200,
                `响应: ${response.data.msg || '成功'}`);
        } catch (error) {
            logTest(testCase.name, false, `异常: ${error.response?.data?.msg || error.message}`);
        }
    }
}

/**
 * 测试6：修改个人中介 - 验证类型锁定
 */
async function testEditIndividualTypeLock() {
    logSection('测试6：修改个人中介 - 验证类型锁定');

    if (!testIndivId) {
        logTest('跳过测试', false, '没有可用的个人中介ID');
        return;
    }

    try {
        // 获取详情
        const getResponse = await api.get(`/dpc/intermediary/${testIndivId}`);
        if (getResponse.data.code === 200) {
            const originalData = getResponse.data.data;
            logTest('获取个人中介详情', true, `类型: ${originalData.intermediaryType}, 姓名: ${originalData.name}`);

            // 尝试修改（保持类型不变）
            const updateData = {
                ...originalData,
                name: '张三（已修改）',
                indivPhone: '13800138000'
            };

            const updateResponse = await api.put('/dpc/intermediary', updateData);
            logTest('修改个人中介成功', updateResponse.data.code === 200,
                `新姓名: ${updateData.name}`);
        }
    } catch (error) {
        logTest('修改个人中介失败', false, error.message);
    }
}

/**
 * 测试7：修改机构中介 - 验证类型锁定
 */
async function testEditCorpTypeLock() {
    logSection('测试7：修改机构中介 - 验证类型锁定');

    if (!testCorpId) {
        logTest('跳过测试', false, '没有可用的机构中介ID');
        return;
    }

    try {
        // 获取详情
        const getResponse = await api.get(`/dpc/intermediary/${testCorpId}`);
        if (getResponse.data.code === 200) {
            const originalData = getResponse.data.data;
            logTest('获取机构中介详情', true, `类型: ${originalData.intermediaryType}, 名称: ${originalData.name}`);

            // 尝试修改（保持类型不变）
            const updateData = {
                ...originalData,
                name: '测试机构有限公司（已修改）',
                corpLegalRep: '法人代表'
            };

            const updateResponse = await api.put('/dpc/intermediary', updateData);
            logTest('修改机构中介成功', updateResponse.data.code === 200,
                `新名称: ${updateData.name}`);
        }
    } catch (error) {
        logTest('修改机构中介失败', false, error.message);
    }
}

/**
 * 测试8：验证新增模式下未选择类型无法提交
 */
async function testAddWithoutType() {
    logSection('测试8：验证新增模式下未选择类型无法提交');

    // 这个测试主要验证前端行为，后端应该会拒绝没有类型的请求
    const testData = {
        name: '无类型测试'
        // 没有 intermediaryType
    };

    try {
        const response = await api.post('/dpc/intermediary', testData);
        const passed = response.data.code !== 200;
        logTest('后端拒绝无类型请求', passed, `响应: ${response.data.msg || '验证失败'}`);
    } catch (error) {
        logTest('后端正确拒绝', true, `异常: ${error.response?.data?.msg || '类型验证失败'}`);
    }
}

/**
 * 测试9：查询列表验证数据正确性
 */
async function testListQuery() {
    logSection('测试9：查询列表验证数据正确性');

    try {
        const response = await api.get('/dpc/intermediary/list', {
            params: {
                pageNum: 1,
                pageSize: 10
            }
        });

        if (response.data.code === 200) {
            const list = response.data.rows;
            logTest('查询列表成功', true, `共 ${response.data.total} 条记录`);

            // 统计类型分布
            const indivCount = list.filter(item => item.intermediaryType === '1').length;
            const corpCount = list.filter(item => item.intermediaryType === '2').length;
            log(`  个人类型: ${indivCount} 条`, 'cyan');
            log(`  机构类型: ${corpCount} 条`, 'cyan');
        } else {
            logTest('查询列表失败', false, response.data.msg);
        }
    } catch (error) {
        logTest('查询列表异常', false, error.message);
    }
}

/**
 * 清理测试数据
 */
async function cleanup() {
    logSection('清理测试数据');

    const idsToDelete = [];
    if (testIndivId) idsToDelete.push(testIndivId);
    if (testCorpId) idsToDelete.push(testCorpId);

    for (const id of idsToDelete) {
        try {
            await api.delete(`/dpc/intermediary/${id}`);
            logTest(`删除测试数据 ID: ${id}`, true);
        } catch (error) {
            logTest(`删除失败 ID: ${id}`, false, error.message);
        }
    }
}

// ==================== 主流程 ====================

async function runTests() {
    log('\n╔════════════════════════════════════════════════════════════╗');
    log('║       中介黑名单弹窗优化功能测试                           ║', 'bright');
    log('║       测试日期: ' + new Date().toLocaleString('zh-CN') + '           ║');
    log('╚════════════════════════════════════════════════════════════╝');

    try {
        // 按顺序执行测试
        await testLogin();
        await testAddIndividualRequired();
        await testAddIndividualMaxLength();
        await testAddCorpSync();
        await testAddCorpCreditCodeLength();
        await testEditIndividualTypeLock();
        await testEditCorpTypeLock();
        await testAddWithoutType();
        await testListQuery();

        logSection('测试完成');
        log('所有测试用例执行完毕！', 'green');

    } catch (error) {
        log('\n测试流程异常终止', 'red');
        log(error.message, 'red');
    } finally {
        // 询问是否清理测试数据
        log('\n是否清理测试数据？(在自动化环境中会自动清理)', 'yellow');
        await cleanup();
    }
}

// 运行测试
if (require.main === module) {
    runTests().catch(console.error);
}

module.exports = {runTests};
