package com.tax.file.service.impl;

import com.google.common.collect.Maps;
import com.tax.file.mapper.TkFileMapper;
import com.tax.file.model.*;
import com.tax.file.model.fileManage.ApplyFileReqModel;
import com.tax.file.service.api.TkFileSegmentService;
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.common.service.AbstractService;
import com.yxcheng.token.utils.DateUtils;
import com.yxcheng.token.utils.MD5Util;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

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


@Transactional
@Component
@ComponentScan(basePackages = {"com.tax.file"})
public class TkFileServiceImpl extends AbstractService<TkFileMapper,TkFileExample,TkFile> implements TkFileService {

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

    @Autowired
    protected TkFileSegmentService tkFileSegmentService;
    @Autowired
    TkTaxUserService tkTaxUserService;

    @Override
    public String queryLastInvDate(TkTaxUser taxUser) {
        return baseMapper.queryLastInvDate(taxUser);
    }

    @Override
    public List<TkFile> queryPastData(TkTaxUser taxUser) {
        return baseMapper.queryPastData(taxUser);
    }

    public List<TkFile> queryApplyFileList(TkTaxUser taxUser) {
        List<TkFile> tkFileList = baseMapper.queryApplyFileList(taxUser);
        return tkFileList;
    }

    public List<TkFile> queryWaitDownFileList(TkTaxUser taxUser) {
        List<TkFile> tkFileList = baseMapper.queryWaitDownFileList(taxUser);
        return tkFileList;
    }

    public List<TkFile> queryResetFileList(TkTaxUser taxUser) {
        List<TkFile> tkFileList = baseMapper.queryResetFileList(taxUser);
        return tkFileList;
    }

    public List<Map<String, Object>> countWaitDownFileList(TkTaxUser taxUser) {
        List<Map<String, Object>> countWaitDownFile = baseMapper.countWaitDownFileList(taxUser);
        return countWaitDownFile;
    }

    public List<TkFile> getTkFilePage(Map map) {
        return baseMapper.getTkFilePage(map);
    }

    @Override
    public List<TkFile> queryExitPastData(TkTaxUser taxUser) {
        return baseMapper.queryExitPastData(taxUser);
    }

    public Map<String, Map<String, TkFile>> queryWaitDownFileMap(TkTaxUser taxUser) {
        Map<String, Map<String, TkFile>> fileGroup = Maps.newHashMap();
        Map<String, TkFile> subFileGroup = null;
        List<TkFile> fileList = queryWaitDownFileList(taxUser);
        for(TkFile tkFile:fileList) {
            String fileKey = tkFile.getFileGroupKey();
            if(fileGroup.containsKey(fileKey)) {
                subFileGroup = fileGroup.get(fileKey);
                subFileGroup.put(tkFile.getFileMd5(), tkFile);
            } else {
                subFileGroup = Maps.newHashMap();
                subFileGroup.put(tkFile.getFileMd5(), tkFile);
                fileGroup.put(fileKey, subFileGroup);
            }
        }
        return fileGroup;
    }

    @Override
    public void updateApplyInfoByPrimaryKey(TkFile tkFile) {
        baseMapper.updateApplyInfoByPrimaryKey(tkFile);
    }

    @Override
    public void saveApplyFileList(String uuidFlag, TkTaxUser taxUser, Map<String, Date> applyDateMap) {
        for(String applyDateStart:applyDateMap.keySet()) {
            Date dateStart = DateUtils.str2Date(applyDateStart, DateUtils.date_sdf);
            Date dateEnd = applyDateMap.get(applyDateStart);
            //获取此税号待申请发票类型列表
            String[] userInvTypes = NationDic.transferInvType(taxUser.getInvType(),taxUser.getSaleInvType(),taxUser.getInvSpec());
            String incomeInvType = userInvTypes[0];
            String saleInvType = userInvTypes[1];
            //申请下载-进项
            if (StringUtils.isNotBlank(incomeInvType)) {
                Arrays.asList(incomeInvType.split(NationDic.divideFlag)).stream().forEach(invType -> {
                    insertTkFile(taxUser, invType, NationDic.INVTYPE_INCOME, dateStart, dateEnd);
                });
            }
            logger.info(uuidFlag + " saveApplyFileList invSpec : " + NationDic.INVTYPE_INCOME + ",invTypes:" + incomeInvType
                    + ",preDateStart:" + DateUtils.date2Str(dateStart, DateUtils.date_sdf)+ ",preDateEnd:" + DateUtils.date2Str(dateEnd, DateUtils.date_sdf));
            //申请下载-销项
            if (StringUtils.isNotBlank(saleInvType)) {
                Arrays.asList(saleInvType.split(NationDic.divideFlag)).stream().forEach(invType -> {
                    insertTkFile(taxUser, invType, NationDic.INVTYPE_SALE, dateStart, dateEnd);
                });
            }
            logger.info(uuidFlag + " saveApplyFileList invSpec : " + NationDic.INVTYPE_SALE + ",invTypes:" + saleInvType
                    + ",preDateStart:" + DateUtils.date2Str(dateStart, DateUtils.date_sdf)+ ",preDateEnd:" + DateUtils.date2Str(dateEnd, DateUtils.date_sdf));
        }
    }

    private void insertTkFile(TkTaxUser taxUser, String invType, String invSpecie, Date preDateStart, Date preDateEnd) {
        TkFileExample tkFileExample = new TkFileExample();
        tkFileExample.createCriteria()
                .andUserNameEqualTo(taxUser.getUserName())
                .andTaxnoEqualTo(taxUser.getTaxno())
                .andInvSpecEqualTo(invSpecie)
                .andInvTypeEqualTo(invType)
                .andInvDateStartEqualTo(DateUtils.toDate(preDateStart,"yyyy-MM-dd"))
                .andInvDateEndEqualTo(DateUtils.toDate(preDateEnd,"yyyy-MM-dd"));
        int tkFileListCount = baseMapper.countByExample(tkFileExample);
        if(tkFileListCount==0){
            TkFile tkFile = createTkFile(taxUser, invType, invSpecie, preDateStart, preDateEnd);
            baseMapper.insertSelective(tkFile);
        }
    }

    private TkFile createTkFile(TkTaxUser taxUser, String invType, String invSpecie, Date preDateStart, Date preDateEnd) {
        Date curDate = DateUtils.getDate();
        TkFile entity = new TkFile();
        entity.setApplyStatus(NationDic.APPLY_STATUS_NO);
        entity.setInvType(invType);
        entity.setTaxno(taxUser.getTaxno());
        entity.setInvSpec(invSpecie);
        entity.setInvDateStart(preDateStart);
        entity.setInvDateEnd(preDateEnd);
        entity.setDecPwd(NationUtil.defaultPwd);
        entity.setUserName(taxUser.getUserName());
        entity.setZoneCode(taxUser.getZoneCode());
        entity.setCreateDate(curDate);
        entity.setUpdateDate(curDate);
        String beMonth = DateUtils.getMonth(preDateStart);
        entity.setFileMonth(beMonth);
        entity.setFileNum(0);
        //判断是否整月
        int daysOfMonth = DateUtils.getDaysOfMonth(preDateStart);
        long days = DateUtils.getDaySub(preDateStart, preDateEnd) + 1;
        if(daysOfMonth == days) {
            entity.setFileDataType("1");
        } else {
            entity.setFileDataType("0");
        }
        entity.setFileMd5(MD5Util.MD5Encode(taxUser.getTaxno() + invSpecie + invType
                + DateUtils.date2Str(preDateStart, DateUtils.date_sdf) + DateUtils.date2Str(preDateEnd, DateUtils.date_sdf)));
        return entity;
    }

    public void saveErrorFileInfo(TkFile tkFile, String errorType) {
        tkFile.setDownStatus("2");
        if(errorType.equals("1")) {
            tkFile.setErrorCode(DownFileInfoModel.DOWNLOAD_TIMES_OVER);
            tkFile.setFileName(DownFileInfoModel.DOWNLOAD_TIMES_OVER_CN);
        } else if(errorType.equals("2")) {
            tkFile.setErrorCode(DownFileInfoModel.RUNNING);
            tkFile.setFileName(DownFileInfoModel.RUNNING_CN);
        }
        tkFile.setUpdateDate(DateUtils.getDate());
        updateByPrimaryKey(tkFile);
    }

    public void updateApplyFileList(List<TkFile> applyFileList) {
        for(TkFile applyFile :applyFileList){
            updateByPrimaryKeySelective(applyFile);
        }
    }

    public void deleteFileInfo(TkFile tkFile) {
        deleteByPrimaryKey(tkFile.getId());
        if(tkFile.getFileNum() > 1) {
            List<TkFileSegment> fileSegmentList = tkFileSegmentService.queryFileSegList(tkFile);
            for(TkFileSegment fileSegment:fileSegmentList) {
                tkFileSegmentService.deleteByPrimaryKey(fileSegment.getId());
            }
        }
    }

    @Override
    public void saveHandApplyFileList(String uuidFlag, TkTaxUser taxUser, List<ApplyFileReqModel> applyInfoList) {
        int saveNum = 0;
        for(ApplyFileReqModel applyFileReqModel:applyInfoList) {
            if(applyFileReqModel.getErrorCode().equals("0")) {
                String applyDateStart = applyFileReqModel.getApplyDateStart();
                String applyDateEnd = applyFileReqModel.getApplyDateEnd();

                Date dateStart = DateUtils.str2Date(applyDateStart,  new SimpleDateFormat("yyyy-MM-dd"));
                Date dateEnd = DateUtils.str2Date(applyDateEnd,  new SimpleDateFormat("yyyy-MM-dd"));

                String invType = applyFileReqModel.getInvType();
                String invSpec =  applyFileReqModel.getInvSpec();

                TkFile oldTkFile = getTkFileBy(taxUser, invType, invSpec, dateStart, dateEnd);
                if(null == oldTkFile){
                    TkFile entity = new TkFile();
                    createTkFile(taxUser, entity, invType, invSpec, dateStart, dateEnd, applyDateStart, applyDateEnd);
                    baseMapper.insertSelective(entity);
                    saveNum++;
                } else {
                    if(applyFileReqModel.getForceApplyFlag().equals("1")) {
                        baseMapper.deleteByPrimaryKey(oldTkFile.getId());
                        TkFile entity = new TkFile();
                        createTkFile(taxUser, entity, invType, invSpec, dateStart, dateEnd, applyDateStart, applyDateEnd);
                        baseMapper.insertSelective(entity);
                        saveNum++;
                    } else {
                        if(oldTkFile.getDownStatus().equals("1")) {
                            applyFileReqModel.setErrorCode("3");
                            applyFileReqModel.setErrorMessage("申请文件已经处理完成");
                        } else {
                            applyFileReqModel.setErrorCode("2");
                            applyFileReqModel.setErrorMessage("申请文件正在处理中");
                            applyFileReqModel.setFileErrorMessage(oldTkFile.getFileErrorMessage());
                        }
                    }
                }
            }
            logger.info(uuidFlag + " saveApplyFileList invSpec : " + applyFileReqModel.getInvSpec() + ",invTypes:" + applyFileReqModel.getInvType()
                    + ",forceApplyFlag:" + applyFileReqModel.getForceApplyFlag()
                    + ",applyDateStart:" + applyFileReqModel.getApplyDateStart() + ",applyDateEnd:" + applyFileReqModel.getApplyDateEnd()
                    + ",errorCode:" + applyFileReqModel.getErrorCode() + ",errorMessage:" + applyFileReqModel.getErrorMessage()
                    + ",fileErrorMessage:" + applyFileReqModel.getFileErrorMessage());
        }
        if(saveNum>0) {
            Date curDate = DateUtils.getDate();
            taxUser.setApplyStatus("1");
            taxUser.setDownStatus("1");
            taxUser.setOverFlag("0");
            taxUser.setApplyDownDate(curDate);
            taxUser.setUpdateDate(curDate);
            //手工申请时间点记录
            taxUser.setApplyBreakPoint(curDate);
            tkTaxUserService.updateByPrimaryKeySelective(taxUser);
        }
    }

    @Override
    public List<TkFile> queryErrorFileList(TkTaxUser taxUser, String fileMonth) {
        taxUser.setFileMonth(fileMonth);
        return baseMapper.queryErrorFileList(taxUser);
    }

    private TkFile getTkFileBy(TkTaxUser taxUser, String invType, String invSpecie, Date dateStart, Date dateEnd) {
        TkFileExample tkFileExample = new TkFileExample();
        tkFileExample.createCriteria()
                .andUserNameEqualTo(taxUser.getUserName())
                .andTaxnoEqualTo(taxUser.getTaxno())
                .andInvSpecEqualTo(invSpecie)
                .andInvTypeEqualTo(invType)
                .andInvDateStartEqualTo(dateStart)
                .andInvDateEndEqualTo(dateEnd);
        List<TkFile> tkFileList = baseMapper.selectByExample(tkFileExample);
        if(tkFileList.size()>0) {
            return tkFileList.get(0);
        }
        return null;
    }

    private TkFile createTkFile(TkTaxUser taxUser, TkFile entity, String invType, String invSpecie, Date dateStart, Date dateEnd, String applyDateStart, String applyDateEnd) {
        Date curDate = DateUtils.getDate();
        entity.setApplyStatus(NationDic.APPLY_STATUS_NO);
        entity.setInvType(invType);
        entity.setTaxno(taxUser.getTaxno());
        entity.setInvSpec(invSpecie);
        entity.setInvDateStart(dateStart);
        entity.setInvDateEnd(dateEnd);
        entity.setInvDateStartStr(applyDateStart);
        entity.setInvDateEndStr(applyDateEnd);
        entity.setDecPwd(NationUtil.defaultPwd);
        entity.setUserName(taxUser.getUserName());
        entity.setZoneCode(taxUser.getZoneCode());
        entity.setCreateDate(curDate);
        entity.setUpdateDate(curDate);
        String beMonth = DateUtils.getMonth(dateEnd);
        entity.setFileMonth(beMonth);
        entity.setFileNum(0);
        //判断是否整月
        int daysOfMonth = DateUtils.getDaysOfMonth(dateEnd);
        long days = DateUtils.getDaySub(dateStart, dateEnd) + 1;
        if(daysOfMonth == days) {
            entity.setFileDataType("1");
        } else {
            entity.setFileDataType("0");
        }
        entity.setFileMd5(MD5Util.MD5Encode(taxUser.getTaxno() + invSpecie + invType + applyDateStart + applyDateEnd));
        return entity;
    }
}
