package org.dromara.biz.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.dromara.biz.domain.BizTask;
import org.dromara.biz.domain.bo.BizTaskBo;
import org.dromara.biz.domain.vo.BizTaskVo;
import org.dromara.biz.mapper.BizTaskMapper;
import org.dromara.biz.service.IBizTaskService;
import org.dromara.common.core.constant.WflowContants;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.wflow.bean.entity.WflowModelHistorys;
import org.dromara.wflow.mapper.WflowFormDataMapper;
import org.dromara.wflow.mapper.WflowModelHistorysMapper;
import org.dromara.wflow.workflow.bean.process.form.Form;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 流程数据Service业务层处理
 *
 * @author Blue
 * @date 2025-05-13
 */
@RequiredArgsConstructor
@Service
public class BizTaskServiceImpl implements IBizTaskService {

    private final BizTaskMapper baseMapper;

    private  final WflowFormDataMapper formDataMapper;

    private final RuntimeService runtimeService;

    private final WflowModelHistorysMapper historysMapper;

    public static final String default_type_field= WflowContants.NORMAL_MISSION_DEFAULT_TYPE_FIELD;
    public static final String default_title_fieldId = WflowContants.NORMAL_MISSION_DEFAULT_TITLE_FIELD;
    public static final String default_content_fieldId = WflowContants.NORMAL_MISSION_DEFAULT_CONTENT_FIELDID;
    public static final String default_level_fieldId = WflowContants.NORMAL_MISSION_DEFAULT_LEVEL_FIELD;
    public static final String default_file_fieldId = WflowContants.NORMAL_MISSION_DEFAULT_FILEID;
    public static final String default_image_fieldId = WflowContants.NORMAL_MISSION_DEFAULT_IMAGEID;

    /**
     * 查询流程数据
     *
     * @param id 主键
     * @return 流程数据
     */
    @Override
    public BizTaskVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询流程数据列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 流程数据分页列表
     */
    @Override
    public TableDataInfo<BizTaskVo> queryPageList(BizTaskBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<BizTask> lqw = buildQueryWrapper(bo);
        Page<BizTaskVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的流程数据列表
     *
     * @param bo 查询条件
     * @return 流程数据列表
     */
    @Override
    public List<BizTaskVo> queryList(BizTaskBo bo) {
        LambdaQueryWrapper<BizTask> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<BizTask> buildQueryWrapper(BizTaskBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<BizTask> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(BizTask::getId);
        lqw.like(StringUtils.isNotBlank(bo.getTitle()), BizTask::getTitle, bo.getTitle());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), BizTask::getType, bo.getType());
        lqw.eq(StringUtils.isNotBlank(bo.getRelationId()), BizTask::getRelationId, bo.getRelationId());
        lqw.eq(StringUtils.isNotBlank(bo.getLevel()), BizTask::getLevel, bo.getLevel());
        lqw.eq(StringUtils.isNotBlank(bo.getTaskNo()), BizTask::getTaskNo, bo.getTaskNo());
        lqw.eq(StringUtils.isNotBlank(bo.getContent()), BizTask::getContent, bo.getContent());
        lqw.eq(bo.getApplyUserId() != null, BizTask::getApplyUserId, bo.getApplyUserId());
        lqw.like(StringUtils.isNotBlank(bo.getApplyUserName()), BizTask::getApplyUserName, bo.getApplyUserName());
        lqw.eq(StringUtils.isNotBlank(bo.getApplyDeptId()), BizTask::getApplyDeptId, bo.getApplyDeptId());
        lqw.like(StringUtils.isNotBlank(bo.getApplyDeptName()), BizTask::getApplyDeptName, bo.getApplyDeptName());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), BizTask::getStatus, bo.getStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getInstanceStatus()), BizTask::getInstanceStatus, bo.getInstanceStatus());
        if (bo.getStartTimes() != null && bo.getStartTimes().length > 0) {
            lqw.ge(BizTask::getCreateTime, bo.getStartTimes()[0]);
            lqw.le(BizTask::getCreateTime, bo.getStartTimes()[1]);
        }
        return lqw;
    }

    /**
     * 新增流程数据
     *
     * @param bo 流程数据
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(BizTaskBo bo) {
        BizTask add = MapstructUtils.convert(bo, BizTask.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改流程数据
     *
     * @param bo 流程数据
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(BizTaskBo bo) {
        BizTask update = MapstructUtils.convert(bo, BizTask.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(BizTask entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除流程数据信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    @Override
    public void saveInstanceFormData(String instanceId, Map<String, Object> formData) {
        ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId(instanceId).singleResult();
        //提取表单字段信息
        WflowModelHistorys models = historysMapper.selectOne(new LambdaQueryWrapper<WflowModelHistorys>()
                .select(WflowModelHistorys::getFormItems)
                .eq(WflowModelHistorys::getProcessDefId, instance.getProcessDefinitionId()));
        Map<String, Form> formMap = loadFormItemsMap(models.getFormItems());
        BizTask build = new BizTask();
        formData.forEach((key, value) -> {
            if (value != null && formMap.containsKey(key)) {
                Form field = formMap.getOrDefault(key, new Form());
                String fieldKey = field.getId();

                if (fieldKey.equals(default_title_fieldId)) {
                    build.setTitle(coverToString(value));
                } else if (fieldKey.equals(default_content_fieldId)) {
                    build.setContent(coverToString(value));
                } else if (fieldKey.equals(default_level_fieldId)) {
                    build.setLevel(coverToString(value));
                } else if (fieldKey.equals(default_type_field)) {
                    build.setType(coverArrayToString(value));
                } else if (fieldKey.equals(default_image_fieldId)) {
                    build.setImage(coverToString(value));
                } else if (fieldKey.equals(default_file_fieldId)) {
                    build.setFile(coverToString(value));
                }
            }
        });

        build.setCreateTime(instance.getStartTime());
        build.setUpdateTime(instance.getStartTime());
        build.setApplyUserId(Long.valueOf(instance.getStartUserId()));
        build.setApplyUserName(Objects.requireNonNull(LoginHelper.getLoginUser()).getNickname());
        build.setApplyDeptId(String.valueOf(Objects.requireNonNull(LoginHelper.getLoginUser()).getDeptId()));
        build.setApplyDeptName(Objects.requireNonNull(LoginHelper.getLoginUser()).getDeptName());
        build.setTaskNo(instanceId);
        // 待本部门领导审批 状态(待本部门领导审批10、待分局领导审批20，待中心下发30，待民警办理40,待中心审批50，办结60)
        build.setStatus("10");
        build.setInstanceStatus(instance.getBusinessStatus());
        baseMapper.insert(build);
    }

    @Override
    public void updateInstanceFormData(String instanceId, Map<String, Object> formData) {
        ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId(instanceId).singleResult();
        if(Objects.isNull(instance)){
            return;
        }
        //提取表单字段信息
        WflowModelHistorys models = historysMapper.selectOne(new LambdaQueryWrapper<WflowModelHistorys>()
                .select(WflowModelHistorys::getFormItems)
                .eq(WflowModelHistorys::getProcessDefId, instance.getProcessDefinitionId()));
        Map<String, Form> formMap = loadFormItemsMap(models.getFormItems());
        BizTask build = new BizTask();
        //任务类型
        formData.forEach((key, value) -> {
            if (value != null && formMap.containsKey(key)) {
                Form field = formMap.getOrDefault(key, new Form());
                String fieldKey = field.getId();
                switch (fieldKey) {
                    case default_title_fieldId -> build.setTitle(coverToString(value));
                    case default_content_fieldId -> build.setContent(coverToString(value));
                    case default_level_fieldId -> build.setLevel(coverToString(value));
                    case default_type_field -> build.setType(coverArrayToString(value));
                    case default_image_fieldId -> build.setImage(coverToString(value));
                    case default_file_fieldId -> build.setFile(coverToString(value));
                }
            }
        });
//        build.setCreateTime(instance.getStartTime());
        build.setUpdateTime(instance.getStartTime());
//        build.setApplyUserId(Long.valueOf(instance.getStartUserId()));
//        build.setApplyUserName(Objects.requireNonNull(LoginHelper.getLoginUser()).getNickname());
//        build.setApplyDeptId(String.valueOf(Objects.requireNonNull(LoginHelper.getLoginUser()).getDeptId()));
//        build.setApplyDeptName(Objects.requireNonNull(LoginHelper.getLoginUser()).getDeptName());
        build.setTaskNo(instanceId);
        // 待本部门领导审批 状态(待本部门领导审批10、待分局领导审批20，待中心下发30，待民警办理40,待中心审批50，办结60)
        String businessStatus = instance.getBusinessStatus();
        if(businessStatus.equals("PASS")){
            build.setStatus(WflowContants.BIZ_TASK_STATUS_TO_CENTER_XIAFA);
        }else{
            build.setStatus(WflowContants.BIZ_TASK_STATUS_START);
        }
        build.setInstanceStatus(businessStatus);

        baseMapper.update(build, new LambdaUpdateWrapper<BizTask>()
                .eq(BizTask::getTaskNo, instanceId));

    }

    @Override
    public Boolean deleteByInstanceId(String instanceId) {
        LambdaUpdateWrapper<BizTask> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(BizTask::getTaskNo, instanceId);

        return baseMapper.delete(updateWrapper) > 0;
    }

    /**
     * 获取流程状态
     * @param instanceId
     * @return
     */
    @Override
    public BizTask getStatus(String instanceId) {
        LambdaQueryWrapper<BizTask> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.select(BizTask::getStatus);
//        queryWrapper.select(BizTask::getRedo);
//        queryWrapper.select(BizTask::getRedoReason);
        queryWrapper.select(BizTask::getRedoTime,BizTask::getRedoReason,BizTask::getRedo,BizTask::getStatus);
        queryWrapper.eq(BizTask::getTaskNo, instanceId);
        BizTask bizTask = baseMapper.selectOne(queryWrapper);
        return bizTask;
    }

    @Override
    public Boolean updateStatus(String taskNo, String status) {
        if(StringUtils.isNotBlank(status)){
            LambdaUpdateWrapper<BizTask> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(BizTask::getTaskNo, taskNo);
            updateWrapper.set(BizTask::getStatus, status);
            return baseMapper.update(null, updateWrapper) > 0;
        }
        return false;
    }

    /**
     * 加载表单配置为map
     *
     * @param formItems 表单配置
     * @return 表单map
     */
    public Map<String, Form> loadFormItemsMap(String formItems) {
        Map<String, Form> formMap = new HashMap<>();
        JSONArray.parseArray(formItems, Form.class).forEach(item -> {
            loadFormItems(formMap, item);
        });
        return formMap;
    }

    //递归加载表单配置
    private void loadFormItems(Map<String, Form> itemsMap, Form item) {
        if ("SpanLayout".equals(item.getName())) {
            JSONObject.from(item.getProps()).getJSONArray("items")
                    .toJavaList(Form.class).forEach(it -> loadFormItems(itemsMap, it));
        } else {
            itemsMap.put(item.getId(), item);
        }
    }

    protected boolean isSimpleType(Object value) {
        return null == value || value instanceof String || value instanceof Number || value instanceof Boolean;
    }

    protected boolean isDiff(Object oldVal, Object newVal) {
        if (isSimpleType(oldVal)) {
            return !Objects.equals(String.valueOf(oldVal), String.valueOf(newVal));
        }
        return !JSON.toJSONString(oldVal).equals(JSON.toJSONString(newVal));
    }

    protected String coverToString(Object val) {
        if (isSimpleType(val)) {
            return String.valueOf(val);
        }
        return JSON.toJSONString(val);
    }

    protected String coverArrayToString(Object val) {
        if (isSimpleType(val)) {
            return String.valueOf(val);
        }
        if(val instanceof ArrayList){
            return ((ArrayList) val).get(0).toString();
        }
        return JSON.toJSONString(val);
    }
}
