package com.mortals.xhx.module.doc.template.service.impl;

import cn.hutool.core.text.StrSpliter;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.XmlUtil;
import com.alibaba.fastjson.JSON;
import com.mortals.xhx.common.pdu.NodeEntity;
import com.mortals.xhx.common.pdu.gen.*;
import com.mortals.xhx.common.pdu.gen.component.ComponentCons;
import com.mortals.xhx.common.utils.ExportDocUtil;
import com.mortals.xhx.common.utils.StringUtils;
import com.mortals.xhx.module.doc.template.model.DocTemplateEntity;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.xhx.module.doc.template.dao.DocTemplateDao;
import com.mortals.xhx.module.doc.template.service.DocTemplateService;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import org.springframework.beans.factory.annotation.Autowired;
import com.mortals.xhx.module.doc.form.model.DocFormEntity;
import com.mortals.xhx.module.doc.form.model.DocFormQuery;
import com.mortals.xhx.module.doc.form.service.DocFormService;
import org.springframework.util.ObjectUtils;
import org.w3c.dom.Document;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * DocTemplateService
 * doc模板 service实现
 *
 * @author zxfei
 * @date 2021-10-16
 */
@Service("docTemplateService")
public class DocTemplateServiceImpl extends AbstractCRUDServiceImpl<DocTemplateDao, DocTemplateEntity, Long> implements DocTemplateService {
    @Autowired
    private DocFormService docFormService;


    @Value("${upload.path}")
    private String filePath;

    @Override
    protected void saveAfter(DocTemplateEntity entity, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(entity.getDocFormEntity())) {
            DocFormEntity subEntity = entity.getDocFormEntity();
            subEntity.setFormName(entity.getName() + "表单");
            subEntity.setTemplateId(entity.getId());
            subEntity.setCreateUser(context.getUser().getLoginName());
            subEntity.setCreateUserId(context.getUser().getId());
            subEntity.setCreateTime(new Date());
            docFormService.save(subEntity, context);
        }
        super.saveAfter(entity, context);
    }

    @Override
    protected void updateAfter(DocTemplateEntity entity, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(entity.getDocFormEntity()) && !ObjectUtils.isEmpty(entity.getDocFormEntity().getId())) {
            DocFormEntity subEntity = entity.getDocFormEntity();
            subEntity.setUpdateUser(context.getUser().getLoginName());
            subEntity.setUpdateUserId(context.getUser().getId());
            subEntity.setUpdateTime(new Date());
            docFormService.update(subEntity, context);
        }
        super.updateAfter(entity, context);
    }

    @Override
    protected void removeAfter(Long[] ids, Context context, int result) throws AppException {
        for (int i = 0; i < ids.length; i++) {
            Long[] formIds = docFormService.find(new DocFormQuery().templateId(ids[i]), context).stream().map(DocFormEntity::getId).toArray(Long[]::new);
            docFormService.remove(formIds, context);
        }
        super.removeAfter(ids, context, result);
    }

    @Override
    public void parseDocXml(DocTemplateEntity docTemplateVo, Context context) {
        //读文件
        String filepath = filePath + docTemplateVo.getTemplatePath();
        //正则找到所有el表达式
        List<NodeEntity> list = new ArrayList<>();
        Document document = ExportDocUtil.parseXMLFile(list, filepath);
        //校验与更新非标准el表达式
        ExportDocUtil.checkAndUpdateExpressionByDocument(document, list);
        //正在匹配所有图片，如果有，替换模板文件  图片标签暂定为 w:binData
        List<String> ids = ExportDocUtil.getIdsByTagName("w:binData", list);
        if (ids.size() > 0) {
            log.info("需要替换图片");
            for (int i = 0; i < ids.size(); i++) {
                List<String> paths = new ArrayList<>();
                NodeEntity nodeEntity = ExportDocUtil.getElementMapById(ids.get(i), list);
                if (!ObjectUtils.isEmpty(nodeEntity)) {
                    //判断内容如果是${} 这不在解析
                    paths.add(nodeEntity.getTagName());
                    ExportDocUtil.getPath(paths, list, nodeEntity.getParentId());
                    String el = String.format("${image_%s_图片%s}", i, i);
                    ExportDocUtil.parseTemplateImage(paths, el, document);
                    nodeEntity.setContent(el);
                }
            }
        }

        //重新更新list
        list = new ArrayList<>();
        ExportDocUtil.parseDocument(list, document);
        //解析替换多选框值
        //获取所有存在el表达式节点值 并去重复
        List<NodeEntity> elList = list.stream().map(item -> {
            if (!"".equals(item.getContent())) {
                return item;
            }
            return null;
        }).filter(f -> f != null).collect(Collectors.toList());
        List<NodeEntity> newList = new ArrayList<>();

        for (NodeEntity nodeEntity : elList) {
            String content = nodeEntity.getContent();
            boolean bool = false;
            for (NodeEntity nodeEntity1 : newList) {
                if (!ObjectUtils.isEmpty(content) && content.equals(nodeEntity1.getContent())) {
                    bool = true;
                    break;
                }
            }
            if (!bool) {
                newList.add(nodeEntity);
            }
        }
        //根据el表达式 动态创建表单组件
        GenRoot root = new GenRoot();
        root.initAttribute();
        for (int i = 0; i < newList.size(); i++) {
            NodeEntity item = newList.get(i);
            //判断是否有多个el表达式
            List<String> elGroups = StrSpliter.split(item.getContent(), ";", true, true);
            for (int j = 0; j < elGroups.size(); j++) {
                String el = elGroups.get(j);
                String val = StrUtil.strip(el, "${", "}");
                List<String> keys = StrSpliter.split(val, "_", true, true);
                //切分分隔符后动态 创建组件  i_1_姓名（第一个代表类型，第二个如果是多个累加，第三个显示label）
                if (keys.size() > 2) {
                    String label = keys.get(2);
                    String type = keys.get(0);
                    // FieldsItem fieldItem = null;
                    //todo
                    ComponentCons cons = new ComponentCons();
                    cons.setLabel(label);
                    cons.setVal(val);
                    cons.setEl(el);
                    cons.setNodeEntity(item);
                    cons.setList(list);
                    cons.setDocument(document);
                    Component component = Component.createType(type);
                    FieldsItem fieldItem = component.buildDefaultComponent(cons);


//                    if ("i".equalsIgnoreCase(type)) {
//                        //输入框，初始化输入组件
//                        fieldItem = root.createDefaultInput();
//                    } else if ("t".equalsIgnoreCase(type)) {
//                        //文本区域框
//                        fieldItem = root.createDefaultTextArea();
//                    } else if ("s".equalsIgnoreCase(type)) {
//                        //选择框
//                        fieldItem = root.createDefaultSelect();
//                        //判断如果包含年，月，日，选项框 基础化
//                        if (val.indexOf("年") != -1) {
//                            //初始化10年
//                            List<OptionsItem> optionsItems = initYears();
//                            fieldItem.getSlot().setOptions(optionsItems);
//                        } else if (val.indexOf("月") != -1) {
//                            List<OptionsItem> optionsItems = initMonths();
//                            fieldItem.getSlot().setOptions(optionsItems);
//                        } else if (val.indexOf("日") != -1) {
//                            List<OptionsItem> optionsItems = initDays();
//                            fieldItem.getSlot().setOptions(optionsItems);
//                        }
//
//                        if (label.indexOf("[") != -1) {
//                            //初始选项框
//                        }
//                    } else if ("date".equalsIgnoreCase(type)) {
//                        //年月日日期选择
//                        fieldItem = root.createDefaultDatePicker();
//                    } else if ("area".equalsIgnoreCase(type)) {
//                        //区域级联选择
//                    } else if ("image".equalsIgnoreCase(type)) {
//                        //图片选择
//                        fieldItem = root.createDefaultImage();
//                    } else if ("ck".equalsIgnoreCase(type)) {
//                        //复选框
//                        fieldItem = root.createDefaultCheckBox();
//                        if (label.indexOf("[") != -1) {
//                            String cks = StringUtils.substringBetween(label, "[", "]");
//                            List<OptionsItem> optionsItemList = StrUtil.splitTrim(cks, "-", -1).stream().map(option -> {
//                                OptionsItem optionsItem = new OptionsItem();
//                                optionsItem.setLabel(option);
//                                optionsItem.setValue(option);
//                                return optionsItem;
//                            }).collect(Collectors.toList());
//                            fieldItem.getSlot().setOptions(optionsItemList);
//
//                            val = val.substring(0, val.indexOf("["));
//                            label = label.substring(0, label.indexOf("["));
//                            //修改模板文件 通过id 查询xpath路径
//                            String parentId = item.getParentId();
//                            List<String> paths = new ArrayList<>();
//                            //paths.add(item.getTagName());
//                            ExportDocUtil.getPath(paths, list, parentId);
//                            String elpress = String.format("${%s}", val);
//                            ExportDocUtil.replaceTemplateEl(paths, elpress, el, document);
//                            item.setContent(elpress);
//                        }
//                    } else if ("btn".equalsIgnoreCase(type)) {
//                        //按钮事件
//                        fieldItem = root.createDefaultButton();
//                        //设置按钮事件 事件名为click+modelkey
//                        fieldItem.getOn().setClick("click" + val);
//
//                    }
                    //显示的label
                    fieldItem.getConfig().setLabel(cons.getLabel());
                    Integer formId = 100 + i + j;
                    fieldItem.getConfig().setFormId(formId);
                    fieldItem.getConfig().setRenderKey(formId + RandomUtil.randomNumbers(13));
                    //设定输入框绑定的key
                    fieldItem.setVModel(cons.getVal());
                    root.getFields().add(fieldItem);
                }
            }
        }
        //判断如果有按钮 添加方法名
        root.getFields().stream().peek(item -> {
            if (item.getOn() != null) {
                if (ObjectUtils.isEmpty(root.getMethods())) {
                    Methods methods = new Methods();
                    methods.getMethods().add(item.getOn().getClick());
                    root.setMethods(methods);
                } else {
                    root.getMethods().getMethods().add(item.getOn().getClick());
                }
            }
        }).count();

        XmlUtil.toFile(document, filepath);
        DocFormEntity docFormEntity = docFormService.selectOne(new DocFormQuery().templateId(docTemplateVo.getId()));
        if (ObjectUtils.isEmpty(docFormEntity)) {
            docFormEntity = new DocFormEntity();
            docFormEntity.setFormContent(JSON.toJSONString(root));
            docFormEntity.setFormName(docTemplateVo.getName() + "表单");
            docFormEntity.setTemplateId(docTemplateVo.getId());
            docFormEntity.setCreateTime(new Date());
            docFormEntity.setCreateUser(context.getUser().getLoginName());
            docFormService.save(docFormEntity, context);
        } else {
            //todo 解析转换 计算交集，id用modelkey
//            GenRoot genRoot = JSON.parseObject(docFormEntity.getFormContent(), new TypeReference<GenRoot>() {
//            });
            docFormEntity.setFormContent(JSON.toJSONString(root));
            docFormEntity.setUpdateTime(new Date());
            docFormEntity.setUpdateUser(context.getUser().getLoginName());
            docFormService.update(docFormEntity, context);
        }
    }

    public List<OptionsItem> initYears() {
        List<OptionsItem> list = new ArrayList<>();
        for (int i = 2020; i < 2030; i++) {
            OptionsItem optionsItem = new OptionsItem();
            optionsItem.setLabel(i + "");
            optionsItem.setValue(i + "");
            list.add(optionsItem);
        }
        return list;
    }

    public List<OptionsItem> initMonths() {
        List<OptionsItem> list = new ArrayList<>();
        for (int i = 1; i <= 12; i++) {
            OptionsItem optionsItem = new OptionsItem();
            optionsItem.setLabel(i + "");
            optionsItem.setValue(i + "");
            list.add(optionsItem);
        }
        return list;
    }

    public List<OptionsItem> initDays() {
        List<OptionsItem> list = new ArrayList<>();
        for (int i = 1; i <= 31; i++) {
            OptionsItem optionsItem = new OptionsItem();
            optionsItem.setLabel(i + "");
            optionsItem.setValue(i + "");
            list.add(optionsItem);
        }
        return list;
    }

}