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

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hzs.common.core.annotation.AccessPermissions;
import com.hzs.common.core.annotation.Log;
import com.hzs.common.core.constant.CacheConstants;
import com.hzs.common.core.constant.CountryConstants;
import com.hzs.common.core.constant.EnumsPrefixConstants;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.service.RedisService;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.core.utils.poi.ExcelUtil;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.core.web.page.TableDataInfo;
import com.hzs.common.domain.system.base.BdCountry;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.common.service.ITransactionCommonService;
import com.hzs.config.pub.controller.ConfigBaseController;
import com.hzs.system.base.ITransactionServiceApi;
import com.hzs.system.base.service.IBdCountryService;
import com.hzs.system.base.vo.CountryVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 国家控制器
 */
@RestController
@RequestMapping("/manage/country")
public class BdCountryController extends ConfigBaseController {

    @Autowired
    private IBdCountryService countryService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private ITransactionCommonService iTransactionCommonService;

    @DubboReference
    ITransactionServiceApi iTransactionServiceApi;

    /**
     * 查询国家信息
     *
     * @return
     */
    @AccessPermissions("National")
    @Log(module = EOperationModule.COUNTRY_LIST, method = EOperationMethod.SELECT)
    @GetMapping("/list")
    public TableDataInfo list(BdCountry bdCountry, Date createStartDate, Date createEndDate
            , Date effectiveStartDate, Date effectiveEndDate) {
        startPage();
        LambdaQueryWrapper<BdCountry> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(bdCountry.getCode())) {
            // 编号
            queryWrapper.like(BdCountry::getCode, bdCountry.getCode());
        }
        if (StringUtils.isNotBlank(bdCountry.getName())) {
            // 名称
            queryWrapper.like(BdCountry::getName, bdCountry.getName());
        }
        if (StringUtils.isNotBlank(bdCountry.getShortName())) {
            // 简称
            queryWrapper.like(BdCountry::getShortName, bdCountry.getShortName());
        }
        if (bdCountry.getEnableState() != null) {
            // 启用状态（0=是,1=否）
            queryWrapper.eq(BdCountry::getEnableState, bdCountry.getEnableState());
        }
        // 语种
        if (bdCountry.getLanguages() != null) {
            queryWrapper.eq(BdCountry::getLanguages, bdCountry.getLanguages());
        }
        // 创建时间筛选
        if (createStartDate != null && createEndDate != null) {
            queryWrapper.between(BdCountry::getCreationTime, createStartDate, createEndDate);
        }
        // 生效筛选
        if (effectiveStartDate != null && effectiveEndDate != null) {
            queryWrapper.between(BdCountry::getEffectiveDate, effectiveStartDate, effectiveEndDate);
        }
        List<BdCountry> list = countryService.list(queryWrapper);
        return getDataTable(list);
    }

    /**
     * 新增国家
     *
     * @param bdCountry
     * @return
     */
    @Log(module = EOperationModule.COUNTRY_SAVE, method = EOperationMethod.INSERT)
    @PostMapping("/save")
    public AjaxResult save(@RequestBody BdCountry bdCountry) {
        bdCountry.setCreationTime(new Date());
        bdCountry.setPkCreator(SecurityUtils.getUserId());

        // 字段翻译保存到数据库
        R<Integer> pkTransaction = iTransactionServiceApi.createTransaction(CountryConstants.CHINA_COUNTRY, ETransactionKey.COUNTRY,
                bdCountry.getShortName(), EYesNo.NO, EYesNo.NO);
        bdCountry.setPkTransaction(pkTransaction.getData());

        countryService.save(bdCountry);
        sendDelayedMessage(bdCountry, EDelayBusType.COUNTRY.getValue(), CacheConstants.BD_COUNTRY + bdCountry.getPkId());
        return AjaxResult.success();
    }

    /**
     * 修改国家
     *
     * @param bdCountry
     * @return
     */
    @Log(module = EOperationModule.COUNTRY_UPDATE, method = EOperationMethod.UPDATE)
    @PostMapping("/update")
    public AjaxResult update(@RequestBody BdCountry bdCountry) {
        BdCountry country = countryService.getById(bdCountry.getPkId());
        if (country == null) {
            return AjaxResult.error("当前国家不存在");
        }
        bdCountry.setModifiedTime(new Date());
        bdCountry.setPkModified(SecurityUtils.getUserId());
        long effectiveDate = bdCountry.getEffectiveDate().getTime();
        long thisTime = DateUtils.currentDate().getTime();
        String key = CacheConstants.BD_COUNTRY + bdCountry.getPkId();
        if (effectiveDate < thisTime) {
            // 生效时间大于当前时间 立即生效 缓存
            redisService.deleteObject(key);
        } else {
            // 删除缓存
            // 判断生效时间，生效时间大于当前时间需要走延时队列
            if (!sendDelayedMessage(bdCountry, EDelayBusType.COUNTRY.getValue(), key)) {
                redisService.deleteObject(key);
            }
        }

        boolean bool = countryService.updateById(bdCountry);
        if (bool) {
            // 更新成功，处理国际化
            iTransactionServiceApi.updateTransaction(CountryConstants.CHINA_COUNTRY, bdCountry.getShortName(), country.getPkTransaction(), true);
        }
        return toAjax(bool);
    }

    /**
     * 删除
     *
     * @param pkId
     * @return
     */
    @Log(module = EOperationModule.COUNTRY_DELETE, method = EOperationMethod.DELETE)
    @DeleteMapping("/{pkId}")
    public AjaxResult delete(@PathVariable Long pkId) {
        if (countryService.removeById(pkId)) {
            // 刷新缓存 TODO 老版本刷新缓存
            //  redisComponent.initCountry();
            String redisKey = CacheConstants.BD_COUNTRY + pkId;
            redisService.deleteObject(redisKey);
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }


    /**
     * 更新状态
     *
     * @param pkId
     * @param enable 启用状态（0=是,1=否）
     * @return
     */
    @Log(module = EOperationModule.COUNTRY_UPDATE_ENABLE, method = EOperationMethod.UPDATE)
    @PostMapping("/updateEnable/{pkId}/{enable}")
    public AjaxResult updateEnable(@PathVariable Integer pkId, @PathVariable Integer enable) {
        if (!EYesNo.checkEnableCode(enable)) {
            return AjaxResult.error("更新状态不存在");
        }
        LambdaQueryWrapper<BdCountry> queryWrapper = new LambdaQueryWrapper<>();
        //      queryWrapper.eq(SystemFieldConstants.ENABLE_STATE, EYesNo.YES.getIntValue());
        queryWrapper.le(BdCountry::getEffectiveDate, DateUtils.currentDateTime());
        queryWrapper.eq(BdCountry::getPkId, pkId);
        BdCountry ct = countryService.getBaseMapper().selectOne(queryWrapper);
        Integer pkCountry = SecurityUtils.getPkCountry();
        if (ct.getPkId().equals(pkCountry) && enable == EnableStatus.STOP.getValue()) {
            return AjaxResult.error("无法禁用当前登录国");
        }
        BdCountry country = new BdCountry();
        country.setPkId(pkId);
        country.setEnableState(enable);
        // 删除缓存
        redisService.deleteObject(CacheConstants.BD_COUNTRY + pkId);
        if (countryService.updateById(country)) {
            // 刷新缓存  TODO 老版本刷新缓存
            // redisComponent.initCountry();
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }

    /**
     * 查询全部国家
     *
     * @return
     */
    @GetMapping("/find-all")
    public AjaxResult findAll() {
        LambdaQueryWrapper<BdCountry> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(BdCountry::getCreationTime);
        List<BdCountry> list = countryService.list(queryWrapper);

        // 获取需要翻译的枚举翻译
        Map<Integer, String> transactionMap = iTransactionCommonService.exportEnumTransactionByDB(EnumsPrefixConstants.KEY_COUNTRY);
        for (BdCountry bdCountry : list) {
            // 处理国家名称国际化
            String name = transactionMap.get(bdCountry.getPkTransaction());
            bdCountry.setShortName(StringUtils.isNotEmpty(name) ? name : bdCountry.getShortName());
        }

        return AjaxResult.success(list);
    }

    /**
     * 查询详情
     *
     * @param pkId
     * @return
     */
    @GetMapping("/detail")
    public AjaxResult detail(Integer pkId) {
        BdCountry country = countryService.getById(pkId);
        return AjaxResult.success(country);
    }

    /**
     * 国家导出
     */
    @PostMapping("/export")
    public void list(BdCountry bdCountry, Date createStartDate, Date createEndDate
            , Date effectiveStartDate, Date effectiveEndDate, HttpServletResponse response) {

        LambdaQueryWrapper<BdCountry> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(bdCountry.getCode())) {
            // 编号
            queryWrapper.like(BdCountry::getCode, bdCountry.getCode());
        }
        if (StringUtils.isNotBlank(bdCountry.getName())) {
            // 名称
            queryWrapper.like(BdCountry::getName, bdCountry.getName());
        }
        if (StringUtils.isNotBlank(bdCountry.getShortName())) {
            // 简称
            queryWrapper.like(BdCountry::getShortName, bdCountry.getShortName());
        }
        if (bdCountry.getEnableState() != null) {
            // 启用状态（0=是,1=否）
            queryWrapper.eq(BdCountry::getEnableState, bdCountry.getEnableState());
        }
        // 语种
        if (bdCountry.getLanguages() != null) {
            queryWrapper.eq(BdCountry::getLanguages, bdCountry.getLanguages());
        }
        // 创建时间筛选
        if (createStartDate != null && createEndDate != null) {
            queryWrapper.between(BdCountry::getCreationTime, createStartDate, createEndDate);
        }
        // 生效筛选
        if (effectiveStartDate != null && effectiveEndDate != null) {
            queryWrapper.between(BdCountry::getEffectiveDate, effectiveStartDate, effectiveEndDate);
        }
        List<BdCountry> list = countryService.list(queryWrapper);
        List<CountryVo> resultList = new ArrayList<>();
        for (BdCountry country : list) {
            CountryVo countryVo = BeanUtil.copyProperties(country, CountryVo.class);
            countryVo.setMemberPrefix(country.getCode());
            resultList.add(countryVo);
        }
        ExcelUtil<CountryVo> util = new ExcelUtil<>(CountryVo.class);
        util.exportExcel(response, resultList, "国家导出");
    }
}
