package com.hzs.system.base.controller.manage;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hzs.common.core.annotation.AccessPermissions;
import com.hzs.common.core.constant.CacheConstants;
import com.hzs.common.core.enums.ELanguages;
import com.hzs.common.core.service.RedisService;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.core.utils.poi.ExcelUtil;
import com.hzs.common.core.utils.reflect.ReflectUtils;
import com.hzs.common.core.web.controller.BaseController;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.core.web.page.TableDataInfo;
import com.hzs.common.domain.system.base.BdTransaction;
import com.hzs.common.domain.system.base.ext.BdTransactionExt;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.system.base.service.IBdTransactionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 国际化翻译控制器
 *
 * @author hzs
 * @since 2022-08-08
 */
@Slf4j
@RestController
@RequestMapping("/manage/transaction")
public class BdTransactionController extends BaseController {

    @Autowired
    private IBdTransactionService iBdTransactionService;
    @Autowired
    private RedisService redisService;

    /**
     * 翻译列表
     *
     * @param transactionExt
     * @return
     */
    @AccessPermissions("Translate")
    @GetMapping("/list")
    public TableDataInfo list(BdTransactionExt transactionExt) {
        QueryWrapper<BdTransaction> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(transactionExt.getName())) {
            if (StringUtils.isNotNull(transactionExt.getLanguagesValue())) {
                ELanguages eLanguages = ELanguages.getLanguagesByValue(transactionExt.getLanguagesValue());
                queryWrapper.like(eLanguages.getColumn(), transactionExt.getName());
            } else {
                queryWrapper.like(ELanguages.CN.getColumn(), transactionExt.getName());
            }
        }
        queryWrapper.orderByDesc("CREATION_TIME");
        startPage();
        List<BdTransaction> list = iBdTransactionService.list(queryWrapper);
        List<BdTransactionExt> listExt = new ArrayList<>();
        list.forEach(item -> listExt.add(BeanUtil.copyProperties(item, BdTransactionExt.class)));
        TableDataInfo tableDataInfo = getDataTable(list);
        tableDataInfo.setRows(listExt);
        return tableDataInfo;
    }

    /**
     * 保存
     *
     * @param bdTransaction
     * @return
     */
    @PostMapping("/save")
    public AjaxResult save(@RequestBody BdTransaction bdTransaction) {
        LambdaQueryWrapper<BdTransaction> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BdTransaction::getKey, bdTransaction.getKey())
                .or()
                .eq(BdTransaction::getChinese, bdTransaction.getChinese());
        List<BdTransaction> queryList = iBdTransactionService.list(queryWrapper);
        if (!CollectionUtils.isEmpty(queryList)) {
            return AjaxResult.error("国际化翻译键或中文已经存在，请检查");
        }
        if (iBdTransactionService.save(bdTransaction)) {
            return AjaxResult.success();
        }
        return AjaxResult.error("国际化翻译保存失败");
    }

    /**
     * 更新
     *
     * @param bdTransaction
     * @return
     */
    @PostMapping("/update")
    public AjaxResult update(@RequestBody BdTransaction bdTransaction) {
        if (null == iBdTransactionService.getById(bdTransaction.getPkId())) {
            return AjaxResult.error("国际化翻译不存在，请刷新后重试");
        }
        iBdTransactionService.updateById(bdTransaction);
        return AjaxResult.success();
    }

    /**
     * 查询详情
     *
     * @param pkId
     * @return
     */
    @GetMapping("getOne")
    public AjaxResult getOne(Integer pkId) {
        BdTransaction transaction = iBdTransactionService.getById(pkId);
        BdTransactionExt transactionExt = BeanUtil.copyProperties(transaction, BdTransactionExt.class);
        return AjaxResult.success(transactionExt);
    }

    /**
     * 导出
     *
     * @param response
     * @param transactionExt
     */
    @PostMapping("/export")
    public void export(HttpServletResponse response, BdTransactionExt transactionExt) {
        QueryWrapper<BdTransaction> queryWrapper = new QueryWrapper<>();

        if (StringUtils.isNotEmpty(transactionExt.getName())) {
            ELanguages eLanguages = ELanguages.getLanguagesByValue(transactionExt.getLanguagesValue());
            if (null != eLanguages) {
                queryWrapper.like(eLanguages.getColumn(), transactionExt.getName());
            } else {
                queryWrapper.like(ELanguages.CN.getColumn(), transactionExt.getName());
            }
        }

        List<BdTransaction> list = iBdTransactionService.list(queryWrapper);
        List<BdTransactionExt> listExt = new ArrayList<>();
        list.forEach(item -> listExt.add(BeanUtil.copyProperties(item, BdTransactionExt.class)));
        ExcelUtil<BdTransactionExt> util = new ExcelUtil<>(BdTransactionExt.class);
        util.exportExcel(response, listExt, "国际化翻译导出");
    }

    /**
     * @description: 下载模板
     * @author: zhang jing
     * @date: 2023/4/6 11:48
     * @param: [response]
     * @return: void
     **/
    @PostMapping("/download")
    public void download(HttpServletResponse response) {
        List<BdTransactionExt> listExt = new ArrayList<>();
        ExcelUtil<BdTransactionExt> util = new ExcelUtil<>(BdTransactionExt.class);
        util.exportExcel(response, listExt, "国际化翻译");
    }


    /**
     * 导入统一翻译信息
     *
     * @param file
     * @param updateSupport
     * @return
     * @throws Exception
     */
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception {
        ExcelUtil<BdTransaction> util = new ExcelUtil<>(BdTransaction.class);
        List<BdTransaction> ordersList = util.importExcel(file.getInputStream());
        if (CollectionUtil.isEmpty(ordersList)) {
            return AjaxResult.success(true);
        }
        return AjaxResult.success(iBdTransactionService.importData(ordersList, updateSupport, SecurityUtils.getUserId()));
    }

    /**
     * 初始化语种（以中文为准，翻译为其它语种）
     *
     * @param language 语种
     * @return
     */
    @GetMapping("/init-languages")
    public AjaxResult initLanguages(@RequestParam("language") Integer language) {
        ELanguages eLanguages = ELanguages.getLanguagesByValue(language);
        if (null == eLanguages) {
            return AjaxResult.error("语种不存在");
        }

        return toAjax(iBdTransactionService.initToLanguage(eLanguages));
    }

    /**
     * 刷新资源缓存
     *
     * @param languages 刷新语种（ELanguages的value）
     * @return
     */
    @GetMapping("/refresh")
    public AjaxResult refresh(Integer languages) {
        try {
            // 刷新缓存，不上传OSS
            iBdTransactionService.flushResources(languages, true, false);

            return AjaxResult.success();
        } catch (Exception e) {
            log.error("翻译刷新缓存资源处理失败", e);
        }
        return AjaxResult.error();
    }

    /**
     * 刷新资源OSS
     *
     * @param languages 刷新语种（ELanguages的value）
     * @return
     */
    @GetMapping("/refresh-oss")
    public AjaxResult refreshOss(Integer languages) {
        try {
            // 不刷新缓存，上传OSS
            iBdTransactionService.flushResources(languages, false, true);

            return AjaxResult.success();
        } catch (Exception e) {
            log.error("翻译刷新OSS资源处理失败", e);
        }
        return AjaxResult.error();
    }

    /**
     * 刷新指定数据资源
     *
     * @param pkIdList 数据ID列表
     * @return
     */
    @GetMapping("/refresh-data")
    public AjaxResult refreshData(@RequestParam List<Long> pkIdList) {
        try {
            List<BdTransaction> transactionList = iBdTransactionService.listByIds(pkIdList);

            if (CollectionUtil.isNotEmpty(transactionList)) {
                // 根据目前语种枚举，生成对应数据集合
                for (ELanguages eLanguages : ELanguages.values()) {
                    Map<String, String> dataMap = new HashMap<>();

                    for (BdTransaction bdTransaction : transactionList) {
                        dataMap.put(bdTransaction.getKey(), ReflectUtils.invokeGetter(bdTransaction, eLanguages.getColumn()));
                    }
                    // 刷新redis缓存
                    redisService.setCacheMap(CacheConstants.LANGUAGE_KEY + eLanguages.getLocal(), dataMap);
                }
                return AjaxResult.success();
            }
            return AjaxResult.error("指定资源ID不存在");
        } catch (Exception e) {
            log.error("翻译刷新指定资源处理失败", e);
        }
        return AjaxResult.error("翻译刷新处理失败");
    }

    /**
     * 以指定语种为基础初始数据资源
     *
     * @param language 基础语种
     * @param pkIdList 翻译数据ID列表
     * @return
     */
    @GetMapping("/init-other-language/{language}")
    public AjaxResult initOtherLanguage(@PathVariable("language") Integer language, @RequestParam List<Long> pkIdList) {
        ELanguages eLanguages = ELanguages.getLanguagesByValue(language);
        if (null == eLanguages) {
            return AjaxResult.error("语种不存在");
        }
        return toAjax(iBdTransactionService.initOtherLanguage(eLanguages, pkIdList));
    }

}
