package com.bcxin.identify.api.common.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.bcxin.identify.api.common.dto.FileParam;
import com.bcxin.identify.api.common.util.FunnelRateLimiter;
import com.bcxin.identify.startup.CacheService;
import com.bcxin.identify.util.Result;
import com.bcxin.identify.util.TokenUtils;
import com.bcxin.identify.util.common.JwtUtil;
import com.bcxin.identify.util.common.StringUtil;
import com.bcxin.identify.util.file.BcxinFileUtils;
import com.bcxin.identify.util.sys.ConfigUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * <b> 负责对外接口 </b>
 * @author ZXF
 * @create 2021/01/28 0028 13:20
 * @version
 * @注意事项 </b>
 */
@Controller
@RequestMapping("/identify/api/common")
@Slf4j
public class FileController {
    @Resource
    private CacheService cacheService;
    @Resource
    private FunnelRateLimiter funnelRateLimiter;

    private static String platform = ConfigUtil.getValue("ENVI_PROD");

    @PostMapping(value = "/upload-file")
    @Async
    public @ResponseBody CompletableFuture<String> uploadFile(@RequestParam("xfile") MultipartFile file,
                                                       HttpServletRequest request, HttpServletResponse response) {
        return CompletableFuture.supplyAsync(() -> {
            log.info("上传文件成功>>>>>>>>>>>>>>>>>>>>");
            try {
                String isTemp = request.getParameter("istemp");
                String url = BcxinFileUtils.huaweiOBSFileUploadAndSign(file, platform, isTemp);
                log.info("====>upload-file.url:{}", url);
                if (StringUtil.isNotEmpty(url)) {
                    return JSON.toJSONString(Result.success("上传成功.", url));
                } else {
                    String errorMsg = "上传失败:" + file.getOriginalFilename();
                    return JSON.toJSONString(Result.fail(errorMsg));
                }
            } catch (Exception e) {
                if (file.getOriginalFilename().contains("&")) {
                    String errorMsg = "上传失败，文件名含有非法字符:" + file.getOriginalFilename();
                    return JSON.toJSONString(Result.fail(errorMsg));
                }

                return JSON.toJSONString(Result.fail(e.getMessage()));
            }
        });
    }

    /**
     * blob文件上传，用于页面中异步上传文件，返回文件路径（华为云）
     *
     * @return Result
     */
    @PostMapping(value = "/upload-blob-file")
    public @ResponseBody Result uploadBlobFile(@RequestParam("xfile") MultipartFile file) {
        log.info("上传文件成功>>>>>>>>>>>>>>>>>>>>");
        try {
            String platform = ConfigUtil.getValue("ENVI_PROD");
            if (file.getOriginalFilename().contains("&")) {
                String errorMsg = "上传失败，文件名含有非法字符:" + file.getOriginalFilename();
                return Result.fail(errorMsg);
            }
            String url = BcxinFileUtils.huaweiOBSFileUploadForBlob(file,platform);
            if (com.github.pagehelper.StringUtil.isNotEmpty(url)) {
                return Result.success("上传成功", url);
            } else {
                String errorMsg = "上传失败:" + file.getOriginalFilename();
                return Result.fail(errorMsg);
            }
        } catch (Exception e) {
            return Result.fail(e.getMessage());
        }
    }

    @PostMapping(value = "/upload-base64-file")
    public @ResponseBody String uploadBase64File(@RequestBody FileParam fileParam) {
        log.info("上传文件成功>>>>>>>>>>>>>>>>>>>>");
        try {
            String platform = ConfigUtil.getValue("ENVI_PROD");
            if (fileParam.getFilename().contains("&")) {
                String errorMsg = "上传失败，文件名含有非法字符:" + fileParam.getFilename();
                return JSON.toJSONString(Result.fail(errorMsg));
            }
            String url = "测试上传瓶颈";//BcxinFileUtils.huaweiOBSFileUploadAndSign(file,platform,isTemp);
            log.info("====>upload-base64-file.url:"+url);
            if (StringUtil.isNotEmpty(url)) {
                return JSON.toJSONString(Result.success("上传成功", url));
            } else {
                String errorMsg = "上传失败:" + fileParam.getFilename();
                return JSON.toJSONString(Result.fail(errorMsg));
            }
        } catch (Exception e) {
            return JSON.toJSONString(Result.fail(e.getMessage()));
        }
    }

    @GetMapping(value = "/transfer-obs")
    public @ResponseBody Result transferObs(HttpServletRequest request) {
        String token = request.getParameter("token");
        log.debug("接口【/identify/api/tencent/trtc-video-room】token:"+token);
        String url = TokenUtils.getUrlFromBcxToken(token);
        String fileType = "pdf";
        if (StrUtil.isEmpty(url) || StrUtil.isEmpty(fileType)) {
            return Result.fail("参数不完整");
        }
        return Result.success("上传成功", BcxinFileUtils.getFileUrl(fileType,url));
    }

    /**
     * <b> 通过接口删除redisKey方便下次加载
     *      * 由于redisKey对应的value存在变动手动删除不方便 </b>
     * @author ZXF
     * @create 2021/05/17 0017 16:21
     * @version
     * @注意事项 </b>
     */
    @GetMapping("delete-redis-by-key")
    @ResponseBody
    public Result deleteRedisByKey(String key) {
        return cacheService.deleteRedisByKey(key);
    }

    /**
     * <b> 个推发送消息给设备 </b>
     * @author ZXF
     * @create 2022/05/09 0009 10:11
     * @version
     * @注意事项 </b>
     */
    @PostMapping(value = "gt-send-msg")
    @ResponseBody
    public Result gtSendMsg(HttpServletRequest request) {
        String orgId = request.getParameter("orgId");
        String param = request.getParameter("param");
        String cuList = request.getParameter("cuList");
        String title = request.getParameter("title");
        String body = request.getParameter("body");
        String payload = request.getParameter("payload");//页面类型
//        String token = request.getParameter("token");
        log.debug("接口【/identify/api/common/gt-send-msg】title:{}",title);
//        log.debug("接口【/identify/api/tencent/trtc-video-room】token:"+token);
//        Claims claims;
//        try {
//            claims = JwtUtil.parseJWT(token, ConfigUtil.getValue("JWT_SECRET"));
//        } catch (Exception e) {
//            return Result.fail("秘钥不对，解密失败");
//        }
//        String subject = claims.getSubject();
//        Map<String,String> params = JSON.parseObject(subject, new TypeReference<Map>(){ });
        Map<String,String> params = Maps.newHashMap();
        params.put("orgId",orgId);
        params.put("cuList",cuList);
        params.put("param",param);
        params.put("title",title);
        params.put("body",body);
        params.put("payload",payload);
        if (StrUtil.isEmpty(params.get("orgId"))
                || StrUtil.isEmpty(params.get("cuList"))
                || StrUtil.isEmpty(params.get("payload"))
                || StrUtil.isEmpty(params.get("title"))
        ) {
            return Result.fail("参数不完整");
        }
        log.debug("接口【/identify/api/common/gt-send-msg】个推发送消息给指定人员。");
        cacheService.gtSendMsg(new HashMap<>(params));
        log.debug("接口【/identify/api/common/gt-send-msg】个推发送消息给指定人员。");
        return Result.success(Result.SUCCESS_MSG);
    }

    /**
     * 电子发票开票参数加密
     */
    @PostMapping(value = "apply-e-invoice-cj")
    @ResponseBody
    public Result applyEInvoiceCJ(String json) {
        return Result.success(Result.SUCCESS_MSG,JwtUtil.createJWT(json));
    }

    /**
     * 电子发票开票参数解密
     */
    @GetMapping(value = "apply-e-invoice-pj")
    @ResponseBody
    public Result applyEInvoicePJ(HttpServletRequest request) {
        String token = request.getParameter("token");
        Claims claims;
        try {
            claims = JwtUtil.parseJWT(token, JwtUtil.JWT_SECRET);
        } catch (Exception e) {
            return Result.fail("秘钥不对，解密失败");
        }
        String subject = claims.getSubject();
        Map<String,String> params = JSON.parseObject(subject, new TypeReference<Map>(){ });
        return Result.success(Result.SUCCESS_MSG,params);
    }

    @GetMapping("update-millis/{mil}")
    @ResponseBody
    public Result updateMillis(@PathVariable("mil") int mil) {
        return Result.success(Result.SUCCESS_MSG,funnelRateLimiter.changeMillis(mil));
    }

    @PostMapping(value = "reduce")
    @ResponseBody
    public Result reduce() {
        /*int availablePermits = semaphore.availablePermits();
        log.debug("接口【/identify/api/common/reduce】可用资源："+availablePermits);
        if(availablePermits>0){
            try {
                boolean b = semaphore.tryAcquire();
                if (!b) {
                    log.debug("接口【/identify/api/common/reduce】线程阻塞");
                    return Result.fail("当前业务繁忙，请重试");
                }
                log.debug("接口【/identify/api/common/reduce】抢到资源");
                if(millis>0){
                    Thread.sleep(millis);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                semaphore.release();
            }
            return Result.success(Result.SUCCESS_MSG);
        }
        log.debug("接口【/identify/api/common/reduce】无资源");*/
        try {
            if(funnelRateLimiter.isActionAllowed("reduce",1,10)){
                log.debug("接口【/identify/api/common/reduce】S");
                return Result.success(Result.SUCCESS_MSG);
            }
        } catch (Exception e) {

        }
        log.debug("接口【/identify/api/common/reduce】F");
        return Result.fail("当前业务繁忙，请重试");
    }

    public static void main(String[] args) {
        Map<String,Object> p = Maps.newHashMap();
        p.put("platform","pss"); /* 第三方调用平台*/
        p.put("serial","12312311441"); /* 第三方唯一流水号*/
        p.put("callback","http://localhost:8888/response"); /* 开票结果回调地址*/
        p.put("kpgs","bcxin"); /* 开票公司，默认为百川信*/
        p.put("gfmc","魔都奇迹网络信息公司"); /* 购方名称*/
        p.put("yhzh","123123123"); /* 购方银行账号*/
        p.put("sh","301239123123123B"); /* 购方税号*/
        p.put("dz","厦门市思明区白绿洲"); /* 购方地址*/
        p.put("dh","0106666666"); /* 购方电话 */
        p.put("email","luopeng@bcxin.com.cn"); /* 购方邮件*/
        List<Map<String,String>> goodsList = Lists.newArrayList();
        Map<String,String> g1 = Maps.newHashMap();
        g1.put("spmc","漫威手办模型浩克2"); /* 商品名称*/
        g1.put("ggxh","个"); /* 规格型号*/
        g1.put("jldw","个"); /* 计量单位*/
        g1.put("spsl","1"); /* 商品数量*/
        g1.put("spdj","100"); /* 商品单价*/
        g1.put("je","100"); /* 金额*/
        g1.put("hsbz","1"); /* 含税标记 1为是，0位否*/
        goodsList.add(g1);
        p.put("splb",goodsList);
        Map<String,Object> requestMap = Maps.newHashMap();
        requestMap.put("json",JSON.toJSONString(p));
        String response = HttpUtil.post("http://localhost:8888/identify/api/common/apply-e-invoice-cj",requestMap);
        System.out.println(response);
    }
}
