package com.tax.file.service.async.apply;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tax.file.constants.CommonConstants;
import com.tax.file.model.ApplyFileModel;
import com.tax.file.model.TkFile;
import com.tax.file.model.TkTaxUser;
import com.tax.file.service.api.FileTokenService;
import com.tax.file.service.api.TkFileService;
import com.tax.file.service.api.TkTaxUserService;
import com.tax.file.utils.NationDic;
import com.tax.file.utils.NationUtil;
import com.yxcheng.token.constants.RedisContants;
import com.yxcheng.token.utils.DateUtils;
import com.yxcheng.token.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Order(2)
@Component
public class SecondApplyFileService extends AbstractApplyService implements ApplyService{

    private static final Logger logger = LoggerFactory.getLogger(SecondApplyFileService.class);

    @Autowired
    protected TkFileService tkFileService;
    @Autowired
    protected TkTaxUserService tkTaxUserService;
    @Autowired
    private FileTokenService fileTokenService;

    @Override
    public boolean apply(String uuidFlag, TkTaxUser taxUser, Map<String, String> context) {
        boolean applyFlag = false;

        boolean overMonthFlag = false;
        String overMonth = "";
        String curMonth = DateUtils.getDataString(new SimpleDateFormat("yyyyMM"));
        List<TkFile> fileList = tkFileService.queryApplyFileList(taxUser);
        logger.info(uuidFlag + " taxno is " + taxUser.getTaxno() + " SecondApplyFileService is start.The file number is " + fileList.size());
        if(fileList.size()>0) {
            for(TkFile tkFile:fileList) {
                String taxno = taxUser.getTaxno();
                logger.info(uuidFlag + " taxno is " + taxUser.getTaxno() + " apply file " + tkFile.getInvoiceInfo() + " is start.");

                String resultIndex = SUCCCESS;
                String fileMonth = tkFile.getFileMonth();
                //跨月后不再申请部分月份，直接作废
                if(tkFile.getFileDataType().equals("0") && !curMonth.equals(fileMonth)) {
                    applyFlag = true;
                    resultIndex = PAST;
                    tkFile.setApplyErrorCode(resultIndex);
                    tkFile.setApplyStatus(NationDic.APPLY_STATUS_FAIL);
                    tkFile.setResponseStatus(NationDic.RESPONSE_STATUS_PAST);
                    tkFile.setUpdateDate(DateUtils.getDate());
                    tkFileService.updateApplyInfoByPrimaryKey(tkFile);
                } else {
                    ApplyFileModel applyFileModel = fileApply(uuidFlag, taxUser, context, tkFile);
                    boolean applyResult = applyFileModel.isApplyResult();
                    resultIndex = applyFileModel.getApplyErrorCode();
                    if(applyResult) {
                        //有一个成功，就认为申请成功，需要下载
                        applyFlag = true;
                        tkFile.setApplyErrorCode(resultIndex);
                        if(resultIndex.equals(SUCCCESS)) {
                            tkFile.setApplyStatus(NationDic.APPLY_STATUS_YES);
                            tkFile.setOldApplyDate(null);
                        }
                        if(resultIndex.equals(ThirtyDays)) {
                            tkFile.setApplyStatus(NationDic.APPLY_STATUS_FAIL);
                            tkFile.setOldApplyDate(parseApplyDate(uuidFlag, taxno, applyFileModel.getApplyResultMessage()));
                        }
                        if(resultIndex.equals(OverApplyCurMonth)) {
                            tkFile.setApplyStatus(NationDic.APPLY_STATUS_FAIL);
                        }
                        tkFile.setUpdateDate(DateUtils.getDate());
                        tkFileService.updateApplyInfoByPrimaryKey(tkFile);

                        if(resultIndex.equals(OverApply)) {
                            //历史月达到两条申请退出申请
                            overMonthFlag = true;
                            overMonth = tkFile.getFileMonth();
                            setOverMonth(taxUser.getUserName(), taxno, tkFile.getInvType(), tkFile.getInvSpec(), tkFile.getFileMonth());
                            break;
                        }
                    } else {
                        //如果token过期后续全部跳出
                        if(resultIndex.equals(TokenOver)) {
                            break;
                        }
                    }
                }
                logger.info(uuidFlag + " taxno is " + taxUser.getTaxno() + " apply file " + tkFile.getInvoiceInfo() + " result : " + applyFlag +  ",resultIndex:" + resultIndex);
            }
        } else {
            applyFlag = true;
        }
        if(overMonthFlag) {
            tkFileService.updateApplyResetFileList(uuidFlag, taxUser, overMonth);
        }
        if(applyFlag) {
            tkTaxUserService.updateDownloadUserInfo(uuidFlag, taxUser, "0");
        }

        logger.info(uuidFlag + " taxno is " + taxUser.getTaxno() + " SecondApplyFileService is end!The applyFlag is " + applyFlag);
        return applyFlag;
    }

    private ApplyFileModel fileApply(String uuidFlag, TkTaxUser user, Map<String,String> context, TkFile entity){
        boolean isFinish = false;
        String resultIndex = FAIL;
        String responseResult = "";
        Date reqDate = DateUtils.getDate();
        String message = "";
        String dataStr = "error";
        try {
            //申请与局端交互
            entity.setToken(context.get(user.getTaxno()));

            String invDateStart = entity.getInvDateStartStr();
            String invDateEnd = entity.getInvDateEndStr();
            dataStr = NationUtil.getFileDownApplyParams(entity, invDateStart, invDateEnd);
            if(invDateStart.equals(invDateEnd)) {
                logger.error(uuidFlag + " taxno:" + user.getTaxno() + " fileApply invDateStart is:" + invDateStart + "=" + invDateEnd);
                message = "申请日期出错";
            } else {
                JSONObject result = NationUtil.fileDownApply(uuidFlag, entity, invDateStart, invDateEnd, dataStr);
                if(result!=null){
                    String code = result.getString("key1");
                    message = result.getString("key2");
                    if("01".equals(code)){
                        isFinish = true;
                        resultIndex = SUCCCESS;
                    } else if("n4000001".equals(code)){
                        //申请过的
                        if(message.contains(CommonConstants.THIRTY_DAYS_MSG)) {//30天内不能重复申请
                            isFinish = true;
                            resultIndex = ThirtyDays;
                        } else if(message.contains(CommonConstants.OVER_APPLY_MSG)) {//已经达到2条
                            isFinish = true;
                            resultIndex = OverApply;
                        } else if(message.contains(CommonConstants.OVER_APPLY_24_MSG) || message.contains(CommonConstants.OVER_APPLY_48_MSG)) {//24小时内不能重复申请，此种情况认为是成功
                            isFinish = true;
                            resultIndex = SUCCCESS;
                        } else if(message.contains(CommonConstants.OVER_APPLY_CURRENT_MONTH_MSG)) {//达到允许上限
                            isFinish = true;
                            resultIndex = OverApplyCurMonth;
                        }
                    } else if("w4000000".equals(code)) {
                        resultIndex = TokenOver;
                        fileTokenService.noticeGetNewToken(uuidFlag, user);
                    }
                    if(!isFinish){
                        timesLimitStrategy.addTime(RedisContants.getLimitName(RedisContants.FILE_APPLY_TIMES_LOCK, user.getUserName(), user.getTaxno()));
                    }
                    responseResult = JSON.toJSONString(result);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            responseResult = StringUtil.getShortLog(e.getMessage(), 500);
            timesLimitStrategy.addTime(RedisContants.getLimitName(RedisContants.FILE_APPLY_TIMES_LOCK, user.getUserName(), user.getTaxno()));
            logger.error(uuidFlag + " taxno:" + user.getTaxno() + " fileDownApply is error:" + e.getMessage());
        }
        fileTaxLogService.saveLog(uuidFlag, user.getTaxno(), reqDate, dataStr, responseResult, DateUtils.getDate(),"1", entity, resultIndex);
        return new ApplyFileModel(isFinish, resultIndex, message);
    }

    public Date parseApplyDate(String uuidFlag, String taxno, String applyMessage) {
        Date applyDate = DateUtils.addDate(DateUtils.getDate(), -25);
        try {
            if(StringUtil.isNotEmpty(applyMessage) && applyMessage.contains("年") && applyMessage.contains("月") && applyMessage.contains("日")) {
                String applyDateStr = applyMessage.substring(applyMessage.indexOf("已经于") + 3, applyMessage.indexOf("提交申请"));
                applyDate = DateUtils.parseDate(applyDateStr, "yyyy年MM月dd日");
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(uuidFlag + " taxno:" + taxno + " parseApplyDate:" + applyMessage + " is error!" + e.getMessage());
        }
        return applyDate;
    }

    public void setOverMonth(String userName, String taxno, String invType, String invSpec, String incomeMonth) {
        redisService.set(RedisContants.getLimitName(RedisContants.FILE_APPLY_ALARM, userName, taxno),invType + "=" + invSpec + "=" + incomeMonth,60*60);
        redisService.set(RedisContants.getLimitName(RedisContants.FILE_APPLY_ALARM, userName, taxno) + invType + invSpec + incomeMonth,"1",60*60);
    }



    public static void main(String[] args) {
        try {
        Date applyDate = DateUtils.addDate(DateUtils.getDate(), -25);
        String applyMessage = "增值税普通发票（卷票）进项票开票（填发）为2021年09月已经于2021年10月02日提交申请，30天内不能重复申请";
        if(StringUtil.isNotEmpty(applyMessage) && applyMessage.contains("年") && applyMessage.contains("月") && applyMessage.contains("日")) {
            String applyDateStr = applyMessage.substring(applyMessage.indexOf("已经于") + 3, applyMessage.indexOf("提交申请"));
            System.out.println(applyDateStr);
            applyDate = DateUtils.parseDate(applyDateStr, "yyyy年MM月dd日");
        }
        System.out.println(applyDate);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
