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 || '';

if (!AUTH_TOKEN) {
    console.error('❌ 缺少 POCKETBASE_AUTH_TOKEN，无法执行文件字段迁移。');
    process.exit(1);
}

const pb = new PocketBase(PB_URL);

function buildReplacementTextField(field) {
    return {
        name: field.name,
        type: 'text',
        required: !!field.required,
        hidden: !!field.hidden,
        presentable: typeof field.presentable === 'boolean' ? field.presentable : true,
    };
}

function buildCollectionPayload(remote, fields) {
    const payload = {
        name: remote.name,
        type: remote.type,
        fields: fields,
        indexes: remote.indexes || [],
        listRule: remote.listRule,
        viewRule: remote.viewRule,
        createRule: remote.createRule,
        updateRule: remote.updateRule,
        deleteRule: remote.deleteRule,
    };

    if (remote.name === 'tbl_attachments') {
        payload.listRule = '';
        payload.viewRule = '';
    }

    return payload;
}

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

    const collections = await pb.collections.getFullList({ sort: 'name' });
    const changed = [];

    for (const remote of collections) {
        const fileFields = (remote.fields || []).filter((field) => field.type === 'file');
        const shouldOpenAttachments = remote.name === 'tbl_attachments' && (remote.listRule !== '' || remote.viewRule !== '');

        if (!fileFields.length && !shouldOpenAttachments) {
            continue;
        }

        console.log(`🔄 正在处理集合: ${remote.name}`);
        if (remote.name === 'tbl_attachments') {
            await pb.collections.update(remote.id, buildCollectionPayload(remote, remote.fields || []));
        } else if (fileFields.length) {
            const remainingFields = (remote.fields || []).filter((field) => field.type !== 'file');
            await pb.collections.update(remote.id, buildCollectionPayload(remote, remainingFields));

            const refreshed = await pb.collections.getOne(remote.name);
            const replacementFields = fileFields.map((field) => buildReplacementTextField(field));
            await pb.collections.update(
                refreshed.id,
                buildCollectionPayload(refreshed, (refreshed.fields || []).concat(replacementFields)),
            );
        }

        changed.push({
            name: remote.name,
            convertedFileFields: remote.name === 'tbl_attachments'
                ? []
                : fileFields.map((field) => field.name),
            attachmentsRulesOpened: remote.name === 'tbl_attachments',
        });
    }

    return changed;
}

async function verifyResult() {
    const collections = await pb.collections.getFullList({ sort: 'name' });
    const residualFileFields = [];
    let attachmentsRules = null;

    for (const remote of collections) {
        for (const field of (remote.fields || [])) {
            if (field.type === 'file' && remote.name !== 'tbl_attachments') {
                residualFileFields.push(`${remote.name}.${field.name}`);
            }
        }

        if (remote.name === 'tbl_attachments') {
            attachmentsRules = {
                listRule: remote.listRule,
                viewRule: remote.viewRule,
            };
        }
    }

    if (residualFileFields.length) {
        throw new Error(`仍存在未迁移的 file 字段: ${residualFileFields.join(', ')}`);
    }

    if (!attachmentsRules || attachmentsRules.listRule !== '' || attachmentsRules.viewRule !== '') {
        throw new Error('tbl_attachments 的公开 list/view 规则未生效');
    }

    console.log('✅ 校验通过：除 tbl_attachments 外已无 file 字段。');
    console.log('✅ 校验通过：tbl_attachments 已开放公共 list/view。');
}

async function main() {
    try {
        const changed = await migrateCollections();
        console.log('📝 本次更新集合：');
        console.log(JSON.stringify(changed, null, 2));
        await verifyResult();
        console.log('🎉 文件字段迁移完成！');
    } catch (error) {
        console.error('❌ 文件字段迁移失败:', error.response?.data || error.message || error);
        process.exitCode = 1;
    }
}

main();
