package com.ruoyi.api.controller.system;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.lang.LangUnit;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysDictTypeService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.framework.utils.Global;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.LocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * API Controller
 *
 * @author Leo
 * @date 22-05-10
 */
//@Api(tags = "2 公用接口")
//@ApiSupport(order = 2)
@RestController
@RequestMapping("/wx/api")
public class GlobalApiController extends BaseController
{
    @Autowired
    private ISysDictTypeService sysDictTypeService;

    @Autowired
    private Global global;

    @Autowired
    private LangUnit langUnit;

    @Autowired
    private LocaleResolver localeResolver;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ISysConfigService sysConfigService;

    /**
     * 单个字典信息
     * 类型名称
     */
//    @ApiOperation(value = "2.1.1 字典详情")
//    @ApiOperationSupport(order = 1)
    @PostMapping("/dictInfo")
    public String getDictDataByType(String dictType){
        JSONObject jsonObj = new JSONObject();
        if (StringUtils.isNull(dictType) || StringUtils.isEmpty(dictType) ){
            jsonObj.put("code", 1001);
            jsonObj.put("msg", langUnit.getValueTag("globalApi.dictInfo.1001","字典类型不能为空") );
            return jsonObj.toJSONString();
        }

        //字典多语言 加后缀1
        String userName = getUsername();
        String dictTypeLast = global.getLanguage(userName);
        dictType = dictType + dictTypeLast;

        List<SysDictData> list = sysDictTypeService.selectDictDataByType(dictType);

        JSONArray jsonArr  = new JSONArray();
        for (SysDictData oneDictInfo : list) {
            jsonArr.add( addOneDictInfo(oneDictInfo) );
        }

        jsonObj.put("code",     200);
        jsonObj.put("msg",      "success");
        jsonObj.put("data",     jsonArr.toArray());
        return jsonObj.toJSONString();
    }

    /**
     * 多个字典信息
     * 类型名称
     */
//    @ApiOperation(value = "2.1.2 多个字典详情")
//    @ApiOperationSupport(order = 1)
    @PostMapping("/dictInfos")
    public String getDictDataByTypes(String[] dictTypes){
        JSONObject jsonObj = new JSONObject();
        if (dictTypes == null || (dictTypes != null && dictTypes.length == 0)){
            jsonObj.put("code", 1001);
            jsonObj.put("msg", langUnit.getValueTag("globalApi.dictInfo.1001","字典类型不能为空") );
            return jsonObj.toJSONString();
        }
        //字典多语言 加后缀1
        String userName = getUsername();
        String dictTypeLast = global.getLanguage(userName);
        JSONObject data = new JSONObject();
        for (String dictType : dictTypes) {
            String dictTypeNew = dictType + dictTypeLast;
            List<SysDictData> list = sysDictTypeService.selectDictDataByType(dictTypeNew);
            JSONArray jsonArr  = new JSONArray();
            for (SysDictData oneDictInfo : list) {
                jsonArr.add( addOneDictInfo(oneDictInfo) );
            }
            data.put(dictType, jsonArr);
        }
        jsonObj.put("code",     200);
        jsonObj.put("msg",      "success");
        jsonObj.put("data",     data);
        return jsonObj.toJSONString();
    }

    public JSONObject addOneDictInfo(SysDictData oneDictInfo) {
        JSONObject jsonOne = new JSONObject();
        jsonOne.put("getDictLabel", oneDictInfo.getDictLabel());
        jsonOne.put("dictType",     oneDictInfo.getDictValue());
        jsonOne.put("dictName",     oneDictInfo.getDictSort());
        jsonOne.put("cssClass",     oneDictInfo.getCssClass());
        return jsonOne;
    }

    // 令牌秘钥
    @Value("${token.secret}")
    public String secret;

//    @ApiOperation(value = "2.2 Web私钥")
//    @ApiOperationSupport(order = 2)
    @PostMapping("/webSecret")
    @PreAuthorize("@ss.hasPermi('wx:web:secret')")
    public String getWebSecret() {
        JSONObject jsonObj = new JSONObject();
        if (StringUtils.isNull(secret) || StringUtils.isEmpty(secret) ){
            jsonObj.put("code", 201);
            jsonObj.put("msg", langUnit.getValueTag("globalApi.webSecret.201","获取私钥失败") );
            return jsonObj.toJSONString();
        }
        jsonObj.put("code", 200);
        jsonObj.put("msg", "success");
        jsonObj.put("data", secret.toUpperCase());

        return jsonObj.toJSONString();
    }

//    @ApiOperation(value = "2.3 DES加密")
//    @ApiOperationSupport(order = 3)
    @PostMapping("/desEncrypt")
    @PreAuthorize("@ss.hasPermi('wx:des:encrypt')")
    public String desEncrypt(String value) {
        JSONObject jsonObj  = new JSONObject();
        try {
            DesUtil des     = new DesUtil();
            String desValue = des.encrypt(secret.toUpperCase(), value);
            jsonObj.put("code", 200);
            jsonObj.put("msg", "success");
            jsonObj.put("data", desValue);
        } catch (Exception e) {
            jsonObj.put("code", 201);
            jsonObj.put("msg", langUnit.getValueTag("globalApi.desEncrypt.201","DES加密失败") );
        }
        return jsonObj.toJSONString();
    }

//    @ApiOperation(value = "2.4 DES解密")
//    @ApiOperationSupport(order = 4)
    @PostMapping("desDecode")
    @PreAuthorize("@ss.hasPermi('wx:des:decode')")
    public String desDecode(String value) {
        JSONObject jsonObj  = new JSONObject();
        try {
            DesUtil des = new DesUtil();
            String decodeValue = des.decode(secret.toUpperCase(), value);
            decodeValue = global.repSpace(decodeValue);
            jsonObj.put("code", 200);
            jsonObj.put("msg", "success");
            jsonObj.put("data", decodeValue);

        } catch (Exception e) {
            jsonObj.put("code", 201);
            jsonObj.put("msg", langUnit.getValueTag("globalApi.desDecode.201","DES解密失败") );
        }
        return jsonObj.toJSONString();
    }

    @Autowired
    private ISysConfigService configService;

    //@ApiOperation(value = "2.5 DES加密1")
    //@ApiOperationSupport(order = 5)
    @PostMapping("/desEncrypt1")
    @PreAuthorize("@ss.hasPermi('wx:des:encrypt')")
    public String desEncrypt1(String value) {
        JSONObject jsonObj  = new JSONObject();
        try {
            DesUtil1 des     = new DesUtil1();
            String desValue = des.encrypt(secret.toUpperCase(), value);
            jsonObj.put("code", 200);
            jsonObj.put("msg", "success");
            jsonObj.put("data", desValue);
        } catch (Exception e) {
            jsonObj.put("code", 201);
            jsonObj.put("msg", langUnit.getValueTag("globalApi.desEncrypt1.201","DES加密失败") );
        }
        return jsonObj.toJSONString();
    }

    //@ApiOperation(value = "2.6 DES解密1")
    //@ApiOperationSupport(order = 6)
    @PostMapping("desDecode1")
    @PreAuthorize("@ss.hasPermi('wx:des:decode')")
    public String desDecode1(String value) {
        JSONObject jsonObj  = new JSONObject();
        try {
            DesUtil1 des = new DesUtil1();
            String decodeValue = des.decrypt(secret.toUpperCase(), value);
            jsonObj.put("code", 200);
            jsonObj.put("msg", "success");
            jsonObj.put("data", decodeValue);

        } catch (Exception e) {
            jsonObj.put("code", 201);
            jsonObj.put("msg", langUnit.getValueTag("globalApi.desDecode1.201","DES解密失败") );
        }
        return jsonObj.toJSONString();
    }

    //秒转小时
    public static String second2hour(long mTime){ //毫秒
        if (mTime <= 0){
            return "0";
        }

        double dHour    = mTime / 3600d / 1000d;
        int iHour       = (int) dHour;

        double dMinute = (dHour - iHour) * 60d;
        int iMinute    = (int) dMinute;

        double dSecond = (dMinute - iMinute) * 60d;
        int iSecond    = (int) dSecond;

        String timeFmt = String.format("%02d:%02d:%02d", iHour, iMinute, iSecond);
        return timeFmt ;
    }

    /**
     * 字典类型
     */
    //@ApiOperation("字典类型")
    @PostMapping("/dict_type")
    @ResponseBody
    public String getDictTypeAll(){
        JSONObject jsonObj = new JSONObject();
        List<SysDictType> list = sysDictTypeService.selectDictTypeAll();

        JSONArray jsonArr  = new JSONArray();
        for (SysDictType oneDictType : list) {
            jsonArr.add( addOneDictType(oneDictType) );
        }

        jsonObj.put("code", 200);
        jsonObj.put("msg", "success");
        jsonObj.put("data", jsonArr.toArray());
        return jsonObj.toJSONString();

    }

    public JSONObject addOneDictType(SysDictType oneDict) {
        JSONObject jsonOne = new JSONObject();
        jsonOne.put("dictId",       oneDict.getDictId());
        jsonOne.put("dictType",     oneDict.getDictType());
        jsonOne.put("dictName",     oneDict.getDictName());
        return jsonOne;
    }

//    @ApiOperation(value = "2.7 手动切换语言", notes = "切换成功后,下次登录默认为新语言")
//    @ApiOperationSupport(author = "Leo", order = 7)
    @PostMapping("/language")
    public String setLocale(String language, HttpServletRequest request, HttpServletResponse response) {
        JSONObject jsonObj = new JSONObject();
        if (StringUtils.isNull(language) || StringUtils.isEmpty(language) ){
            jsonObj.put("code", 1001);
            jsonObj.put("msg", langUnit.getValueTag("globalApi.language.1001","语言类型不能为空") );
            return jsonObj.toJSONString();
        }

        String userName = getUsername();
        SysUser sysUser = userService.selectUserByUserName(userName);
        if (sysUser == null){
            jsonObj.put("code", 1002);
            jsonObj.put("msg", langUnit.getValueTag("globalApi.language.1002","语言切换失败,找不到该用户") );
            return jsonObj.toJSONString();
        }

        // 根据传入的lo创建Locale实例:
        Locale locale = null;
        int pos = language.indexOf('_');
        if (pos > 0) {
            String lang = language.substring(0, pos);
            String country = language.substring(pos + 1);
            locale = new Locale(lang, country);
        } else {
            locale = new Locale(language);
        }
        // 设定此Locale:
        localeResolver.setLocale(request, response, locale);
        logger.info("locale is set to {}.", locale);

        List<SysDictData> dictDataList = sysDictTypeService.selectDictDataByType("sys_language");
        boolean flag = false;
        for (SysDictData sysDictData : dictDataList) {
            if (sysDictData.getDictValue().equals(language)) {
                flag = true;
            }
        }
        if (flag) {
            //写入数据库
            sysUser.setLanguage(language);
            userService.updateUserLang(sysUser.getUserName(), language);

            LoginUser loginUser  = getLoginUser();
            loginUser.getUser().setLanguage(language);

            // 保存用户语言到redis中
            redisCache.setCacheObject(Constants.USER_LANGUAGE_KEY + sysUser.getUserId(), language);
        } else {
            jsonObj.put("code", 1003);
            jsonObj.put("msg", langUnit.getValueTag("globalApi.language.1003","语言切换失败") );
            return jsonObj.toJSONString();
        }

        jsonObj.put("code",         200);
        jsonObj.put("msg",          "success");
        jsonObj.put("language",     language);
        return jsonObj.toJSONString();
    }

//    @ApiOperation(value = "2.8 多语言-页面语言", notes = "不读取Accept-Language, 设置2.7有效")
//    @ApiOperationSupport(author = "Leo", order = 8)
    @PostMapping("/i18nTest")
    public String i18nTest2()
    {
        String msg  = langUnit.getValueDef("user.login.success");
        return msg;
    }

//    @ApiOperation(value = "2.9 读取其他Key", notes = "使用页面语言")
//    @ApiOperationSupport(author = "Leo", order = 9)
    @PostMapping("/i18nTest3")
    public String i18nTest3(String key)
    {
        String msg  = langUnit.getValueDef(key);
        return msg;
    }


//    @ApiOperation(value = "2.10 首页大屏地址", notes = "建构首页大屏地址")
//    @ApiResponses(
//            {
//                    @ApiResponse(code = 200,  message = "生成地址成功,返回首页url及是否外链标志（0是 1否）"),
//                    @ApiResponse(code = 1001, message = "生成地址出错"),
//            }
//    )
//    @ApiOperationSupport(author = "lwen", order = 10)
    @GetMapping("/buildMainPageURL")
    @PreAuthorize("@ss.hasPermi('wx.build.buildMainPageURL')") //dashboard:main:view
    public String buildMainPageURL(){
        JSONObject jsonObj  = new JSONObject();
        Long userId = SecurityUtils.getUserId();
        String userName = getUsername();
        SysUser sysUser = userService.selectUserByUserName(userName);

        if (StringUtils.isNull(sysUser)){
            jsonObj.put("code", 1001);
            jsonObj.put("msg", langUnit.getValueTag("globalApi.buildBiURL.1001","获取地址出错") );
            return jsonObj.toJSONString();
        } else {
            jsonObj.put("code", 200);
            jsonObj.put("msg", "success");
            // 默认首页地址
            String url = sysConfigService.selectConfigByKey(Constants.MAIN_PAGE_URL_KEY +  (StringUtils.isEmpty(sysUser.getLanguage()) ? "zh" : sysUser.getLanguage()));
            Integer isFrame  = 0;
            jsonObj.put("data", url);
            jsonObj.put("isFrame", isFrame);

            List<SysRole> roleList = sysUser.getRoles();
            List<String> roleArr = new ArrayList<>();
            for (SysRole sysRole : roleList) {
                roleArr.add(sysRole.getRoleKey());
            }
            String roleStr = roleArr.toString();
            // 管理员不处理
            if (roleStr.contains("admin")) {
                return jsonObj.toJSONString();
            }
            return jsonObj.toJSONString();
        }
    }

}
