import { createRequire } from 'module';
import PocketBase from 'pocketbase';

const require = createRequire(import.meta.url);

let runtimeConfig = {};
try {
    runtimeConfig = require('../pocket-base/bai_api_pb_hooks/bai_api_shared/config/runtime.js');
} catch (_error) {
    runtimeConfig = {};
}

const PB_URL = (process.env.PB_URL || 'https://bai-api.blv-oa.com/pb').replace(/\/+$/, '');
const AUTH_TOKEN = process.env.POCKETBASE_AUTH_TOKEN || runtimeConfig.POCKETBASE_AUTH_TOKEN || '';
const SOFT_DELETE_RULE = 'is_delete = 0';

if (!AUTH_TOKEN) {
    console.error('❌ 缺少 POCKETBASE_AUTH_TOKEN，无法执行字典建表。');
    process.exit(1);
}

const pb = new PocketBase(PB_URL);

const collectionData = {
    name: 'tbl_system_dict',
    type: 'base',
    listRule: SOFT_DELETE_RULE,
    viewRule: SOFT_DELETE_RULE,
    createRule: '(@request.auth.users_idtype = "ManagePlatform" || @request.auth.usergroups_id = "ROLE-1774666070666-9dDrTB")',
    updateRule: '(@request.auth.users_idtype = "ManagePlatform" || @request.auth.usergroups_id = "ROLE-1774666070666-9dDrTB")',
    deleteRule: '(@request.auth.users_idtype = "ManagePlatform" || @request.auth.usergroups_id = "ROLE-1774666070666-9dDrTB")',
    fields: [
        { name: 'system_dict_id', type: 'text', required: true },
        { name: 'dict_name', type: 'text', required: true },
        { name: 'dict_word_enum', type: 'text' },
        { name: 'dict_word_description', type: 'text' },
        { name: 'dict_word_image', type: 'text' },
        { name: 'dict_word_is_enabled', type: 'bool' },
        { name: 'dict_word_sort_order', type: 'text' },
        { name: 'dict_word_parent_id', type: 'text' },
        { name: 'dict_word_remark', type: 'text' },
        { name: 'is_delete', type: 'number', default: 0, min: 0, max: 1, onlyInt: true },
    ],
    indexes: [
        'CREATE UNIQUE INDEX idx_system_dict_id ON tbl_system_dict (system_dict_id)',
        'CREATE UNIQUE INDEX idx_dict_name ON tbl_system_dict (dict_name)',
        'CREATE INDEX idx_dict_word_parent_id ON tbl_system_dict (dict_word_parent_id)',
    ],
};

function normalizeFieldPayload(field, existingField) {
    const payload = existingField
        ? Object.assign({}, existingField)
        : {
            name: field.name,
            type: field.type,
        };

    if (existingField && existingField.id) {
        payload.id = existingField.id;
    }

    payload.name = field.name;
    payload.type = field.type;

    if (typeof field.required !== 'undefined') {
        payload.required = field.required;
    }

    return payload;
}

function buildCollectionPayload(target, existingCollection) {
    if (!existingCollection) {
        return {
            name: target.name,
            type: target.type,
            listRule: target.listRule,
            viewRule: target.viewRule,
            createRule: target.createRule,
            updateRule: target.updateRule,
            deleteRule: target.deleteRule,
            fields: target.fields.map((field) => normalizeFieldPayload(field, null)),
            indexes: target.indexes,
        };
    }

    const targetFieldMap = new Map(target.fields.map((field) => [field.name, field]));
    const fields = (existingCollection.fields || []).map((existingField) => {
        const nextField = targetFieldMap.get(existingField.name);
        if (!nextField) {
            return existingField;
        }

        targetFieldMap.delete(existingField.name);
        return normalizeFieldPayload(nextField, existingField);
    });

    for (const field of targetFieldMap.values()) {
        fields.push(normalizeFieldPayload(field, null));
    }

    return {
        name: target.name,
        type: target.type,
        listRule: target.listRule,
        viewRule: target.viewRule,
        createRule: target.createRule,
        updateRule: target.updateRule,
        deleteRule: target.deleteRule,
        fields: fields,
        indexes: target.indexes,
    };
}

function normalizeFieldList(fields) {
    return (fields || []).map((field) => ({
        name: field.name,
        type: field.type,
        required: !!field.required,
    }));
}

async function createOrUpdateCollection(target) {
    console.log(`🔄 正在处理表: ${target.name} ...`);

    try {
        const existing = await pb.collections.getOne(target.name);
        await pb.collections.update(existing.id, buildCollectionPayload(target, existing));
        console.log(`♻️ ${target.name} 已存在，已按最新结构更新。`);
    } catch (error) {
        if (error.status === 404) {
            await pb.collections.create(buildCollectionPayload(target, null));
            console.log(`✅ ${target.name} 创建完成。`);
            return;
        }

        console.error(`❌ 处理集合 ${target.name} 失败:`, {
            status: error.status,
            message: error.message,
            response: error.response?.data,
        });
        throw error;
    }
}

async function verifyCollection(target) {
    console.log('\n🔍 开始校验字典表结构与索引...');
    const remote = await pb.collections.getOne(target.name);
    const remoteFields = normalizeFieldList(remote.fields);
    const targetFields = normalizeFieldList(target.fields);
    const remoteFieldMap = new Map(remoteFields.map((field) => [field.name, field.type]));
    const remoteRequiredMap = new Map(remoteFields.map((field) => [field.name, field.required]));
    const missingFields = [];
    const mismatchedTypes = [];
    const mismatchedRequired = [];

    for (const field of targetFields) {
        if (!remoteFieldMap.has(field.name)) {
            missingFields.push(field.name);
            continue;
        }

        if (remoteFieldMap.get(field.name) !== field.type) {
            mismatchedTypes.push(`${field.name}:${remoteFieldMap.get(field.name)}!=${field.type}`);
        }

        if (remoteRequiredMap.get(field.name) !== !!field.required) {
            mismatchedRequired.push(`${field.name}:${remoteRequiredMap.get(field.name)}!=${!!field.required}`);
        }
    }

    const remoteIndexes = new Set(remote.indexes || []);
    const missingIndexes = target.indexes.filter((indexSql) => !remoteIndexes.has(indexSql));

    if (!missingFields.length && !mismatchedTypes.length && !mismatchedRequired.length && !missingIndexes.length) {
        console.log(`✅ ${target.name} 校验通过。`);
        return;
    }

    if (missingFields.length) {
        console.log(`  - 缺失字段: ${missingFields.join(', ')}`);
    }
    if (mismatchedTypes.length) {
        console.log(`  - 字段类型不匹配: ${mismatchedTypes.join(', ')}`);
    }
    if (mismatchedRequired.length) {
        console.log(`  - 字段必填属性不匹配: ${mismatchedRequired.join(', ')}`);
    }
    if (missingIndexes.length) {
        console.log(`  - 缺失索引: ${missingIndexes.join(' | ')}`);
    }

    throw new Error(`${target.name} 结构与预期不一致`);
}

async function init() {
    try {
        console.log(`🔄 正在连接 PocketBase: ${PB_URL}`);
        pb.authStore.save(AUTH_TOKEN, null);
        console.log('✅ 已使用 POCKETBASE_AUTH_TOKEN 载入认证状态。');

        await createOrUpdateCollection(collectionData);
        await verifyCollection(collectionData);
        console.log('\n🎉 字典表结构初始化并校验完成！');
    } catch (error) {
        console.error('❌ 初始化失败:', error.response?.data || error.message);
        process.exitCode = 1;
    }
}

init();
