package cn.superdesk.uniorder.service.thirdpart.szhtxx.electronicInvoice.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.superdesk.uniorder.common.enums.common.CommonSoftDeleteEnum;
import cn.superdesk.uniorder.common.enums.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceResponseCodeEnum;
import cn.superdesk.uniorder.common.numerical.AnBeanUtils;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxResult;
import cn.superdesk.uniorder.dao.entity.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxResultExample;
import cn.superdesk.uniorder.dao.mapper.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxResultMapper;
import cn.superdesk.uniorder.dto._constant.ResourceConstant;
import cn.superdesk.uniorder.dto.param.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxQueryCriteria;
import cn.superdesk.uniorder.dto.param.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxResultQueryCriteria;
import cn.superdesk.uniorder.dto.vo.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxListItemVo;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.electronicInvoice.dto.request.BatchQueryRequest;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.electronicInvoice.dto.request.BatchQueryRequestBodySerialNosItemVo;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.electronicInvoice.dto.response.BatchQueryResponse;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.electronicInvoice.service.BatchQueryCallService;
import cn.superdesk.uniorder.service.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxResultService;
import cn.superdesk.uniorder.service.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Description:
 * @Author: linjinyu
 * @Email linjinyu@avic-s.com
 * @CreateDate: 2022-01-24 11:50:43
 * @UpdateUser: linjinyu
 * @UpdateDate: 2022-01-24 11:50:43
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class SzhtxxElectronicInvoiceFptxxResultServiceImpl implements SzhtxxElectronicInvoiceFptxxResultService {

    @Autowired
    private SzhtxxElectronicInvoiceFptxxResultMapper szhtxxElectronicInvoiceFptxxResultMapper;

    @Autowired
    private SzhtxxElectronicInvoiceFptxxService szhtxxElectronicInvoiceFptxxService;

    @Autowired
    private ResourceConstant resourceConstant;

    /**************************************** thirdpart service start ****************************************/

    @Autowired
    private BatchQueryCallService batchQueryCallService;

    /**************************************** thirdpart service   end ****************************************/


    /****************************************** extends BaseService 部分 start ******************************************/

    @Override
    public int insertSelective(SzhtxxElectronicInvoiceFptxxResult entity) {
        return szhtxxElectronicInvoiceFptxxResultMapper.insertSelective(entity);
    }

    @Override
    public int updateByPrimaryKeySelective(SzhtxxElectronicInvoiceFptxxResult entity) {
        return szhtxxElectronicInvoiceFptxxResultMapper.updateByPrimaryKeySelective(entity);
    }

    @Override
    public void deleteObj(Long id) {
    }

    public int opLogicalDelete(String batchId, String fpqqlsh, LoginSysUser loginSysUser) {

        SzhtxxElectronicInvoiceFptxxResultExample          example  = new SzhtxxElectronicInvoiceFptxxResultExample();
        SzhtxxElectronicInvoiceFptxxResultExample.Criteria criteria = example.createCriteria();

        criteria
                .andFpqqlshEqualTo(fpqqlsh)
                .andDeletedEqualTo(CommonSoftDeleteEnum.正常.getKey())
                .andBatchIdNotEqualTo(batchId);

        return szhtxxElectronicInvoiceFptxxResultMapper.updateByExampleSelective(
                SzhtxxElectronicInvoiceFptxxResult.builder().deleted(CommonSoftDeleteEnum.删除.getKey()).build(),
                example
        );

    }

    @Override
    public SzhtxxElectronicInvoiceFptxxResult findById(Long id) {
        return szhtxxElectronicInvoiceFptxxResultMapper.selectByPrimaryKey(id);
    }

    @Override
    public PageInfo<SzhtxxElectronicInvoiceFptxxResult> findByPaging(Map<String, Object> conditions, Integer pageNun, Integer pageSize) {
        return null;
    }

    @Override
    public List<SzhtxxElectronicInvoiceFptxxResult> findAll(Map<String, Object> queryMap) {
        return null;
    }

    /****************************************** extends BaseService 部分   end ******************************************/


    public void addSzhtxxElectronicInvoiceFptxxResult(SzhtxxElectronicInvoiceFptxxResult entity) {
        szhtxxElectronicInvoiceFptxxResultMapper.insertSelective(entity);
    }

    /**
     * 主要是深圳航信纸质票用
     *
     * @param entity
     * @return
     */
    public int saveOrUpdate(SzhtxxElectronicInvoiceFptxxResult entity) {

        if (StrUtil.isBlank(entity.getBatchId())) {
            return 0;
        }
        if (StrUtil.isBlank(entity.getFpqqlsh())) {
            return 0;
        }

        SzhtxxElectronicInvoiceFptxxResult isExistDb = findByFpqqlsh(entity.getFpqqlsh());

        if (ObjectUtil.isNull(isExistDb)) {
            addSzhtxxElectronicInvoiceFptxxResult(entity);
        } else {
            entity.setId(isExistDb.getId());
            updateByPrimaryKeySelective(entity);
        }

        return 0;


    }


    public void updateSzhtxxElectronicInvoiceFptxxResult(SzhtxxElectronicInvoiceFptxxResult entity) {
        SzhtxxElectronicInvoiceFptxxResult originEntity = szhtxxElectronicInvoiceFptxxResultMapper.selectByPrimaryKey(entity.getId());
//		AssertUtil.notNull(originEntity);
        AnBeanUtils.copy(entity, originEntity);
        szhtxxElectronicInvoiceFptxxResultMapper.updateByPrimaryKeySelective(originEntity);
    }

    public void deleteSzhtxxElectronicInvoiceFptxxResult(Long id) {
        szhtxxElectronicInvoiceFptxxResultMapper.deleteByPrimaryKey(id);
    }

    public SzhtxxElectronicInvoiceFptxxResult findSzhtxxElectronicInvoiceFptxxResultById(Long id) {
        SzhtxxElectronicInvoiceFptxxResult entity = szhtxxElectronicInvoiceFptxxResultMapper.selectByPrimaryKey(id);
//		AssertUtil.notNull(entity);
        return entity;
    }


    public SzhtxxElectronicInvoiceFptxxResult findByFpqqlsh(String fpqqlsh) {


        SzhtxxElectronicInvoiceFptxxResultExample          example  = new SzhtxxElectronicInvoiceFptxxResultExample();
        SzhtxxElectronicInvoiceFptxxResultExample.Criteria criteria = example.createCriteria();

        criteria.andFpqqlshEqualTo(fpqqlsh);

        example.setOrderByClause("create_time DESC");

        List<SzhtxxElectronicInvoiceFptxxResult> resultList = szhtxxElectronicInvoiceFptxxResultMapper.selectByExample(example);

        if (CollUtil.isNotEmpty(resultList)) {
            return resultList.get(0);
        } else {
            return null;
        }


    }

    public R<List<SzhtxxElectronicInvoiceFptxxResult>> pageQuery(Map<String, Object> conditions, int pageNun, int pageSize) {

        SzhtxxElectronicInvoiceFptxxResultExample          example  = new SzhtxxElectronicInvoiceFptxxResultExample();
        SzhtxxElectronicInvoiceFptxxResultExample.Criteria criteria = example.createCriteria();

        // TODO 喜欢用Map 还是 Bean 自己喜欢... 后期添加 转 SzhtxxElectronicInvoiceFptxxResultExample.Criteria
        // SzhtxxElectronicInvoiceFptxxResult szhtxxElectronicInvoiceFptxxResultConditions = BeanUtils.mapToBean(conditions,SzhtxxElectronicInvoiceFptxxResult.class);

        PageHelper.startPage(pageNun, pageSize);
        List<SzhtxxElectronicInvoiceFptxxResult>     resultList = szhtxxElectronicInvoiceFptxxResultMapper.selectByExample(example);
        PageInfo<SzhtxxElectronicInvoiceFptxxResult> page       = new PageInfo<SzhtxxElectronicInvoiceFptxxResult>(resultList);
        PageHelper.clearPage();

        return new R<List<SzhtxxElectronicInvoiceFptxxResult>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), resultList);

    }

    public R<List<SzhtxxElectronicInvoiceFptxxResult>> pageQueryGenericParam(SzhtxxElectronicInvoiceFptxxResultQueryCriteria queryCriteria) {

        SzhtxxElectronicInvoiceFptxxResultExample          example  = new SzhtxxElectronicInvoiceFptxxResultExample();
        SzhtxxElectronicInvoiceFptxxResultExample.Criteria criteria = example.createCriteria();

        // TODO 添加条件... 后期添加 queryCriteria 转 SzhtxxElectronicInvoiceFptxxResultExample.Criteria

        PageHelper.startPage(queryCriteria.getPageNumber(), queryCriteria.getPageSize());
        List<SzhtxxElectronicInvoiceFptxxResult>     resultList = szhtxxElectronicInvoiceFptxxResultMapper.selectByExample(example);
        PageInfo<SzhtxxElectronicInvoiceFptxxResult> page       = new PageInfo<SzhtxxElectronicInvoiceFptxxResult>(resultList);
        PageHelper.clearPage();

        return new R<List<SzhtxxElectronicInvoiceFptxxResult>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), resultList);

    }


    /****************************************** biz start ******************************************/

    /**
     * op转存-通过发票请求唯一流水号转存发票Pdf
     *
     * @param fpqqlsh      发票请求唯一流水号 发票申请编号 发票单编号
     * @param loginSysUser
     * @return
     */
    public int savedPdfUrl(String fpqqlsh, LoginSysUser loginSysUser) {

        int ret = 0;

//		SzhtxxElectronicInvoiceFptxxResult fptxxResult = findByFpqqlsh(fpqqlsh);
//
//		if (ObjectUtil.isNull(fptxxResult)) {
//			return 0;
//		}

        List<SzhtxxElectronicInvoiceFptxxListItemVo> resultList = szhtxxElectronicInvoiceFptxxService.queryGenericParam(
                SzhtxxElectronicInvoiceFptxxQueryCriteria.builder().fpqqlsh(fpqqlsh).build(),
                loginSysUser
        );

        if (CollUtil.isEmpty(resultList)) {
            return 0;
        }

        SzhtxxElectronicInvoiceFptxxListItemVo fptxxResult = resultList.get(0);

        return savedPdfUrl(fptxxResult, loginSysUser);


    }

    public int savedPdfUrl(SzhtxxElectronicInvoiceFptxxListItemVo fptxxResult, LoginSysUser loginSysUser) {

        int ret = 0;

        String excelExportPathRoot             = resourceConstant.getPathRoot();
        String excelExportRelativePathTemplate = resourceConstant.getPathTemplate();
        String excelExportRelativePathStorage  = resourceConstant.getPathStorage();

//		thirdpart.szhtxx.electronicInvoice
        String relativePath = File.separator + "pdf" + File.separator + "thirdpart" + File.separator + "szhtxx" + File.separator + "electronicInvoice" + File.separator;

        String targetBasePath = excelExportPathRoot + excelExportRelativePathStorage;
        // 原本文件名 https://eitest.szhtxx.com/dzfpTest/downPdf/VN4n47kq
        String targetFileNameOriginal = StrUtil.format("{}_{}_{}.pdf", fptxxResult.getFpqqlsh(), fptxxResult.getFpdm(), fptxxResult.getFphm());
        // 转换文件名 发票代码_发票号_开票申请编号_对账单编号.pdf
        String targetFileNameSaved = StrUtil.format("{}_{}_{}_{}.pdf",
                fptxxResult.getFpdm(),
                fptxxResult.getFphm(),
                fptxxResult.getFpqqlsh(),
                fptxxResult.getAccountingOrderSn()
        );

        String targetWriteFileRelativePathOriginal = relativePath + "original" + File.separator;
        String targetWriteFileRelativePathSaved    = relativePath + "saved" + File.separator + fptxxResult.getAccountingOrderSn() + File.separator;

//		FileUtil.touch(targetWriteFileFullPathOriginal);
//		FileUtil.touch(targetWriteFileFullPathSaved);


		/*
		【后端部分完成-20220309-对映文档-2. 积分结算-2.7 金税盘发票-部分整理-20220309】
		https://www.tapd.cn/33003868/prong/stories/view/1133003868001004003
		(4)下载【发票】说明:
		①以rar压缩包的形式下载;
		②压缩包命名:按侨城汇结算中心导出统一命名;
		③压缩包内文件排序:按发票号"从小到大"顺序依次排列显示;
		④压缩包PDF文件命名:发票代码_发票号_开票申请编号_对账单编号.pdf;
		⑤发票PDF内容:为该发票的电子发票票面;
		*/
        try {
            remoteDownloadDelayAndRetry(fptxxResult.getPdfUrl(), targetBasePath, targetWriteFileRelativePathOriginal, targetFileNameOriginal);
            remoteDownloadDelayAndRetry(fptxxResult.getPdfUrl(), targetBasePath, targetWriteFileRelativePathSaved, targetFileNameSaved);

            ret = 1;
        } catch (FileNotFoundException fileNotFoundException) {
            fileNotFoundException.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }


        return ret;
    }

    public void remoteDownloadDelayAndRetry(String urlString, String targetBasePath, String targetRelativePath, String targetFileName) throws Exception {

        try {

            Thread.sleep(3000);
            int ret = remoteDownload(urlString, targetBasePath, targetRelativePath, targetFileName);
            if (ret != 1) {
                Thread.sleep(3000);
                remoteDownload(urlString, targetBasePath, targetRelativePath, targetFileName);
            }
        } catch (FileNotFoundException fileNotFoundException) {
            fileNotFoundException.printStackTrace();
            Thread.sleep(3000);
            remoteDownload(urlString, targetBasePath, targetRelativePath, targetFileName);
        } catch (Exception e) {
            e.printStackTrace();


        }
    }

    public static int remoteDownload(String urlString, String targetBasePath, String targetRelativePath, String targetFileName) throws Exception {

        int ret = 0;

        String targetWriteFileFullPath = targetBasePath + targetRelativePath + targetFileName;

        log.info("remoteDownload info \n{}\n{}\n{}\n{}\n{}", urlString, targetFileName, targetBasePath, targetRelativePath, targetWriteFileFullPath);

        FileUtil.touch(targetWriteFileFullPath);

        CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

        log.info("download start ... {}", urlString);

        URL           url           = new URL(urlString);
        URLConnection urlConnection = url.openConnection();
        InputStream   inputStream   = urlConnection.getInputStream();

        /****************************************** 老旧办法 start ******************************************/

//		byte[]       bs           = new byte[1024];
//		int          length;
//		OutputStream outputStream = new FileOutputStream(targetFileName);
//		while ((length = inputStream.read(bs)) != -1) {
//			outputStream.write(bs, 0, length);
//		}
//		outputStream.close();

        /****************************************** 老旧办法   end ******************************************/


        /****************************************** 开箱即用 start ******************************************/

        FileWriter fileWriter = new FileWriter(targetWriteFileFullPath);
        fileWriter.writeFromStream(inputStream);

        /****************************************** 开箱即用   end ******************************************/

        inputStream.close();

        log.info("download over ... {}", targetFileName);

        ret = 1;

        return ret;
    }

    public int callServiceSzhtxxElectronicInvoiceApiBatchQuery(List<SzhtxxElectronicInvoiceFptxxListItemVo> fptxxListItemVoList, LoginSysUser loginSysUser) {


        List<BatchQueryRequestBodySerialNosItemVo> serialNos = new ArrayList<>();

        fptxxListItemVoList.forEach(item -> {
            serialNos.add(BatchQueryRequestBodySerialNosItemVo
                    .builder()
                    .serialNo(item.getFpqqlsh())
                    .build());
        });

        BatchQueryRequest request = BatchQueryRequest
                .builder()
                .serialNos(serialNos)
                .build();

        BatchQueryResponse response = batchQueryCallService.callBatchQueryApi(request);

//        {
//            "datas":[{
//            "reason":"下载PDF文件成功", "fpdm":"044032000111", "hjse":"-10.70", "returnCodeX":"0000", "serailNo":
//            "CIA2022040778832384R", "pdfUrl":"https://eitest.szhtxx.com:10443/dzfpTest/downPdf/YlbNqy7l", "kprq":
//            "2022-04-07 12:03:10", "returnMsgX":"开票成功", "hjbhsje":"-82.30", "hasPdf":"1", "fphm":"22051255", "jym":
//            "51302223043411840081"
//        }],"returnCode":"0000", "returnMsg":"查询成功！"
//        }

        if (response.getReturnCode().equals(SzhtxxElectronicInvoiceResponseCodeEnum.SUCCESS.getReturnCode())) {
            return 1;
        } else {
            return 0;
        }
    }

    public int entryFileNotFoundPdfSingleTime(SzhtxxElectronicInvoiceFptxxListItemVo listItemVo, LoginSysUser loginSysUser) {

        return 0;
    }

}
