package com.tax.sign.web.controller;

import com.google.common.collect.Lists;
import com.tax.sign.integration.user.UserClient;
import com.tax.sign.model.*;
import com.tax.sign.service.api.SignService;
import com.tax.sign.utils.SignUtil;
import com.tax.sign.utils.TaxnoUtil;
import com.yxcheng.token.common.annotation.LogT;
import com.yxcheng.token.common.cache.RedisService;
import com.yxcheng.token.common.controller.BaseClientController;
import com.yxcheng.token.common.enumutil.ResultEnum;
import com.yxcheng.token.common.model.CrRpcResult;
import com.yxcheng.token.common.model.JsonResult;
import com.yxcheng.token.constants.RedisContants;
import com.yxcheng.token.constants.RestFulApiContants;
import com.yxcheng.token.utils.DateUtils;
import com.yxcheng.token.utils.ObjectUtil;
import com.yxcheng.token.utils.Security;
import com.yxcheng.token.utils.UUIDGenerator;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

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

/**
 * 签名服务统一入口
 */
@RestController
@RequestMapping("/signService")
@ComponentScan(basePackages = {"com.tax.sign.service"})
public class SignController extends BaseClientController {

     private static Logger logger = Logger.getLogger(SignController.class);

    @Value("${limit.taxno.list}")
    private String taxnoLimtList;

    @Value("${taxno.sync.url}")
    private String taxnoUrl;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private HttpServletResponse response;

    @Autowired
    private SignService signService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private UserClient userClient;

    @RequestMapping(value ="/getLoginSign" , method = RequestMethod.GET)
//    @LogT
    public JsonResult<SignModel> getLoginSign(SignReq signReq){
        if(!ObjectUtil.checkData(signReq.getTaxno(),signReq.getDqdm(),signReq.getServerRandom())){
            return new JsonResult().errorResponse(ResultEnum.param_error);
        }
        if(StringUtils.isBlank(signReq.getUserName())){
            signReq.setUserName(signReq.getAccessKeyID());
        }
        signReq.setApplyFunction(RestFulApiContants.SIGN);

        CrRpcResult crRpcResult = userClient.isSafe(signReq);
        if(!checkUserSafe(crRpcResult)){
            return JsonResult.errorResult(crRpcResult.getCode(),crRpcResult.getMessage());
        }

//        String accessKeyID = signReq.getAccessKeyID();

//        if(taxnoLimtList.contains(accessKeyID + ",")) {
//            if(!checkTaxnoFromRedis(accessKeyID, signReq.getTaxno())) {
//                return new JsonResult().errorResponse(ResultEnum.no_opt_taxno_error);
//            }
//        }
        return signService.getLoginSign(signReq,request);
    }


    @RequestMapping(value ="/getOneInvSign" , method = RequestMethod.GET)
//    @LogT
    public JsonResult<SignModel> getOneInvSign(OneInvSignReq signReq){
        CrRpcResult crRpcResult = userClient.isSafe(signReq);

        if(!checkUserSafe(crRpcResult)){
            return JsonResult.errorResult(crRpcResult.getCode(),crRpcResult.getMessage());
        }
        return signService.getOneInvSign(signReq,request);
    }


    @RequestMapping(value ="/getSelectSign" , method = RequestMethod.GET)
//    @LogT
    public JsonResult<SignModel> getSelectSign(SignReq signReq){
        CrRpcResult crRpcResult = userClient.isSafe(signReq);

        if(!checkUserSafe(crRpcResult)){
            return JsonResult.errorResult(crRpcResult.getCode(),crRpcResult.getMessage());
        }
        return signService.getSelectSign(signReq,request);
    }


    @RequestMapping(value ="/getDkDownloadSign" , method = RequestMethod.GET)
//    @LogT
    public JsonResult<SignModel> getDkDownloadSign(DkDownloadReq signReq){
        CrRpcResult crRpcResult = userClient.isSafe(signReq);

        if(!checkUserSafe(crRpcResult)){
            return JsonResult.errorResult(crRpcResult.getCode(),crRpcResult.getMessage());
        }
        return signService.getDkDownloadSign(signReq,request);
    }


    @RequestMapping(value ="/getOtherSign" , method = RequestMethod.GET)
//    @LogT
    public JsonResult<SignModel> getOtherSign(SignReq signReq){
        CrRpcResult crRpcResult = userClient.isSafe(signReq);
        if(!checkUserSafe(crRpcResult)) {
            return JsonResult.errorResult(crRpcResult.getCode(), crRpcResult.getMessage());
        }

        return signService.getSuperSign(signReq,request);
    }

    public boolean checkTaxnoFromRedis(String userName, String taxno) {
        return redisService.exists(RedisContants.SIGN_TAXNO_LIST + userName + ":" + taxno);
    }

    public void setTaxnoToRedis(String userName, String taxno) {
        redisService.set(RedisContants.SIGN_TAXNO_LIST + userName + ":" + taxno, DateUtils.getDataString(DateUtils.datetimeFormat));
    }

    @RequestMapping(value ="/flushTaxnoList" , method = RequestMethod.GET)
    public JsonResult flushTaxnoList() {
        JsonResult<SignModel>jsonResult = new JsonResult<SignModel>();
        // 获取当前时间，用于记录
        long start = System.currentTimeMillis();
        String uuid = UUIDGenerator.generate();
        logger.info(uuid + " the flushTaxnoList task number is:" + Thread.currentThread().getName());
        List<String> taxnoList = Lists.newArrayList();
        try {
            taxnoList = TaxnoUtil.getTaxnoList(taxnoUrl);
            for (String taxno : taxnoList) {
                setTaxnoToRedis("bwgf-limit", taxno);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return JsonResult.errorResult("99","刷新异常");
        }
        logger.info(uuid + " flushTaxnoList lost time is :" + (System.currentTimeMillis()-start) + "ms, the taxno number is : " + taxnoList.size());
        return jsonResult;
    }


    @RequestMapping(value ="/decodeTs" , method = RequestMethod.GET)
    @LogT
    public JsonResult<String> decodeTs(SignReq signReq){
        CrRpcResult crRpcResult = userClient.isSafe(signReq);
        if(!checkUserSafe(crRpcResult)) {
            return JsonResult.errorResult(crRpcResult.getCode(), crRpcResult.getMessage());
        }

        Map<String, String> params = ObjectUtil.getParameterMap(request);
        String ts = Security.decodeTs(params.get("cert"), params.get("token"));

        return new JsonResult<String>(ts);
    }


    @RequestMapping(value ="getTime" , method = RequestMethod.GET)
    public JsonResult<String>getTime(){
        return new JsonResult<String>(String.valueOf(new Date().getTime()));
    }


    @RequestMapping(value ="/getPubSign" , method = RequestMethod.GET)
    @LogT
    public JsonResult<String> getPubSign(PubSignReq signReq){
        CrRpcResult crRpcResult = userClient.isSafe(signReq);
        if(!checkUserSafe(crRpcResult)) {
            return JsonResult.errorResult(crRpcResult.getCode(), crRpcResult.getMessage());
        }
        return new JsonResult<String>(SignUtil.getPubSign(signReq.getTaxno(),signReq.getToken(),signReq.getTs()));
    }


    @RequestMapping(value ="/getSuperPubSign" , method = RequestMethod.GET)
    @LogT
    public JsonResult<SignModel> getSuperPubSign(PubSignReq signReq){
        CrRpcResult crRpcResult = userClient.isSafe(signReq);
        if(!checkUserSafe(crRpcResult)) {
            return JsonResult.errorResult(crRpcResult.getCode(), crRpcResult.getMessage());
        }
        return signService.getSuperPubSign(signReq,request);
    }



    @RequestMapping(value ="/getDeduSign" , method = RequestMethod.GET)
    @LogT
    public JsonResult<DeduSignModel> getDeduSign(DeduSignReq signReq){
        CrRpcResult crRpcResult = userClient.isSafe(signReq);
        if(!checkUserSafe(crRpcResult)) {
            return JsonResult.errorResult(crRpcResult.getCode(), crRpcResult.getMessage());
        }
        return signService.getDeduSign(signReq,request);
    }


    @RequestMapping(value ="/getDeduSignNew" , method = RequestMethod.GET)
    @LogT
    public JsonResult<DeduSignModel> getDeduSignNew(DeduSignReq signReq){
        CrRpcResult crRpcResult = userClient.isSafe(signReq);
        if(!checkUserSafe(crRpcResult)) {
            return JsonResult.errorResult(crRpcResult.getCode(), crRpcResult.getMessage());
        }
        return signService.getDeduSignNew(signReq,request);
    }



    @RequestMapping(value ="/getSignCookie" , method = RequestMethod.GET)
    @LogT
    public JsonResult<SignCookieRes> getSignCookie(SignCookieReq signReq){
        CrRpcResult crRpcResult = userClient.isSafe(signReq);
        if(!checkUserSafe(crRpcResult)) {
            return JsonResult.errorResult(crRpcResult.getCode(), crRpcResult.getMessage());
        }
        return signService.getSignCookie(signReq,request,false);
    }


    @RequestMapping(value ="/getSignCookieForInterior" , method = RequestMethod.GET)
    @LogT
    public JsonResult<SignCookieRes> getSignCookieForInterior(SignCookieReq signReq){
        CrRpcResult crRpcResult = userClient.isSafe(signReq);
        if(!checkUserSafe(crRpcResult)) {
            return JsonResult.errorResult(crRpcResult.getCode(), crRpcResult.getMessage());
        }
        return signService.getSignCookie(signReq,request,true);
    }
}
