package com.yunzhupaas.base.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.bean.BeanUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import com.yunzhupaas.base.ActionResult;
import com.yunzhupaas.base.Pagination;
import com.yunzhupaas.base.entity.BaseLangEntity;
import com.yunzhupaas.base.entity.DictionaryDataEntity;
import com.yunzhupaas.base.model.language.*;
import com.yunzhupaas.base.service.BaseLangService;
import com.yunzhupaas.base.service.DictionaryDataService;
import com.yunzhupaas.base.util.ExcelTool;
import com.yunzhupaas.base.vo.DownloadVO;
import com.yunzhupaas.config.ConfigValueUtil;
import com.yunzhupaas.constant.ConfigConst;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.model.ExcelColumnAttr;
import com.yunzhupaas.model.ExcelImportVO;
import com.yunzhupaas.model.ExcelModel;
import com.yunzhupaas.util.JsonUtil;
import com.yunzhupaas.util.RegexUtils;
import com.yunzhupaas.util.StringUtil;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 多语言管理
 *
 * @author 云筑产品开发平台组
 * @version v5.0.0
 * @copyright 深圳市乐程软件有限公司
 * @date 2024/4/28 11:26:57
 */
@Tag(name = "多语言配置", description = "BaseLang")
@RestController
@RequestMapping("/api/system/BaseLang")
public class BaseLangController {

    @Autowired
    private BaseLangService baseLangService;

    @Autowired
    private ConfigValueUtil configValueUtil;

    @Autowired
    private DictionaryDataService dictionaryDataApi;

    @Operation(summary = "标记翻译列表")
    @GetMapping("/List")
    public ActionResult getList(Pagination pagination) {
//        pagination.setPageSize(100000);
        BaseLangListVO list = baseLangService.getList(pagination);
//        List list1 = list.getList();
//        for(Object o : list1) {
//            Map<String, Object> stringObjectMap = JsonUtil.entityToMap(o);
//            LinkedHashMap<String, String> map = new LinkedHashMap<>();
//            map.put("zh-CN",stringObjectMap.get("zh_CN").toString());
//            map.put("zh-TW",stringObjectMap.get("zh_TW").toString());
//            map.put("en",stringObjectMap.get("en").toString());
//            BaseLangForm form =new BaseLangForm();
//            form.setType(0);
//            form.setEnCode(stringObjectMap.get("code").toString());
//            form.setMap(map);
//            baseLangService.create(form);
//        }
        return ActionResult.success(list);
    }

    @Operation(summary = "标记翻译列表")
    @SaCheckPermission("system.language")
    @GetMapping()
    public ActionResult list(BaseLangPage pagination) {
        BaseLangListVO list = baseLangService.list(pagination);
        return ActionResult.success(list);
    }

    @Operation(summary = "创建")
    @Parameters({
            @Parameter(name = "form", description = "多语言表单对象", required = true)
    })
    @SaCheckPermission(value = {"system.language", "onlineDev.webDesign"}, mode = SaMode.OR)
    @PostMapping()
    public ActionResult create(@RequestBody @Valid BaseLangForm form) {
        if (RegexUtils.checkEnCode2(form.getEnCode())) {
            ActionResult.fail(MsgCode.SYS050.get());
        }
        baseLangService.create(form);
        return ActionResult.success(MsgCode.SU001.get());
    }

    @Operation(summary = "修改")
    @Parameters({
            @Parameter(name = "form", description = "多语言表单对象", required = true)
    })
    @SaCheckPermission("system.language")
    @PutMapping("/{id}")
    public ActionResult update(@PathVariable("id") String id, @RequestBody @Valid BaseLangForm form) {
        if (RegexUtils.checkEnCode2(form.getEnCode())) {
            ActionResult.fail(MsgCode.SYS050.get());
        }
        form.setId(id);
        baseLangService.update(form);
        return ActionResult.success(MsgCode.SU004.get());
    }

    @Operation(summary = "详情")
    @Parameters({
            @Parameter(name = "enCode", description = "翻译标记", required = true)
    })
    @SaCheckPermission("system.language")
    @GetMapping("/{id}")
    public ActionResult info(@PathVariable("id") String id) {
        BaseLangForm info = baseLangService.getInfo(id);
        return ActionResult.success(info);
    }

    @Operation(summary = "删除")
    @Parameters({
            @Parameter(name = "id", description = "翻译标记", required = true)
    })
    @SaCheckPermission("system.language")
    @DeleteMapping("/{id}")
    public ActionResult delete(@PathVariable("id") String id) {
        baseLangService.delete(id);
        return ActionResult.success();
    }

    @Operation(summary = "获取语种json")
    @Parameters({
            @Parameter(name = "language", description = "语种编码", required = true)
    })
    @GetMapping("/LangJson")
    public ActionResult LangJson(Locale locale) {
        if (locale == null || StringUtil.isEmpty(locale.toLanguageTag()) || "und".equals(locale.toLanguageTag())) {
            locale = Locale.SIMPLIFIED_CHINESE;
        }
        String languageJson = baseLangService.getLanguageJson(locale);
        return ActionResult.success(MsgCode.SU000.get(), languageJson);
    }

    @Operation(summary = "获取语种json")
    @Parameters({
            @Parameter(name = "language", description = "语种编码", required = true)
    })
    @GetMapping("/ServerLang")
    public ActionResult<List<BaseLangVo>> getServerLang(Locale locale) {
        List<BaseLangEntity> serverLang = baseLangService.getServerLang(locale);
        List<BaseLangVo> list = JsonUtil.getJsonToList(serverLang, BaseLangVo.class);
        return ActionResult.success(list);
    }

    //++++++++++++++++++++++++++++++++++以下导入导出接口++++++++++++++++++++++++++++++++++++++++++

    @Operation(summary = "模板下载")
    @SaCheckPermission("system.language")
    @GetMapping("/TemplateDownload")
    public ActionResult<DownloadVO> TemplateDownload() {
        BaseLangColumn columnMap = new BaseLangColumn(getDicLangMap());
        String excelName = columnMap.getExcelName();
        Map<String, String> keyMap = columnMap.getColumnByType(0);
        List<ExcelColumnAttr> models = columnMap.getFieldsModel(false);
        List<Map<String, Object>> list = columnMap.getDefaultList();
        Map<String, String[]> optionMap = new HashMap<>();
        optionMap.put("type", new String[]{"客户端", "服务端"});

        ExcelModel excelModel = ExcelModel.builder().models(models).selectKey(new ArrayList<>(keyMap.keySet())).optionMap(optionMap).hasHeader(true).build();
        DownloadVO vo = ExcelTool.getImportTemplate(configValueUtil.getTemporaryFilePath(), excelName, keyMap, list, excelModel);
        return ActionResult.success(vo);
    }

    /**
     * 从字典获取语言map
     *
     * @return
     */
    private Map<String, String> getDicLangMap() {
        List<DictionaryDataEntity> langTypeList = dictionaryDataApi.getListByTypeDataCode(ConfigConst.BASE_LANGUAGE);
        Map<String, String> collect = new LinkedHashMap<>();
        langTypeList.forEach(t -> collect.put(t.getEnCode(), t.getFullName()));
        return collect;
    }

    @Operation(summary = "上传导入Excel")
    @SaCheckPermission("system.language")
    @PostMapping("/Uploader")
    public ActionResult<Object> Uploader() {
        return ExcelTool.uploader();
    }

    @Operation(summary = "导入数据")
    @SaCheckPermission("system.language")
    @PostMapping("/ImportData")
    public ActionResult<ExcelImportVO> ImportData(@RequestBody BaseLangModel model) {
        // 导入字段
        BaseLangColumn columnMap = new BaseLangColumn(getDicLangMap());
        Map<String, String> keyMap = columnMap.getColumnByType(0);
        Map<String, Object> headAndDataMap = ExcelTool.importPreview(configValueUtil.getTemporaryFilePath(), model.getFileName(), keyMap,1,1);
        List<Map<String, Object>> listData = (List<Map<String, Object>>) headAndDataMap.get("dataRow");
        List<BaseLangEntity> addList = new ArrayList<>();
        List<Map<String, Object>> failList = new ArrayList<>();
        // 对数据做校验 (处理)
        this.validateImportData(listData, addList, failList);
        //写入数据
        baseLangService.importSaveOrUpdate(addList);
        return ActionResult.success(MsgCode.IMP001.get());
    }

    public void validateImportData(List<Map<String, Object>> listData, List<BaseLangEntity> addList, List<Map<String, Object>> failList) {
        List<DictionaryDataEntity> langTypeList = dictionaryDataApi.getListByTypeDataCode(ConfigConst.BASE_LANGUAGE);
        for (Map<String, Object> map : listData) {
            if (MapUtils.isNotEmpty(map) && map.get("enCode")!=null && StringUtil.isNotBlank(map.get("enCode").toString()) && RegexUtils.checkEnCode2(map.get("enCode").toString())) {
                BaseLangEntity baseLangEntity = new BaseLangEntity();
                baseLangEntity.setEnCode(map.get("enCode").toString());
                Integer type = 0;
                if (map.get("type") != null && StringUtil.isNotBlank(map.get("type").toString())) {
                    type = "服务端".equals(map.get("type").toString()) ? 1 : 0;
                }
                baseLangEntity.setType(type);
                boolean allNull = true;
                List<BaseLangEntity> thisList =new ArrayList<>();
                for (DictionaryDataEntity item : langTypeList) {
                    String enCode = item.getEnCode();
                    String fullName = "";
                    if (map.get(enCode) != null) {
                        fullName = map.get(enCode).toString();
                    }
                    if(StringUtil.isNotBlank(fullName)){
                        allNull = false;
                    }
                    baseLangEntity.setLanguage(enCode);
                    baseLangEntity.setFullName(fullName);
                    BaseLangEntity entity = BeanUtil.copyProperties(baseLangEntity, BaseLangEntity.class);
                    thisList.add(entity);
                }
                if(!allNull){
                    addList.addAll(thisList);
                }
            } else {
                failList.add(map);
            }
        }
    }
}

