package cn.com.tenlion.configtable.service.configtablefield.impl;

import cn.com.tenlion.configtable.pojo.dtos.configtable.ConfigTableDTO;
import cn.com.tenlion.configtable.pojo.dtos.configtableoperation.ConfigTableOperationDTO;
import cn.com.tenlion.configtable.service.configtable.IConfigTableService;
import cn.com.tenlion.configtable.service.configtableoperation.IConfigTableOperationSubService;
import cn.com.tenlion.freemarker.pojo.vos.templaterecord.TemplateRecordVO;
import cn.com.tenlion.freemarker.util.TemplateBuilderUtil;
import cn.com.tenlion.freemarker.util.TemplateCreateData;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.exceptions.SaveException;
import ink.wgink.exceptions.UpdateException;
import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.result.SuccessResultList;
import ink.wgink.util.map.HashMapUtil;
import ink.wgink.util.UUIDUtil;
import cn.com.tenlion.configtable.dao.configtablefield.IConfigTableFieldDao;
import cn.com.tenlion.configtable.pojo.dtos.configtablefield.ConfigTableFieldDTO;
import cn.com.tenlion.configtable.pojo.vos.configtablefield.ConfigTableFieldVO;
import cn.com.tenlion.configtable.pojo.bos.configtablefield.ConfigTableFieldBO;
import cn.com.tenlion.configtable.pojo.pos.configtablefield.ConfigTableFieldPO;
import cn.com.tenlion.configtable.service.configtablefield.IConfigTableFieldService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName: ConfigTableFieldServiceImpl
 * @Description: 
 * @Author: CodeFactory
 * @Date: 2021-06-24 11:06:57
 * @Version: 3.0
 **/
@Service
public class ConfigTableFieldServiceImpl extends DefaultBaseService implements IConfigTableFieldService {

    @Autowired
    private IConfigTableFieldDao configTableFieldDao;
    @Autowired
    private IConfigTableService iConfigTableService;
    @Autowired
    private IConfigTableOperationSubService iConfigTableOperationSubService;

    @Override
    public void save(ConfigTableFieldVO configTableFieldVO) {
        saveReturnId(configTableFieldVO);
    }

    @Override
    public void save(String token, ConfigTableFieldVO configTableFieldVO) {
        saveReturnId(token, configTableFieldVO);
    }

    @Override
    public String saveReturnId(ConfigTableFieldVO configTableFieldVO) {
        return saveReturnId(null, configTableFieldVO);
    }

    @Override
    public String saveReturnId(String token, ConfigTableFieldVO configTableFieldVO) {
        String configTableFieldId = UUIDUtil.getUUID();
        /**
         * 如果已经激活, 则不允许再进行新增
         */
        String configTableId = configTableFieldVO.getConfigTableId();
        ConfigTableDTO configTableDTO = iConfigTableService.get(configTableId);
        if(configTableDTO == null) {
            throw new SaveException("缺少表单参数");
        }
        if("1".equals(configTableDTO.getConfigTableActivation())) {
            throw new SaveException("已激活的表单不允许新增字段");
        }
        // 去除左右的空格
        String configTableFieldCode = configTableFieldVO.getConfigTableFieldCode().trim();
        /**
         * 判断表名的命名规范是否合法
         */
        char beginCode = configTableFieldCode.charAt(0);
        if( !( beginCode >= 65 && beginCode <= 90 ) && !( beginCode >= 97 && beginCode <= 122 ) ) {
            throw new SaveException("列名首位必须为英文");
        }
        Pattern pattern1 = Pattern.compile("\\w+$");
        Matcher matcher1 = pattern1.matcher(configTableFieldCode);
        if(!matcher1.find()) {
            throw new SaveException("列名的命名不符合规范");
        }
        /**
         * 查询数据库表名明是否存在
         */
        Map<String, Object> queryCode = new HashMap<String, Object>();
        queryCode.put("configTableId", configTableFieldVO.getConfigTableId());
        queryCode.put("configTableFieldCode", configTableFieldCode);
        ConfigTableFieldDTO tableCodeFieldDTO1 = configTableFieldDao.getTableFieldCode(queryCode);
        if(tableCodeFieldDTO1 != null) {
            throw new SaveException("该字段已经存在");
        }
        queryCode.put("configTableFieldCode", configTableFieldCode.toLowerCase());
        ConfigTableFieldDTO tableCodeFieldDTO2 = configTableFieldDao.getTableFieldCode(queryCode);
        if(tableCodeFieldDTO2 != null) {
            throw new SaveException("该字段已经存在");
        }
        queryCode.put("configTableFieldCode", configTableFieldCode.toUpperCase());
        ConfigTableFieldDTO tableCodeFieldDTO3 = configTableFieldDao.getTableFieldCode(queryCode);
        if(tableCodeFieldDTO3 != null) {
            throw new SaveException("该字段已经存在");
        }
        // 去除左右的空格
        configTableFieldVO.setConfigTableFieldCode(configTableFieldCode);
        Map<String, Object> params = HashMapUtil.beanToMap(configTableFieldVO);
        params.put("configTableFieldId", configTableFieldId);
        if (StringUtils.isBlank(token)) {
            setSaveInfo(params);
        } else {
            setAppSaveInfo(token, params);
        }
        configTableFieldDao.save(params);
        return configTableFieldId;
    }

    @Override
    public void remove(List<String> ids) {
        remove(null, ids);
    }

    @Override
    public void remove(String token, List<String> ids) {
        for (String id: ids) {
            /**
             * 如果已经激活, 则不允许再进行新增
             */
            ConfigTableFieldDTO dto = get(id);
            String configTableId = dto.getConfigTableId();
            ConfigTableDTO configTableDTO = iConfigTableService.get(configTableId);
            if("1".equals(configTableDTO.getConfigTableActivation())) {
                throw new SaveException("已激活的表单不允许删除字段");
            }
        }
        Map<String, Object> params = getHashMap(2);
        params.put("configTableFieldIds", ids);
        if (StringUtils.isBlank(token)) {
            setUpdateInfo(params);
        } else {
            setAppUpdateInfo(token, params);
        }
        configTableFieldDao.remove(params);
    }

    @Override
    public void delete(List<String> ids) {
        Map<String, Object> params = getHashMap(2);
        params.put("configTableFieldIds", ids);
        configTableFieldDao.delete(params);
    }

    @Override
    public void update(String configTableFieldId, ConfigTableFieldVO configTableFieldVO) {
        update(null, configTableFieldId, configTableFieldVO);
    }

    @Override
    public void update(String token, String configTableFieldId, ConfigTableFieldVO configTableFieldVO) {
        /**
         * 如果已经激活, 则不允许再进行新增
         */
        String configTableId = configTableFieldVO.getConfigTableId();
        ConfigTableDTO configTableDTO = iConfigTableService.get(configTableId);
        if(configTableDTO == null) {
            throw new SaveException("缺少表单参数");
        }
        // 去除左右的空格
        String configTableFieldCode = configTableFieldVO.getConfigTableFieldCode().trim();
        /**
         * 判断表名的命名规范是否合法
         */
        char beginCode = configTableFieldCode.charAt(0);
        if( !( beginCode >= 65 && beginCode <= 90 ) && !( beginCode >= 97 && beginCode <= 122 ) ) {
            throw new SaveException("列名首位必须为英文");
        }
        Pattern pattern1 = Pattern.compile("\\w+$");
        Matcher matcher1 = pattern1.matcher(configTableFieldCode);
        if(!matcher1.find()) {
            throw new SaveException("列名的命名不符合规范");
        }
        /**
         * 查询数据库表名明是否存在
         */
        Map<String, Object> queryCode = new HashMap<String, Object>();
        queryCode.put("configTableId", configTableFieldVO.getConfigTableId());
        queryCode.put("configTableFieldCode", configTableFieldCode);
        ConfigTableFieldDTO tableCodeFieldDTO1 = configTableFieldDao.getTableFieldCode(queryCode);
        if(tableCodeFieldDTO1 != null && !tableCodeFieldDTO1.getConfigTableFieldId().equals(configTableFieldId)) {
            throw new SaveException("该字段已经存在");
        }
        queryCode.put("configTableFieldCode", configTableFieldCode.toLowerCase());
        ConfigTableFieldDTO tableCodeFieldDTO2 = configTableFieldDao.getTableFieldCode(queryCode);
        if(tableCodeFieldDTO2 != null && !tableCodeFieldDTO2.getConfigTableFieldId().equals(configTableFieldId)) {
            throw new SaveException("该字段已经存在");
        }
        queryCode.put("configTableFieldCode", configTableFieldCode.toUpperCase());
        ConfigTableFieldDTO tableCodeFieldDTO3 = configTableFieldDao.getTableFieldCode(queryCode);
        if(tableCodeFieldDTO3 != null && !tableCodeFieldDTO3.getConfigTableFieldId().equals(configTableFieldId)) {
            throw new SaveException("该字段已经存在");
        }
        // 去除左右的空格
        configTableFieldVO.setConfigTableFieldCode(configTableFieldCode);
        /**
         * 已激活的表单只允许修改 字段名称 / 字段排序 / 是否必填 / 字段描述
         * 不允许修改列名 / 字段类型 / 存储数量
         */
        if("1".equals(configTableDTO.getConfigTableActivation())) {
            configTableFieldVO.setConfigTableFieldType(null);
            configTableFieldVO.setConfigTableFieldCode(null);
            configTableFieldVO.setConfigTableFieldNumber(null);
        }
        Map<String, Object> params = HashMapUtil.beanToMap(configTableFieldVO);
        params.put("configTableFieldId", configTableFieldId);
        if (StringUtils.isBlank(token)) {
            setUpdateInfo(params);
        } else {
            setAppUpdateInfo(token, params);
        }
        configTableFieldDao.update(params);
    }

    @Override
    public ConfigTableFieldDTO get(Map<String, Object> params) {
        return configTableFieldDao.get(params);
    }

    @Override
    public ConfigTableFieldDTO get(String configTableFieldId) {
        Map<String, Object> params = super.getHashMap(2);
        params.put("configTableFieldId", configTableFieldId);
        return get(params);
    }

    @Override
    public ConfigTableFieldBO getBO(Map<String, Object> params) {
        return configTableFieldDao.getBO(params);
    }

    @Override
    public ConfigTableFieldBO getBO(String configTableFieldId) {
        Map<String, Object> params = super.getHashMap(2);
        params.put("configTableFieldId", configTableFieldId);
        return getBO(params);
    }

    @Override
    public ConfigTableFieldPO getPO(Map<String, Object> params) {
        return configTableFieldDao.getPO(params);
    }

    @Override
    public ConfigTableFieldPO getPO(String configTableFieldId) {
        Map<String, Object> params = super.getHashMap(2);
        params.put("configTableFieldId", configTableFieldId);
        return getPO(params);
    }

    @Override
    public List<ConfigTableFieldDTO> list(Map<String, Object> params) {
        return configTableFieldDao.list(params);
    }

    @Override
    public List<ConfigTableFieldBO> listBO(Map<String, Object> params) {
        return configTableFieldDao.listBO(params);
    }

    @Override
    public List<ConfigTableFieldPO> listPO(Map<String, Object> params) {
        return configTableFieldDao.listPO(params);
    }

    @Override
    public SuccessResultList<List<ConfigTableFieldDTO>> listPage(ListPage page) {
        PageHelper.startPage(page.getPage(), page.getRows());
        List<ConfigTableFieldDTO> configTableFieldDTOs = list(page.getParams());
        PageInfo<ConfigTableFieldDTO> pageInfo = new PageInfo<>(configTableFieldDTOs);
        return new SuccessResultList<>(configTableFieldDTOs, pageInfo.getPageNum(), pageInfo.getTotal());
    }

    @Override
    public Integer count(Map<String, Object> params) {
        Integer count = configTableFieldDao.count(params);
        return count == null ? 0 : count;
    }

    @Override
    public List<ConfigTableFieldDTO> getByConfigTableId(String configTableId) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("configTableId", StringUtils.isEmpty(configTableId) ? "noQuery" : configTableId);
        return configTableFieldDao.list(params);
    }

    @Override
    public void updateOrder(String configTableId, String createPage, JSONObject jsonObject) {
        ConfigTableDTO configTableDTO = iConfigTableService.get(configTableId);
        if("0".equals(configTableDTO.getConfigTableActivation())) {
            throw new UpdateException("激活后的表单才可以进行布局");
        }
        JSONArray jsonArray = jsonObject.getJSONArray("configArray");
        for (int i = 0; i < jsonArray.size(); i++) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("configTableId", configTableId);
            JSONObject baseConfig = jsonArray.getJSONObject(i).getJSONObject("baseConfig");
            String customConfig = jsonArray.getJSONObject(i).getString("customConfig");
            params.put("configTableFieldId", baseConfig.getString("configTableFieldId"));
            params.put("configTableFieldConfig", customConfig);
            params.put("configTableFieldRowCol", baseConfig.getIntValue("configTableFieldRowCol"));
            params.put("configTableFieldRow", baseConfig.getIntValue("configTableFieldRow"));
            params.put("configTableFieldOrder", baseConfig.getIntValue("configTableFieldOrder"));
            params.put("configTableFieldName", baseConfig.getString("configTableFieldName"));
            params.put("configTableFieldMust", baseConfig.getIntValue("configTableFieldMust"));
            params.put("configTableFieldPlaceholder", baseConfig.getString("configTableFieldPlaceholder"));
            params.put("configTableFieldDefault", baseConfig.getString("configTableFieldDefault"));
            params.put("configTableFieldDisplay", baseConfig.getIntValue("configTableFieldDisplay"));
            configTableFieldDao.updateOrder(params);
        }
        List<ConfigTableOperationDTO> list = iConfigTableOperationSubService.listFieldConfig("", configTableId);
        /**
         * H5页面生成
         */
        if("createH5".equals(createPage)) {
            Map<String, Object> templateDataMap = HashMapUtil.beanToMap(configTableDTO);
            templateDataMap.put("tableFieldList", list);
            TemplateCreateData createData = new TemplateCreateData();
            createData.setTemplateDataMap(templateDataMap);
            try{
                createData.setTemplateCode("H5-EDIT");
                createData.setBusinessId(configTableDTO.getConfigTableId() + "Edit");
                createData.setBusinessContent(configTableDTO.getConfigTableName() + "-Edit");
                TemplateRecordVO recordEditVo =  TemplateBuilderUtil.getInstance().createFile(createData);

                createData.setTemplateCode("H5-SAVE");
                createData.setBusinessId(configTableDTO.getConfigTableId() + "Save");
                createData.setBusinessContent(configTableDTO.getConfigTableName() + "-Save");
                TemplateRecordVO recordSaveVo =  TemplateBuilderUtil.getInstance().createFile(createData);

                createData.setTemplateCode("H5-LIST");
                createData.setBusinessId(configTableDTO.getConfigTableId() + "List");
                createData.setBusinessContent(configTableDTO.getConfigTableName() + "-List");
                TemplateRecordVO recordListVo =  TemplateBuilderUtil.getInstance().createFile(createData);

                createData.setTemplateCode("H5-VIEW");
                createData.setBusinessId(configTableDTO.getConfigTableId() + "View");
                createData.setBusinessContent(configTableDTO.getConfigTableName() + "-View");
                TemplateRecordVO recordViewVo =  TemplateBuilderUtil.getInstance().createFile(createData);
            }catch(Exception e) {
                e.printStackTrace();
                throw new UpdateException("生成编辑页面发生异常");
            }
        }
    }

}