package com.yunzhupaas.message.service.impl;

import com.yunzhupaas.base.service.SuperServiceImpl;
import com.yunzhupaas.base.ActionResult;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.database.model.superQuery.ConditionJsonModel;
import com.yunzhupaas.database.model.superQuery.SuperQueryConditionModel;
import com.yunzhupaas.exception.DataException;
import com.yunzhupaas.message.entity.MessageTemplateConfigEntity;
import com.yunzhupaas.message.entity.SmsFieldEntity;
import com.yunzhupaas.message.entity.TemplateParamEntity;
import com.yunzhupaas.message.mapper.MessageTemplateConfigMapper;
import com.yunzhupaas.message.model.messagetemplateconfig.MessageTemplateConfigForm;
import com.yunzhupaas.message.model.messagetemplateconfig.MessageTemplateConfigPagination;
import com.yunzhupaas.message.model.messagetemplateconfig.TemplateParamModel;
import com.yunzhupaas.message.service.MessageTemplateConfigService;
import com.yunzhupaas.message.service.SmsFieldService;
import com.yunzhupaas.message.service.TemplateParamService;
import cn.hutool.core.util.ObjectUtil;
import com.yunzhupaas.permission.service.AuthorizeService;
import java.lang.reflect.Field;
import com.baomidou.mybatisplus.annotation.TableField;
import com.yunzhupaas.util.DateUtil;
import com.yunzhupaas.util.JsonUtil;
import com.yunzhupaas.util.StringUtil;
import com.yunzhupaas.util.UserProvider;
import com.yunzhupaas.util.visiual.YunzhupaasKeyConsts;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 消息模板（新）
 * 版本： V3.2.0
 * 版权： 深圳市乐程软件有限公司（http://www.szlecheng.cn）
 * 作者： 云筑产品开发平台组
 * 日期： 2022-08-18
 */
@Service
public class MessageTemplateConfigServiceImpl
        extends SuperServiceImpl<MessageTemplateConfigMapper, MessageTemplateConfigEntity>
        implements MessageTemplateConfigService {

    @Autowired
    private TemplateParamService templateParamService;

    @Autowired
    private SmsFieldService smsFieldService;

    @Override
    public List<MessageTemplateConfigEntity> getList(MessageTemplateConfigPagination MessageTemplateConfigPagination) {
        return getTypeList(MessageTemplateConfigPagination, MessageTemplateConfigPagination.getDataType());
    }

    @Override
    public List<MessageTemplateConfigEntity> getTypeList(
            MessageTemplateConfigPagination MessageTemplateConfigPagination, String dataType) {
        String userId = UserProvider.getUser().getUserId();
        int total = 0;
        int messageTemplateNewNum = 0;
        QueryWrapper<MessageTemplateConfigEntity> messageTemplateNewQueryWrapper = new QueryWrapper<>();
        int templateParamNum = 0;
        QueryWrapper<TemplateParamEntity> templateParamQueryWrapper = new QueryWrapper<>();
        int smsFieldNum = 0;
        QueryWrapper<SmsFieldEntity> smsFieldQueryWrapper = new QueryWrapper<>();
        // 关键字
        if (ObjectUtil.isNotEmpty(MessageTemplateConfigPagination.getKeyword())) {
            messageTemplateNewNum++;
            messageTemplateNewQueryWrapper.lambda().and(t -> t
                    .like(MessageTemplateConfigEntity::getEnCode, MessageTemplateConfigPagination.getKeyword()).or()
                    .like(MessageTemplateConfigEntity::getFullName, MessageTemplateConfigPagination.getKeyword()));
        }
        // 模板类型
        if (ObjectUtil.isNotEmpty(MessageTemplateConfigPagination.getTemplateType())) {
            messageTemplateNewNum++;
            messageTemplateNewQueryWrapper.lambda().eq(MessageTemplateConfigEntity::getTemplateType,
                    MessageTemplateConfigPagination.getTemplateType());
        }
        // 消息类型
        if (ObjectUtil.isNotEmpty(MessageTemplateConfigPagination.getMessageType())) {
            messageTemplateNewNum++;
            messageTemplateNewQueryWrapper.lambda().eq(MessageTemplateConfigEntity::getMessageType,
                    MessageTemplateConfigPagination.getMessageType());
        }
        // 消息来源
        if (ObjectUtil.isNotEmpty(MessageTemplateConfigPagination.getMessageSource())) {
            messageTemplateNewNum++;
            messageTemplateNewQueryWrapper.lambda().eq(MessageTemplateConfigEntity::getMessageSource,
                    MessageTemplateConfigPagination.getMessageSource());
        }
        // 状态
        if (ObjectUtil.isNotEmpty(MessageTemplateConfigPagination.getEnabledMark())) {
            messageTemplateNewNum++;
            int enabledMark = Integer.parseInt(MessageTemplateConfigPagination.getEnabledMark());
            messageTemplateNewQueryWrapper.lambda().eq(MessageTemplateConfigEntity::getEnabledMark, enabledMark);
        }

        // 排序
        if (StringUtil.isEmpty(MessageTemplateConfigPagination.getSidx())) {
            messageTemplateNewQueryWrapper.lambda().orderByAsc(MessageTemplateConfigEntity::getSortCode)
                    .orderByDesc(MessageTemplateConfigEntity::getCreatorTime)
                    .orderByDesc(MessageTemplateConfigEntity::getLastModifyTime);
        } else {
            try {
                String sidx = MessageTemplateConfigPagination.getSidx();
                MessageTemplateConfigEntity MessageTemplateConfigEntity = new MessageTemplateConfigEntity();
                Field declaredField = MessageTemplateConfigEntity.getClass().getDeclaredField(sidx);
                declaredField.setAccessible(true);
                String value = declaredField.getAnnotation(TableField.class).value();
                messageTemplateNewQueryWrapper = "asc".equals(MessageTemplateConfigPagination.getSort().toLowerCase())
                        ? messageTemplateNewQueryWrapper.orderByAsc(value)
                        : messageTemplateNewQueryWrapper.orderByDesc(value);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }
        if (!"1".equals(dataType)) {
            if (total > 0 || total == 0) {
                Page<MessageTemplateConfigEntity> page = new Page<>(MessageTemplateConfigPagination.getCurrentPage(),
                        MessageTemplateConfigPagination.getPageSize());
                IPage<MessageTemplateConfigEntity> userIPage = this.page(page, messageTemplateNewQueryWrapper);
                return MessageTemplateConfigPagination.setData(userIPage.getRecords(), userIPage.getTotal());
            } else {
                List<MessageTemplateConfigEntity> list = new ArrayList();
                return MessageTemplateConfigPagination.setData(list, list.size());
            }
        } else {
            return this.list(messageTemplateNewQueryWrapper);
        }
    }

    @Override
    public MessageTemplateConfigEntity getInfo(String id) {
        QueryWrapper<MessageTemplateConfigEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MessageTemplateConfigEntity::getId, id);
        return this.getOne(queryWrapper);
    }

    @Override
    public MessageTemplateConfigEntity getInfoByEnCode(String enCode, String messageType) {
        QueryWrapper<MessageTemplateConfigEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MessageTemplateConfigEntity::getEnCode, enCode);
        queryWrapper.lambda().eq(MessageTemplateConfigEntity::getMessageType, messageType);
        return this.getOne(queryWrapper);
    }

    @Override
    public void create(MessageTemplateConfigEntity entity) {
        this.save(entity);
    }

    @Override
    public boolean update(String id, MessageTemplateConfigEntity entity) {
        entity.setId(id);
        return this.updateById(entity);
    }

    @Override
    public void delete(MessageTemplateConfigEntity entity) {
        if (entity != null) {
            this.removeById(entity.getId());
        }
    }

    // 子表方法
    @Override
    public List<TemplateParamEntity> getTemplateParamList(String id,
            MessageTemplateConfigPagination MessageTemplateConfigPagination) {
        QueryWrapper<TemplateParamEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TemplateParamEntity::getTemplateId, id);
        return templateParamService.list(templateParamService.getChild(MessageTemplateConfigPagination, queryWrapper));
    }

    @Override
    public List<TemplateParamEntity> getTemplateParamList(String id) {
        QueryWrapper<TemplateParamEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TemplateParamEntity::getTemplateId, id);
        return templateParamService.list(queryWrapper);
    }

    @Override
    public List<SmsFieldEntity> getSmsFieldList(String id,
            MessageTemplateConfigPagination MessageTemplateConfigPagination) {
        QueryWrapper<SmsFieldEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SmsFieldEntity::getTemplateId, id);
        return smsFieldService.list(smsFieldService.getChild(MessageTemplateConfigPagination, queryWrapper));
    }

    @Override
    public List<SmsFieldEntity> getSmsFieldList(String id) {
        QueryWrapper<SmsFieldEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SmsFieldEntity::getTemplateId, id);
        return smsFieldService.list(queryWrapper);
    }

    // 验证表单唯一字段
    @Override
    public boolean checkForm(MessageTemplateConfigForm form, int i, String id) {
        int total = 0;
        if (ObjectUtil.isNotEmpty(form.getEnCode())) {
            QueryWrapper<MessageTemplateConfigEntity> codeWrapper = new QueryWrapper<>();
            codeWrapper.lambda().eq(MessageTemplateConfigEntity::getEnCode, form.getEnCode());
            if (StringUtil.isNotBlank(id) && !"null".equals(id)) {
                codeWrapper.lambda().ne(MessageTemplateConfigEntity::getId, id);
            }
            if ((int) this.count(codeWrapper) > i) {
                total++;
            }
        }
        if (form.getTemplateParamList() != null) {
        }
        if (form.getSmsFieldList() != null) {
        }
        if (total > 0) {
            return true;
        }
        return false;
    }

    @Override
    public boolean isExistByFullName(String fullName, String id) {
        QueryWrapper<MessageTemplateConfigEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MessageTemplateConfigEntity::getFullName, fullName);
        if (!StringUtil.isEmpty(id)) {
            queryWrapper.lambda().ne(MessageTemplateConfigEntity::getId, id);
        }
        return this.count(queryWrapper) > 0 ? true : false;
    }

    @Override
    public boolean isExistByEnCode(String enCode, String id) {
        QueryWrapper<MessageTemplateConfigEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MessageTemplateConfigEntity::getEnCode, enCode);
        if (!StringUtil.isEmpty(id)) {
            queryWrapper.lambda().ne(MessageTemplateConfigEntity::getId, id);
        }
        return this.count(queryWrapper) > 0 ? true : false;
    }

    @Override
    public ActionResult ImportData(MessageTemplateConfigEntity entity) throws DataException {
        if (entity != null) {
            // if (isExistByFullName(entity.getFullName(), null)) {
            // return ActionResult.fail(MsgCode.EXIST001.get());
            // }
            if (isExistByEnCode(entity.getEnCode(), entity.getId())) {
                return ActionResult.fail(MsgCode.EXIST002.get());
            }
            try {
                this.save(entity);
            } catch (Exception e) {
                throw new DataException(MsgCode.IMP003.get());
            }
            return ActionResult.success(MsgCode.IMP001.get());
        }
        return ActionResult.fail(MsgCode.IMP006.get());
    }

    @Override
    public List<TemplateParamModel> getParamJson(String id) {
        MessageTemplateConfigEntity entity = getInfo(id);
        List<TemplateParamModel> paramModelList = new ArrayList<>();
        List<String> smsField = new ArrayList<>();
        List<String> paramList = new ArrayList<>();
        if (entity != null) {
            if ("3".equals(entity.getMessageType()) || "7".equals(entity.getMessageType())) {
                List<SmsFieldEntity> smsFieldList = smsFieldService.getDetailListByParentId(id);
                for (SmsFieldEntity entity1 : smsFieldList) {
                    if (!"@flowLink".equals(entity1.getField())) {
                        smsField.add(entity1.getField());
                    }
                }
                List<TemplateParamEntity> paramFieldList = templateParamService.getDetailListByParentId(id);
                for (TemplateParamEntity entity1 : paramFieldList) {
                    if (smsField.contains(entity1.getField())) {
                        TemplateParamModel paramModel = new TemplateParamModel();
                        paramModel.setTemplateId(entity.getId());
                        paramModel.setTemplateCode(entity.getEnCode());
                        paramModel.setTemplateType(entity.getTemplateType());
                        paramModel.setField(entity1.getField());
                        paramModel.setFieldName(entity1.getFieldName());
                        paramModel.setId(entity1.getId());
                        paramModel.setTemplateName(entity.getFullName());
                        paramModelList.add(paramModel);
                    }
                }
            } else {
                String content = StringUtil.isNotEmpty(entity.getContent()) ? entity.getContent() : "";
                String title = StringUtil.isNotEmpty(entity.getTitle()) ? entity.getTitle() : "";
                Set<String> list = new HashSet<>();
                list.addAll(regexContent(content));
                list.addAll(regexContent(title));
                List<TemplateParamEntity> paramFieldList = templateParamService.getDetailListByParentId(id);
                for (TemplateParamEntity entity1 : paramFieldList) {
                    TemplateParamModel paramModel = new TemplateParamModel();
                    paramModel.setTemplateId(entity.getId());
                    paramModel.setTemplateCode(entity.getEnCode());
                    paramModel.setTemplateType(entity.getTemplateType());
                    paramModel.setField(entity1.getField());
                    paramModel.setFieldName(entity1.getFieldName());
                    paramModel.setId(entity1.getId());
                    paramModel.setTemplateName(entity.getFullName());
                    if (list.contains(entity1.getField())) {
                        if (!"@FlowLink".equals(entity1.getField())
                                && !"@CreatorUserName".equals(entity1.getField())
                                && !"@SendTime".equals(entity1.getField())
                                && !"@Mandator".equals(entity1.getField())
                                && !"@Mandatary".equals(entity1.getField())) {
                            paramModelList.add(paramModel);
                        }
                    }
                }
            }
        }
        // 将参数模板转为json格式数据
        // String data = JsonUtil.getObjectToString(paramModelList);
        return paramModelList;
    }

    // 获取消息内容参数
    public List<String> regexContent(String content) {
        List<String> list = new ArrayList<>();
        String pattern = "[{]([^}]+)[}]";
        Pattern patternList = Pattern.compile(pattern);
        Matcher m = patternList.matcher(content);
        while (m.find()) {
            String group = m.group().replaceAll("\\{", "").replaceAll("}", "");
            list.add(group);
        }
        return list;
    }

    /**
     * 高级查询
     *
     * @param conditionModel
     * @param entity
     * @param num
     * @return
     */
    public Integer getCondition(SuperQueryConditionModel conditionModel, Object entity, int num) {
        QueryWrapper<?> queryWrapper = conditionModel.getObj();
        List<ConditionJsonModel> queryConditionModels = conditionModel.getConditionList();
        String op = conditionModel.getMatchLogic();
        String tableName = conditionModel.getTableName();
        List<ConditionJsonModel> useCondition = new ArrayList<>();
        for (ConditionJsonModel queryConditionModel : queryConditionModels) {
            if (queryConditionModel.getTableName().equalsIgnoreCase(tableName)) {
                if (queryConditionModel.getField().contains("yunzhupaas")) {
                    String child = queryConditionModel.getField();
                    String s1 = child.substring(child.lastIndexOf("yunzhupaas_")).replace("yunzhupaas_", "");
                    queryConditionModel.setField(s1);
                }
                if (queryConditionModel.getField().toLowerCase().startsWith(YunzhupaasKeyConsts.CHILD_TABLE_PREFIX)) {
                    String child = queryConditionModel.getField();
                    String s1 = child.substring(child.indexOf("-") + 1);
                    queryConditionModel.setField(s1);
                }
                useCondition.add(queryConditionModel);
            }
        }

        if (queryConditionModels.size() < 1 || useCondition.size() < 1) {
            return num;
        }
        if (useCondition.size() > 0) {
            num += 1;
        }
        // 处理控件 转换为有效值
        for (ConditionJsonModel queryConditionModel : useCondition) {
            String yunzhupaasKey = queryConditionModel.getYunzhupaasKey();
            String fieldValue = queryConditionModel.getFieldValue();
            if (yunzhupaasKey.equals(YunzhupaasKeyConsts.DATE)) {
                Long o1 = Long.valueOf(fieldValue);
                String startTime = DateUtil.daFormat(o1);
                queryConditionModel.setFieldValue(startTime);
            } else if (yunzhupaasKey.equals(YunzhupaasKeyConsts.CREATETIME)
                    || yunzhupaasKey.equals(YunzhupaasKeyConsts.MODIFYTIME)) {
                Long o1 = Long.valueOf(fieldValue);
                String startTime = DateUtil.daFormatHHMMSS(o1);
                queryConditionModel.setFieldValue(startTime);
            } else if (yunzhupaasKey.equals(YunzhupaasKeyConsts.CURRORGANIZE)) {
                List<String> orgList = JsonUtil.getJsonToList(fieldValue, String.class);
                queryConditionModel.setFieldValue(orgList.get(orgList.size() - 1));
            }
        }
        // 反射获取数据库实际字段
        Class<?> aClass = entity.getClass();

        queryWrapper.and(tw -> {
            for (ConditionJsonModel conditionJsonModel : useCondition) {
                String conditionField = conditionJsonModel.getField();
                Field declaredField = null;
                try {
                    declaredField = aClass.getDeclaredField(conditionField);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                }
                declaredField.setAccessible(true);
                String field = declaredField.getAnnotation(TableField.class).value();
                String fieldValue = conditionJsonModel.getFieldValue();
                String symbol = conditionJsonModel.getSymbol();
                if ("AND".equalsIgnoreCase(op)) {
                    if (symbol.equals("==")) {
                        tw.eq(field, fieldValue);
                    } else if (symbol.equals(">=")) {
                        tw.ge(field, fieldValue);
                    } else if (symbol.equals("<=")) {
                        tw.le(field, fieldValue);
                        tw.and(
                                qw -> qw.ne(field, ""));
                    } else if (symbol.equals(">")) {
                        tw.gt(field, fieldValue);
                    } else if (symbol.equals("<")) {
                        tw.lt(field, fieldValue);
                        tw.and(
                                qw -> qw.ne(field, ""));
                    } else if (symbol.equals("<>")) {
                        tw.ne(field, fieldValue);
                        if (StringUtil.isNotEmpty(fieldValue)) {
                            tw.or(
                                    qw -> qw.isNull(field));
                        }
                    } else if (symbol.equals("like")) {
                        if (StringUtil.isNotEmpty(fieldValue)) {
                            tw.like(field, fieldValue);
                        } else {
                            tw.isNull(field);
                        }
                    } else if (symbol.equals("notLike")) {
                        if (StringUtil.isNotEmpty(fieldValue)) {
                            tw.notLike(field, fieldValue);
                            tw.or(
                                    qw -> qw.isNull(field));
                        } else {
                            tw.isNotNull(field);
                        }
                    }
                } else {
                    if (symbol.equals("==")) {
                        tw.or(
                                qw -> qw.eq(field, fieldValue));
                    } else if (symbol.equals(">=")) {
                        tw.or(
                                qw -> qw.ge(field, fieldValue));
                    } else if (symbol.equals("<=")) {
                        tw.or(
                                qw -> qw.le(field, fieldValue));
                    } else if (symbol.equals(">")) {
                        tw.or(
                                qw -> qw.gt(field, fieldValue));
                    } else if (symbol.equals("<")) {
                        tw.or(
                                qw -> qw.lt(field, fieldValue));
                    } else if (symbol.equals("<>")) {
                        tw.or(
                                qw -> qw.ne(field, fieldValue));
                        if (StringUtil.isNotEmpty(fieldValue)) {
                            tw.or(
                                    qw -> qw.isNull(field));
                        }
                    } else if (symbol.equals("like")) {
                        if (StringUtil.isNotEmpty(fieldValue)) {
                            tw.or(
                                    qw -> qw.like(field, fieldValue));
                        } else {
                            tw.or(
                                    qw -> qw.isNull(field));
                        }
                    } else if (symbol.equals("notLike")) {
                        if (StringUtil.isNotEmpty(fieldValue)) {
                            tw.or(
                                    qw -> qw.notLike(field, fieldValue));
                            tw.or(
                                    qw -> qw.isNull(field));
                        } else {
                            tw.or(
                                    qw -> qw.isNotNull(field));
                        }
                    }
                }
            }
        });
        return num;
    }

}
