
package com.jeelowcode.core.framework.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeelowcode.core.framework.entity.*;
import com.jeelowcode.core.framework.mapper.*;
import com.jeelowcode.core.framework.params.PageReportParam;
import com.jeelowcode.core.framework.service.II18nService;
import com.jeelowcode.core.framework.utils.Func;
import com.jeelowcode.framework.excel.model.ExcelTitleModel;
import com.jeelowcode.framework.excel.model.MoreSheetConfig;
import com.jeelowcode.framework.utils.component.redis.JeeLowCodeRedisUtils;
import com.jeelowcode.framework.utils.constant.JeeRedisConstants;
import com.jeelowcode.framework.utils.utils.FuncBase;
import org.apache.commons.collections4.map.LinkedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 模块组合相关
 */
@Service
public class I18nServiceImpl implements II18nService {

    @Autowired
    private AdapterMapper adapterMapper;

    @Autowired
    private JeeLowCodeMapper jeeLowCodeMapper;

    @Autowired
    private FormFieldWebMapper formFieldWebMapper;

    @Autowired
    private DesFormMapper desFormMapper;

    @Autowired
    private ReportFieldMapper reportFieldMapper;

    @Autowired
    private TabOptionMapper tabOptionMapper;

    @Autowired
    private FormButtonMapper buttonMapper;

    @Autowired
    private HistoryI18nMapper historyI18nMapper;

    @Autowired
    private JeeLowCodeRedisUtils jeeLowCodeRedisUtils;

    @Override
    public void saveHistory(HistoryI18nEntity entity){
        historyI18nMapper.insert(entity);
    }

    @Override
    public synchronized void addOneCou(String batchCode){
        String redisKey= JeeRedisConstants.I18N_HISTORY+":"+batchCode;
        Integer cou = jeeLowCodeRedisUtils.get(redisKey, Integer.class);
        if(Func.isEmpty(cou)){
            cou=0;
        }
        cou++;
        jeeLowCodeRedisUtils.set(redisKey,cou,3600*24);

    }

    @Override
    public Map<String,Integer> getImportProgress(String batchCode){
        LambdaQueryWrapper<HistoryI18nEntity> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(HistoryI18nEntity::getBatchCode,batchCode);
        HistoryI18nEntity historyI18nEntity = historyI18nMapper.selectOne(wrapper);
        Integer totalCou = historyI18nEntity.getTotalCou();

        String redisKey= JeeRedisConstants.I18N_HISTORY+":"+batchCode;
        Integer cou = jeeLowCodeRedisUtils.get(redisKey, Integer.class);
        if(Func.isEmpty(cou)){
            cou=0;
        }
        Map<String,Integer> resultMap=new HashMap<>();
        resultMap.put("totalCou",totalCou);
        resultMap.put("handleCou",cou);
        return resultMap;
    }


    //导出国际化配置
    @Override
    public List<MoreSheetConfig> export(Map<String,Object> langMap) {

        //表单开发 自定义表单 报表设计  多模块组合
        List<MoreSheetConfig> exportList = new ArrayList<>();
        exportList.add(this.exportDbForm(langMap));//表单开发
        exportList.add(this.exportDesForm(langMap));//自定义表单
        exportList.add(this.exportReport(langMap));//报表
        exportList.add(this.exportTab(langMap));//分组
        exportList.add(this.exportButton(langMap));//自定义按钮
        exportList.add(this.exportMenuButton(langMap));
        return exportList;
    }




    //导入
    @Async("asyncPoolTaskExecutor")
    @Override
    public void importData(String batchCode,Map<Integer,List<Map<String, Object>>> sheetDataMap){
        List<Map<String, Object>> dbFormDataMapList = sheetDataMap.get(0);//表单开发
        List<Map<String, Object>> desFormDataMapList = sheetDataMap.get(1);//自定义表单
        List<Map<String, Object>> reportDataMapList = sheetDataMap.get(2);//报表
        List<Map<String, Object>> tabDataMapList = sheetDataMap.get(3);//多模块组合
        List<Map<String, Object>> buttonDataMapList = sheetDataMap.get(4);//自定义按钮
        List<Map<String, Object>> menuDataMapList = sheetDataMap.get(5);//菜单

        if(Func.isNotEmpty(dbFormDataMapList)){
            this.importDbForm(batchCode,dbFormDataMapList);
        }
        if(Func.isNotEmpty(desFormDataMapList)){
            this.importDesForm(batchCode,desFormDataMapList);
        }
        if(Func.isNotEmpty(reportDataMapList)){
            this.importReport(batchCode,reportDataMapList);
        }
        if(Func.isNotEmpty(tabDataMapList)){
            this.importTab(batchCode,tabDataMapList);
        }
        if(Func.isNotEmpty(buttonDataMapList)){
            this.importButton(batchCode,buttonDataMapList);
        }
        if(Func.isNotEmpty(menuDataMapList)){
            this.importMenu(batchCode,menuDataMapList);
        }
    }

    //分页 - 表单开发
    @Override
    public IPage<HistoryI18nEntity> getPages(Page page) {
        LambdaQueryWrapper<HistoryI18nEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(HistoryI18nEntity::getId);
        IPage<HistoryI18nEntity> pages = historyI18nMapper.selectPage(page, wrapper);
        return pages;
    }


    private MoreSheetConfig exportDbForm(Map<String,Object> langMap) {
        MoreSheetConfig moreSheetConfig = new MoreSheetConfig();
        moreSheetConfig.setSheetName("表单开发");

        LinkedMap<String, ExcelTitleModel> headMap = new LinkedMap<>();
        headMap.put("id", new ExcelTitleModel("Id(不允许改动)"));
        headMap.put("table_name", new ExcelTitleModel("表名称"));
        headMap.put("field_name",new ExcelTitleModel("字段名"));
        langMap.forEach((k,v)->{
            headMap.put(k, new ExcelTitleModel(Func.toStr(v)));
        });


        moreSheetConfig.setHeadMap(headMap);

        List<Map<String, Object>> dataList = new ArrayList<>();
        List<Map<String, Object>> dbFormI18nMapList = jeeLowCodeMapper.getDbFormI18nMapList();
        for (Map<String, Object> i18nMap : dbFormI18nMapList) {
            String id = Func.getMap2Str(i18nMap, "id");
            String table_name = Func.getMap2Str(i18nMap, "table_name");
            String field_name = Func.getMap2Str(i18nMap, "field_name");
            String label_i18n = Func.getMap2Str(i18nMap, "label_i18n");
            Map<String, Object> tmpMap = Func.in18n2Map(label_i18n);

            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("id", id);
            dataMap.put("table_name", table_name);
            dataMap.put("field_name", field_name);

            if (Func.isNotEmpty(tmpMap)) {
                dataMap.putAll(tmpMap);
            }
            dataMap.put("zh-CN",field_name);
            dataList.add(dataMap);
        }
        moreSheetConfig.setDataList(dataList);

        return moreSheetConfig;
    }

    private void importDbForm(String batchCode,List<Map<String, Object>> dbFormDataMapList) {
        for(Map<String, Object> dataMap:dbFormDataMapList){
           try{
               Long id = Func.getMap2Long(dataMap, "id");
               dataMap.remove("id");
               dataMap.remove("jeelowcode_excel_import_step");
               dataMap.remove("jeelowcode_excel_import_id");

               String lang = Func.json2Str(dataMap);
               String i18nData="return "+lang;

               //更新
               FormFieldWebEntity formFieldWebEntity=new FormFieldWebEntity();
               formFieldWebEntity.setId(id);
               formFieldWebEntity.setLabelI18n(i18nData);
               formFieldWebMapper.updateById(formFieldWebEntity);
           }catch (Exception e){
               e.printStackTrace();
           }finally {
               addOneCou(batchCode);
           }
        }
    }



    private MoreSheetConfig exportDesForm(Map<String,Object> langMap) {
        MoreSheetConfig moreSheetConfig = new MoreSheetConfig();
        moreSheetConfig.setSheetName("自定义表单");

        LinkedMap<String, ExcelTitleModel> headMap = new LinkedMap<>();
        headMap.put("id", new ExcelTitleModel("Id(不允许改动)"));
        headMap.put("desform_name", new ExcelTitleModel("表单设计名称"));
        headMap.put("field_name", new ExcelTitleModel("字段名称"));
        langMap.forEach((k,v)->{
            headMap.put(k, new ExcelTitleModel(Func.toStr(v)));
        });
        moreSheetConfig.setHeadMap(headMap);


        List<Map<String, Object>> dataList = new ArrayList<>();
        List<Map<String, Object>> dbFormI18nMapList = jeeLowCodeMapper.getDesFormI18nMapList();
        for (Map<String, Object> i18nMap : dbFormI18nMapList) {
            String id = Func.getMap2Str(i18nMap, "id");
            String desform_name = Func.getMap2Str(i18nMap, "desform_name");
            String i18n_data = Func.getMap2Str(i18nMap, "i18n_data");
            Map<String, Object> fieldMap = Func.json2Bean(i18n_data,Map.class);

            //便利map
            fieldMap.forEach((k,v)->{
                if(Func.isEmpty(v)){
                    return;
                }
                Map<String, Object> tmpMap = Func.in18n2Map(Func.toStr(v));
                if(Func.isEmpty(tmpMap)){
                    return;
                }
                String cn = Func.getMap2Str(tmpMap, "zh-CN");
                if(Func.isEmpty(cn)){
                    return;
                }

                Map<String, Object> dataMap = new HashMap<>();
                dataMap.put("id", id+"-"+k);
                dataMap.put("desform_name", desform_name);
                dataMap.put("field_name",cn);
                dataMap.putAll(tmpMap);
                dataList.add(dataMap);
            });
        }
        moreSheetConfig.setDataList(dataList);

        return moreSheetConfig;
    }

    private void importDesForm(String batchCode,List<Map<String, Object>> desFormDataMapList) {
        for(Map<String, Object> dataMap:desFormDataMapList){
            try{
                String idStr = Func.getMap2Str(dataMap, "id");
                String[] split = idStr.split("-");
                Long id = Func.toLong(split[0]);
                String fieldCode=split[1];
                dataMap.remove("id");
                dataMap.remove("jeelowcode_excel_import_step");
                dataMap.remove("jeelowcode_excel_import_id");
                String lang = Func.json2Str(dataMap);
                String i18nData="return "+lang;

                DesformEntity desformEntity = desFormMapper.selectById(id);
                if(Func.isEmpty(desformEntity)){
                    return;
                }
                String oldI18nData = desformEntity.getI18nData();
                Map<String, Object> fieldMap = Func.json2Bean(oldI18nData,Map.class);
                //覆盖
                fieldMap.put(fieldCode,i18nData);


                //更新
                DesformEntity updateEntity=new DesformEntity();
                updateEntity.setId(id);
                updateEntity.setI18nData(Func.json2Str(fieldMap));
                desFormMapper.updateById(updateEntity);
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                addOneCou(batchCode);
            }
        }
    }



    private MoreSheetConfig exportReport(Map<String,Object> langMap) {
        MoreSheetConfig moreSheetConfig = new MoreSheetConfig();
        moreSheetConfig.setSheetName("报表设计");

        LinkedMap<String, ExcelTitleModel> headMap = new LinkedMap<>();
        headMap.put("id", new ExcelTitleModel("Id(不允许改动)"));
        headMap.put("report_name", new ExcelTitleModel("报表名称"));
        headMap.put("field_name", new ExcelTitleModel("字段名"));

        langMap.forEach((k,v)->{
            headMap.put(k, new ExcelTitleModel(Func.toStr(v)));
        });
        moreSheetConfig.setHeadMap(headMap);

        List<Map<String, Object>> dataList = new ArrayList<>();
        List<Map<String, Object>> dbFormI18nMapList = jeeLowCodeMapper.getReportI18nMapList();
        for (Map<String, Object> i18nMap : dbFormI18nMapList) {
            String id = Func.getMap2Str(i18nMap, "id");
            String report_name = Func.getMap2Str(i18nMap, "report_name");
            String field_name = Func.getMap2Str(i18nMap, "field_name");
            String label_i18n = Func.getMap2Str(i18nMap, "label_i18n");
            Map<String, Object> tmpMap = Func.in18n2Map(label_i18n);

            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("id", id);
            dataMap.put("report_name", report_name);
            dataMap.put("field_name",field_name);

            if (Func.isNotEmpty(tmpMap)) {
                dataMap.putAll(tmpMap);
            }
            dataMap.put("zh-CN",field_name);
            dataList.add(dataMap);
        }
        moreSheetConfig.setDataList(dataList);

        return moreSheetConfig;
    }

    private void importReport(String batchCode,List<Map<String, Object>> reportDataMapList) {
        for(Map<String, Object> dataMap:reportDataMapList){
            try{
                Long id = Func.getMap2Long(dataMap, "id");
                dataMap.remove("id");
                dataMap.remove("jeelowcode_excel_import_step");
                dataMap.remove("jeelowcode_excel_import_id");
                String lang = Func.json2Str(dataMap);
                String i18nData="return "+lang;

                //更新
                ReportFieldEntity reportFieldEntity=new ReportFieldEntity();
                reportFieldEntity.setId(id);
                reportFieldEntity.setLabelI18n(i18nData);
                reportFieldMapper.updateById(reportFieldEntity);
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                addOneCou(batchCode);
            }
        }
    }



    private MoreSheetConfig exportTab(Map<String,Object> langMap) {
        MoreSheetConfig moreSheetConfig = new MoreSheetConfig();
        moreSheetConfig.setSheetName("多模块组合");

        LinkedMap<String, ExcelTitleModel> headMap = new LinkedMap<>();
        headMap.put("id", new ExcelTitleModel("Id(不允许改动)"));
        headMap.put("module_name", new ExcelTitleModel("模块名称"));
        headMap.put("tab_name", new ExcelTitleModel("Tab名称"));
        langMap.forEach((k,v)->{
            headMap.put(k, new ExcelTitleModel(Func.toStr(v)));
        });
        moreSheetConfig.setHeadMap(headMap);


        List<Map<String, Object>> dataList = new ArrayList<>();
        List<Map<String, Object>> dbFormI18nMapList = jeeLowCodeMapper.getTabI18nMapList();
        for (Map<String, Object> i18nMap : dbFormI18nMapList) {
            String id = Func.getMap2Str(i18nMap, "id");
            String module_name = Func.getMap2Str(i18nMap, "module_name");
            String tab_name = Func.getMap2Str(i18nMap, "tab_name");
            String label_i18n = Func.getMap2Str(i18nMap, "label_i18n");
            Map<String, Object> tmpMap = Func.in18n2Map(label_i18n);

            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("id", id);
            dataMap.put("module_name", module_name);
            dataMap.put("tab_name",tab_name);

            if (Func.isNotEmpty(tmpMap)) {
                dataMap.putAll(tmpMap);
            }
            dataMap.put("zh-CN",tab_name);
            dataList.add(dataMap);
        }
        moreSheetConfig.setDataList(dataList);

        return moreSheetConfig;
    }

    private void importTab(String batchCode,List<Map<String, Object>> tabMapList) {
        for(Map<String, Object> dataMap:tabMapList){
           try{
               Long id = Func.getMap2Long(dataMap, "id");
               dataMap.remove("id");
               dataMap.remove("jeelowcode_excel_import_step");
               dataMap.remove("jeelowcode_excel_import_id");
               String lang = Func.json2Str(dataMap);
               String i18nData="return "+lang;

               //更新
               TabOptionEntity tabOptionEntity=new TabOptionEntity();
               tabOptionEntity.setId(id);
               tabOptionEntity.setTabI18n(i18nData);
               tabOptionMapper.updateById(tabOptionEntity);
           }catch (Exception e){
               e.printStackTrace();
           }finally {
               addOneCou(batchCode);
           }
        }
    }

    private MoreSheetConfig exportButton(Map<String,Object> langMap) {
        MoreSheetConfig moreSheetConfig = new MoreSheetConfig();
        moreSheetConfig.setSheetName("自定义按钮");

        LinkedMap<String, ExcelTitleModel> headMap = new LinkedMap<>();
        headMap.put("id", new ExcelTitleModel("Id(不允许改动)"));
        headMap.put("button_name", new ExcelTitleModel("按钮名称"));
        langMap.forEach((k,v)->{
            headMap.put(k, new ExcelTitleModel(Func.toStr(v)));
        });
        moreSheetConfig.setHeadMap(headMap);


        List<Map<String, Object>> dataList = new ArrayList<>();
        List<Map<String, Object>> buttonI18nMapList = jeeLowCodeMapper.getButtonI18nMapList();
        for (Map<String, Object> i18nMap : buttonI18nMapList) {
            String id = Func.getMap2Str(i18nMap, "id");
            String button_name = Func.getMap2Str(i18nMap, "button_name");
            String label_i18n = Func.getMap2Str(i18nMap, "label_i18n");
            Map<String, Object> tmpMap = Func.in18n2Map(label_i18n);

            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("id", id);
            dataMap.put("button_name", button_name);

            if (Func.isNotEmpty(tmpMap)) {
                dataMap.putAll(tmpMap);
            }
            dataMap.put("zh-CN",button_name);
            dataList.add(dataMap);
        }
        moreSheetConfig.setDataList(dataList);

        return moreSheetConfig;
    }

    private void importButton(String batchCode,List<Map<String, Object>> buttonMapList) {
        for(Map<String, Object> dataMap:buttonMapList){
            try{
                Long id = Func.getMap2Long(dataMap, "id");
                dataMap.remove("id");
                dataMap.remove("jeelowcode_excel_import_step");
                dataMap.remove("jeelowcode_excel_import_id");
                String lang = Func.json2Str(dataMap);
                String i18nData="return "+lang;

                //更新
                FormButtonEntity entity=new FormButtonEntity();
                entity.setId(id);
                entity.setButtonI18n(i18nData);
                buttonMapper.updateById(entity);
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                addOneCou(batchCode);
            }
        }
    }

    private MoreSheetConfig exportMenuButton(Map<String,Object> langMap) {
        MoreSheetConfig moreSheetConfig = new MoreSheetConfig();
        moreSheetConfig.setSheetName("菜单");

        LinkedMap<String, ExcelTitleModel> headMap = new LinkedMap<>();
        headMap.put("id", new ExcelTitleModel("Id(不允许改动)"));
        headMap.put("name", new ExcelTitleModel("菜单名称"));
        langMap.forEach((k,v)->{
            headMap.put(k, new ExcelTitleModel(Func.toStr(v)));
        });
        moreSheetConfig.setHeadMap(headMap);


        List<Map<String, Object>> dataList = new ArrayList<>();
        List<Map<String, Object>> menuI18nMapList = adapterMapper.getMenuI18nMapList();
        for (Map<String, Object> i18nMap : menuI18nMapList) {
            String id = Func.getMap2Str(i18nMap, "id");
            String name = Func.getMap2Str(i18nMap, "name");
            String name_i18n = Func.getMap2Str(i18nMap, "name_i18n");
            Map<String, Object> tmpMap = Func.in18n2Map(name_i18n);

            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("id", id);
            dataMap.put("name", name);

            if (Func.isNotEmpty(tmpMap)) {
                dataMap.putAll(tmpMap);
            }
            dataMap.put("zh-CN",name);
            dataList.add(dataMap);
        }
        moreSheetConfig.setDataList(dataList);

        return moreSheetConfig;
    }

    private void importMenu(String batchCode,List<Map<String, Object>> menuMapList) {
        for(Map<String, Object> dataMap:menuMapList){
            try{
                Long id = Func.getMap2Long(dataMap, "id");
                dataMap.remove("id");
                dataMap.remove("jeelowcode_excel_import_step");
                dataMap.remove("jeelowcode_excel_import_id");
                String lang = Func.json2Str(dataMap);
                String i18nData="return "+lang;

                //更新
                adapterMapper.updateMenuI18n(id,i18nData);
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                addOneCou(batchCode);
            }
        }
    }

}
