const _ = require('lodash');
const { getCollection } = require('../utils/collection');

function _getNumberRuleName(str) {
    if (_.isString(str) && str?.indexOf("auto_number(") > -1) {
        return str.replace("auto_number(", "").replace(")", "").replace(/["']/g, "");
    }
    return null;
}

async function _getFlowByForm(form, flowId, is_copy, company_id) {
    const query = { form };
    if (flowId) {
        query._id = flowId;
    }

    const flowsCollection = await getCollection('flows');
    const flows = await flowsCollection.find(query, { projection: { history: 0 } }).toArray();

    for (const flow of flows) {
        flow.historys = [];
        
        const objectWorkflowsCollection = await getCollection('object_workflows');
        flow.object_workflows = await objectWorkflowsCollection.find(
            { flow_id: flow._id },
            { 
                projection: { 
                    name: 1,
                    object_name: 1,
                    flow_id: 1,
                    field_map: 1,
                    field_map_back: 1,
                    field_map_script: 1,
                    field_map_back_script: 1,
                    sync_attachment: 1,
                    lock_record_after_approval: 1,
                    required_details: 1,
                }
            }
        ).toArray();

        if (!is_copy || (!company_id && flow.company_id) || (company_id && !flow.company_id) || (company_id !== flow.company_id)) {
            if (flow.current?.steps) {
                for (const step of flow.current.steps) {
                    // Process approver_roles
                    if (!_.isEmpty(step.approver_roles)) {
                        const flowRolesCollection = await getCollection('flow_roles');
                        const roles = await flowRolesCollection.find(
                            { _id: { $in: step.approver_roles } },
                            { projection: { name: 1, api_name: 1 } }
                        ).toArray();
                        
                        step.approver_roles_name = _.map(roles, 'name');
                        step.approver_roles_api_name = _.map(roles, 'api_name');
                    } else {
                        step.approver_roles_name = [];
                        step.approver_roles_api_name = [];
                    }

                    // Process approver_hr_roles
                    if (!_.isEmpty(step.approver_hr_roles)) {
                        const rolesCollection = await getCollection('roles');
                        const hrRoles = await rolesCollection.find(
                            { _id: { $in: step.approver_hr_roles } },
                            { projection: { name: 1, api_name: 1 } }
                        ).toArray();
                        
                        step.approver_hr_roles_name = _.map(hrRoles, 'name');
                        step.approver_hr_roles_api_name = _.map(hrRoles, 'api_name');
                    } else {
                        step.approver_hr_roles_name = [];
                        step.approver_hr_roles_api_name = [];
                    }
                }
            }
        }
    }
    return flows;
}

async function exportForm(formId, flowId, is_copy, company_id) {
    const formsCollection = await getCollection('forms');
    const form = await formsCollection.findOne(
        { _id: formId },
        { projection: { historys: 0 } }
    );

    if (!form) {
        return {};
    }

    form.historys = [];

    if (form?.category) {
        const categoriesCollection = await getCollection('categories');
        const category = await categoriesCollection.findOne(
            { _id: form.category },
            { projection: { name: 1 } }
        );
        if (category?.name) {
            form.category_name = category.name;
        }
    }

    const instance_number_rules = [];
    if (form.current) {
        const fields = [];
        const c_fields = form.current.fields;

        if (c_fields) {
            for (const f of c_fields) {
                if (f.type === 'table') {
                    console.log('ignore table field');
                } else if (f.type === 'section' && f.fields) {
                    fields.push(...f.fields);
                } else {
                    fields.push(f);
                }
            }
        }

        async function _getFieldNumberRule(spaceId, instance_number_rules, str) {
            const number_rule_name = _getNumberRuleName(str);
            if (!number_rule_name) return;

            const instanceNumberRulesCollection = await getCollection('instance_number_rules');
            
            if (number_rule_name.startsWith("{") && number_rule_name.endsWith("}")) {
                const fieldName = number_rule_name.substring(1, number_rule_name.length - 1);
                const field = c_fields.find(f => f.name === fieldName && f.type === 'select');
                
                if (field) {
                    const options = field.options.split("\n");
                    const rule_names = options.map(o => o.split(":")[1] || o.split(":")[0]);
                    
                    for (const rule_name of rule_names) {
                        const rule = await instanceNumberRulesCollection.findOne(
                            { space: spaceId, name: rule_name },
                            { projection: { _id: 1, name: 1, year: 1, first_number: 1, rules: 1 } }
                        );
                        
                        if (rule) {
                            rule.number = 0;
                            if (!instance_number_rules.some(r => r.name === rule.name)) {
                                delete rule._id;
                                instance_number_rules.push(rule);
                            }
                        }
                    }
                }
            } else {
                const number_rule = await instanceNumberRulesCollection.findOne(
                    { space: spaceId, name: number_rule_name },
                    { projection: { _id: 1, name: 1, year: 1, first_number: 1, rules: 1 } }
                );
                
                if (!number_rule) {
                    throw new Error(`not find instance number rule, name is ${number_rule_name}`);
                }
                
                number_rule.number = 0;
                if (!instance_number_rules.some(r => r.name === number_rule.name)) {
                    delete number_rule._id;
                    instance_number_rules.push(number_rule);
                }
            }
        }

        for (const f of fields) {
            await _getFieldNumberRule(form.space, instance_number_rules, f.default_value);
            await _getFieldNumberRule(form.space, instance_number_rules, f.formula);
        }
    }

    form.instance_number_rules = instance_number_rules;
    form.flows = await _getFlowByForm(formId, flowId, is_copy, company_id);
    return form;
}

module.exports = {
    exportForm
};