const converter = require('../util/templateConverter');
const _ = require('lodash');
const { MongoClient } = require('mongodb');

// MongoDB connection
let client = null;
let db = null;

async function connectToMongoDB() {
    if (db) {
        return db;
    }

    const mongoUrl = process.env.MONGO_URL || 'mongodb://127.0.0.1:27017/steedos';
    try {
        client = new MongoClient(mongoUrl);
        await client.connect();
        
        const dbName = mongoUrl.split('/').pop().split('?')[0];
        db = client.db(dbName);
        return db;
    } catch (error) {
        console.error('Failed to connect to MongoDB:', error.message);
        throw error;
    }
}

async function getCollection(name) {
    const database = await connectToMongoDB();
    return database.collection(name);
}

module.exports = {
    rest: {
        method: 'GET',
        fullPath: '/api/workflow/migrateTemplates'
    },
    params: {
        batchSize: { type: 'number', optional: true, convert: true },
        force: { type: 'boolean', optional: true, convert: true },
        flowId: { type: 'string', optional: true }
    },
    async handler(ctx) {
        const { user } = ctx.meta;

        if (user.is_space_admin !== true) {
            throw new Error('只有管理员才能执行此操作');
        }

        const { batchSize = 5000, force = false, flowId } = ctx.params;
        
        const flowsCollection = await getCollection('flows');
        const formsCollection = await getCollection('forms');

        let flows = [];
        if (flowId) {
            flows = await flowsCollection.find({ _id: flowId }).toArray();
        } else {
            let query = {
                $and: [
                    {
                        $or: [
                           { instance_template: { $exists: true, $ne: '' } },
                           { print_template: { $exists: true, $ne: '' } }
                        ]
                    }
                ]
            };

            if (!force) {
                query.$or = [
                    { migrate_status: { $ne: 'completed' } },
                    { migrate_status: { $exists: false } }
                ];
            }
            flows = await flowsCollection.find(query).limit(batchSize).toArray();
        }

        const results = {
            total: flows.length,
            success: 0,
            failed: 0,
            skipped: 0,
            details: []
        };

        for (const flow of flows) {
            const flowId = flow._id;
            const updateDoc = {};
            let isChanged = false;

            try {
                let fields = {};
                if (flow.form) {
                    const form = await formsCollection.findOne(
                        { _id: flow.form }, 
                        { projection: { 'current.fields': 1 } }
                    );
                    if (form && form.current && form.current.fields) {
                        fields = _.keyBy(form.current.fields, (f) => f.name || f.code);
                        fields._raw = form.current.fields;
                    }
                }

                if (!flow.backup_status) {
                    if (flow.instance_template) {
                        updateDoc.instance_template_backup = flow.instance_template;
                    }
                    if (flow.print_template) {
                        updateDoc.print_template_backup = flow.print_template;
                    }
                    updateDoc.backup_status = true;
                    isChanged = true;
                }

                const sourceInstance = updateDoc.instance_template_backup || flow.instance_template_backup || flow.instance_template;
                const sourcePrint = updateDoc.print_template_backup || flow.print_template_backup || flow.print_template;

                if (sourceInstance) {
                    const converted = converter.convertTemplate(sourceInstance, fields, false);
                    updateDoc.instance_template = converted;
                    isChanged = true;
                }

                if (sourcePrint) {
                    const converted = converter.convertTemplate(sourcePrint, fields, true);
                    updateDoc.print_template = converted;
                    isChanged = true;
                }

                updateDoc.migrate_status = 'completed';
                updateDoc.migrated_at = new Date();

                await flowsCollection.updateOne({ _id: flow._id }, { $set: updateDoc });
                
                results.success++;
                results.details.push({ id: flow._id, name: flow.name, status: 'success' });
            } catch (error) {
                console.error(`Error migrating flow ${flowId}:`, error);
                results.failed++;
                results.details.push({ id: flow._id, name: flow.name, status: 'error', error: error.message });
                
                try {
                    await flowsCollection.updateOne(
                        { _id: flow._id }, 
                        { $set: { migrate_status: 'error', migrate_error: error.message } }
                    );
                } catch (e) {}
            }
        }

        return results;
    }
}
