const express = require("express");
const router = express.Router();
const { instanceNumberBuilder } = require("../manager/instance_number_rules");
const objectql = require('@steedos/objectql');
const _ = require('lodash');
const UUFlowManager = require('../manager/uuflow_manager');
const { requireAuthentication } = require("@steedos/auth");
const { getCollection } = require('../utils/collection');

// 获取用户当前的 approve
const getUserApprove = ({ instance, userId }) => {
    const currentTrace = _.find(instance.traces, (trace) => {
        return trace.is_finished != true;
    });
    let currentApprove = null;
    if (currentTrace) {
        currentApprove = _.find(currentTrace.approves, (approve) => {
            return approve.is_finished != true && approve.handler == userId;
        });
    }

    //传阅的approve返回最新一条
    if (!currentApprove || currentApprove.type == "cc") {
        // 当前是传阅
        _.each(instance.traces, function (t) {
            _.each(t.approves, function (a) {
                if (a.type == "cc" && a.handler == userId && a.is_finished == false) {
                    currentApprove = a;
                }
            });
        });
    }

    if (!currentApprove) return;

    if (currentApprove._id) {
        currentApprove.id = currentApprove._id;
    }
    return currentApprove;
};

// ===== 新设计器 autoNumber 字段：基于字段配置直接生成编号 =====

// 序号补零
const padNumber = (num, length) => {
    if (length <= 0) return String(num);
    const str = String(num);
    return str.length >= length ? str : '0'.repeat(length - str.length) + str;
};

// 根据日期格式生成日期片段
const formatDatePart = (dateFormat, yyyy, mm, dd) => {
    const mmStr = mm < 10 ? '0' + mm : String(mm);
    const ddStr = dd < 10 ? '0' + dd : String(dd);
    switch (dateFormat) {
        case 'YYYY': return String(yyyy);
        case 'YYYYMM': return String(yyyy) + mmStr;
        case 'YYYYMMDD': return String(yyyy) + mmStr + ddStr;
        default: return ''; // 'none' 或 undefined
    }
};

// 根据重置周期判断是否需要重置序号
const shouldResetNumber = (resetCycle, storedRule, yyyy, mm, dd) => {
    switch (resetCycle) {
        case 'yearly': return yyyy !== storedRule.year;
        case 'monthly': return yyyy !== storedRule.year || mm !== storedRule.month;
        case 'daily': return yyyy !== storedRule.year || mm !== storedRule.month || dd !== storedRule.day;
        default: return false; // 'none' - 永不重置
    }
};

/**
 * 基于字段配置生成自动编号（新设计器 autoNumber 类型字段）
 * 同样使用 instance_number_rules 集合做序号持久化，如果尚未创建规则记录则自动创建
 */
const generateAutoNumberFromFieldConfig = async (spaceId, fieldConfig) => {
    const db = await getCollection("instance_number_rules");

    const ruleName = fieldConfig.auto_number_name;
    const prefix = fieldConfig.autoNumberPrefix || '';
    const suffix = fieldConfig.autoNumberSuffix || '';
    const paddingLen = fieldConfig.autoNumberPadding != null ? fieldConfig.autoNumberPadding : 4;
    const dateFormat = fieldConfig.autoNumberDateFormat || 'YYYYMM';
    const resetCycle = fieldConfig.autoNumberResetCycle || 'monthly';

    const now = new Date();
    const yyyy = now.getFullYear();
    const mm = now.getMonth() + 1;
    const dd = now.getDate();

    let numberRules = await db.findOne({ space: spaceId, name: ruleName });

    if (!numberRules) {
        // 首次使用该字段，自动创建规则记录
        await db.insertOne({
            space: spaceId,
            name: ruleName,
            year: yyyy,
            month: mm,
            day: dd,
            first_number: 1,
            number: 0,
            rules: '' // 新类型字段不使用 rules 模板
        });
        numberRules = await db.findOne({ space: spaceId, name: ruleName });
    }

    let nextNumber = (numberRules.number || 0) + 1;

    if (shouldResetNumber(resetCycle, numberRules, yyyy, mm, dd)) {
        nextNumber = numberRules.first_number || 1;
    }

    const paddedNumber = padNumber(nextNumber, paddingLen);
    const datePart = formatDatePart(dateFormat, yyyy, mm, dd);
    const autoNumber = prefix + datePart + paddedNumber + suffix;

    await db.updateOne(
        { _id: numberRules._id },
        { $set: { year: yyyy, month: mm, day: dd, number: nextNumber } }
    );

    return autoNumber;
};

// 获取可编辑的自动编号字段
const getEditableAutoNumberFields = async (step, formId, formVersion) => {
    const permissions = step.permissions || {};
    const form = await UUFlowManager.getForm(formId);
    const formV = await UUFlowManager.getFormVersion(form, formVersion);
    
    const autoNumberFields = [];
    const pushedFieldKeys = new Set();

    const getFieldKey = (field) => field?.code || field?.name;
    const isAutoNumberTypeField = (field) => {
        const fieldType = (field?.type || '').toString().toLowerCase();
        return fieldType === 'autonumber' || field?.type === 'autoNumber';
    };
    const canGenerateAutoNumber = (field) => {
        const fieldKey = getFieldKey(field);
        if (!fieldKey) return false;
        const permission = permissions[fieldKey];
        if (permission === 'editable') return true;
        return false;
    };
    
    // 检查字段是否是自动编号字段（通过 formula 判断）
    const isAutoNumberField = (field) => {
        if (!field) return false;
        const hasLegacyAutoNumberFormula = field.default_value && typeof field.default_value === 'string' && field.default_value.trim().startsWith('auto_number(');
        return hasLegacyAutoNumberFormula || isAutoNumberTypeField(field);
    };
    
    // 从 formula 中提取自动编号规则名称
    const extractAutoNumberName = (formula) => {
        // 匹配 auto_number("xxx") 或 auto_number('xxx') 或 auto_number(xxx)
        const match = formula.match(/auto_number\s*\(\s*['"]?([^'"()]+?)['"]?\s*\)/);
        return match ? match[1].trim() : null;
    };

    const getAutoNumberRuleName = (field) => {
        // 1) 兼容旧字段公式：default_value = auto_number(...)
        if (field?.default_value && typeof field.default_value === 'string') {
            const byFormula = extractAutoNumberName(field.default_value);
            if (byFormula) return byFormula;
        }

        // 2) 兼容常见字段属性命名
        const fromProps =
            field?.auto_number_name ||
            field?.autoNumberName ||
            field?.auto_number_rule ||
            field?.autoNumberRule ||
            field?.auto_number_rule_name ||
            field?.autoNumberRuleName;
        if (fromProps && typeof fromProps === 'string') {
            return fromProps.trim();
        }

        // 3) 对于新设计器 autoNumber 字段，默认回退到字段标识（code/name）
        return getFieldKey(field);
    };

    const tryPushAutoNumberField = (field) => {
        if (!isAutoNumberField(field) || !canGenerateAutoNumber(field)) {
            return;
        }
        const fieldKey = getFieldKey(field);
        const autoNumberName = getAutoNumberRuleName(field);
        if (!fieldKey || !autoNumberName || pushedFieldKeys.has(fieldKey)) {
            return;
        }
        pushedFieldKeys.add(fieldKey);

        const fieldInfo = {
            code: fieldKey,
            auto_number_name: autoNumberName,
        };

        // 新设计器 autoNumber 字段，携带配置属性用于直接生成编号
        if (isAutoNumberTypeField(field)) {
            fieldInfo.isNewType = true;
            fieldInfo.autoNumberPrefix = field.autoNumberPrefix;
            fieldInfo.autoNumberSuffix = field.autoNumberSuffix;
            fieldInfo.autoNumberPadding = field.autoNumberPadding;
            fieldInfo.autoNumberDateFormat = field.autoNumberDateFormat;
            fieldInfo.autoNumberResetCycle = field.autoNumberResetCycle;
        }

        autoNumberFields.push(fieldInfo);
    };

    for (const field of formV.fields || []) {
        if (field.type === "section") {
            // 处理 section 中的字段
            for (const sectionField of field.fields || []) {
                tryPushAutoNumberField(sectionField);
            }
        } else {
            // 处理普通字段
            tryPushAutoNumberField(field);
        }
    }
    
    return autoNumberFields;
};

router.post('/api/workflow/v2/auto_number', requireAuthentication, async function (req, res) {
    try {
        const userSession = req.user;
        const userId = userSession.userId;
        const { instanceId } = req.body;
        
        if (!instanceId) {
            return res.status(200).send({
                error: '缺少必填参数: instanceId'
            });
        }

        // 获取 instance 信息
        const instancesCollection = await objectql.getObject('instances');
        const instance = await instancesCollection.findOne(instanceId);
        
        if (!instance) {
            return res.status(200).send({
                error: '未找到该实例'
            });
        }

        // 获取当前用户的 approve
        const currentApprove = getUserApprove({ instance, userId });
        
        if (!currentApprove) {
            return res.status(200).send({
                error: '未找到当前用户的审批节点'
            });
        }

        // 如果是传阅类型，则不处理自动编号
        if (currentApprove.type === 'cc') {
            return res.status(200).send({
                success: true,
                message: '传阅节点不处理自动编号'
            });
        }

        // 查找当前 trace 和 approve 的位置
        let traceIndex = -1;
        let approveIndex = -1;
        
        for (let i = 0; i < instance.traces.length; i++) {
            const trace = instance.traces[i];
            if (trace.approves && trace.approves.length > 0) {
                const index = trace.approves.findIndex(app => app._id === currentApprove._id);
                if (index !== -1) {
                    traceIndex = i;
                    approveIndex = index;
                    break;
                }
            }
        }

        if (traceIndex === -1 || approveIndex === -1) {
            return res.status(200).send({
                error: '未找到对应的 trace 和 approve'
            });
        }

        const currentTrace = instance.traces[traceIndex];
        
        // 获取当前 step
        const flowsCollection = await objectql.getObject('flows');
        const flow = await flowsCollection.findOne(instance.flow);
        
        if (!flow) {
            return res.status(200).send({
                error: '未找到对应的流程'
            });
        }

        let step = null;
        if (flow.current && flow.current.steps) {
            step = flow.current.steps.find(s => s._id === currentTrace.step);
        }
        
        if (!step && flow.historys) {
            for (const h of flow.historys) {
                step = h.steps.find(s => s._id === currentTrace.step);
                if (step) break;
            }
        }

        if (!step) {
            return res.status(200).send({
                error: '未找到对应的步骤'
            });
        }

        // 获取可编辑的自动编号字段
        const autoNumberFields = await getEditableAutoNumberFields(step, instance.form, instance.form_version);
        if (autoNumberFields.length === 0) {
            return res.status(200).send({
                success: true,
                message: '当前步骤没有可编辑的自动编号字段'
            });
        }

        // 为每个自动编号字段生成编号
        const result = {};
        const updateObj = {};
        let currentValues = {}
        if(_.isEmpty(currentApprove.values)){
            currentValues = instance.values || {};
        }else{
            currentValues = currentApprove.values;
        }
        
        for (const field of autoNumberFields) {
            // 检查字段是否已有值
            if (currentValues && currentValues[field.code]) {
                result[field.code] = currentValues[field.code];
                continue;
            }
            
            let autoNumber;
            if (field.isNewType) {
                // 新设计器 autoNumber 字段：基于字段配置直接生成
                autoNumber = await generateAutoNumberFromFieldConfig(instance.space, field);
            } else {
                // 旧规则：通过预配置的 instance_number_rules 记录生成
                autoNumber = await instanceNumberBuilder(instance.space, field.auto_number_name);
            }
            
            if (autoNumber && autoNumber._error) {
                throw autoNumber._error;
            }
            
            result[field.code] = autoNumber;
            updateObj[`traces.${traceIndex}.approves.${approveIndex}.values.${field.code}`] = autoNumber;
        }

        // 更新 approve 的 values
        if (Object.keys(updateObj).length > 0) {
            await instancesCollection.update(instanceId, updateObj);
        }

        res.status(200).send({
            success: true,
            fields: result
        });
    } catch (error) {
        console.error(error);
        res.status(200).send({
            error: error.message
        });
    }
});


exports.default = router;