package com.bailuntec.job;

import com.alibaba.fastjson.JSON;
import com.bailuntec.domain.entity.DcBaseCompanyAccount;
import com.bailuntec.domain.entity.DcBaseFinanceAmazonAdProduct;
import com.bailuntec.domain.entity.JobAmazonAdLog;
import com.bailuntec.domain.enumerate.CurrencyType;
import com.bailuntec.domain.example.DcBaseCompanyAccountExample;
import com.bailuntec.domain.example.DcBaseFinanceAmazonAdProductExample;
import com.bailuntec.domain.pojo.AmazonAdAuth;
import com.bailuntec.domain.pojo.AmazonAdProduct;
import com.bailuntec.mapper.DcBaseCompanyAccountMapper;
import com.bailuntec.mapper.DcBaseFinanceAmazonAdProductMapper;
import com.bailuntec.mapper.JobAmazonAdLogMapper;
import com.bailuntec.support.CallBailunSystem;
import com.bailuntec.utils.OkHttpUtil;
import com.bailuntec.utils.SessionUtil;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.ibatis.session.SqlSession;

import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;

@Slf4j
public class AmazonAdDownloadReportJob implements SimpleJob {

    private final OkHttpClient client = OkHttpUtil.getInstance();


    @Override
    public void execute(ShardingContext shardingContext) {

        SqlSession sqlSession = SessionUtil.getFactory().openSession(true);

        try {

            JobAmazonAdLogMapper jobAmazonAdLogMapper = sqlSession.getMapper(JobAmazonAdLogMapper.class);
            DcBaseCompanyAccountMapper dcBaseCompanyAccountMapper = sqlSession.getMapper(DcBaseCompanyAccountMapper.class);
            DcBaseFinanceAmazonAdProductMapper dcBaseFinanceAmazonAdProductMapper = sqlSession.getMapper(DcBaseFinanceAmazonAdProductMapper.class);

            //获取15分钟前未下载的报告 注：省略报告状态判断 直接根据时间
            List<JobAmazonAdLog> jobAmazonAdLogList = jobAmazonAdLogMapper.selectUnDownload(shardingContext, LocalDateTime.now());

            jobAmazonAdLogList
//                    .stream()
//                    .filter(jobAmazonAdLog -> jobAmazonAdLog.getAccountId().equals(671))
                    .forEach(jobAmazonAdLog -> {
                        DcBaseCompanyAccount dcBaseCompanyAccount = dcBaseCompanyAccountMapper.selectOneByExample(DcBaseCompanyAccountExample.newAndCreateCriteria()
                                .andCompanyIdEqualTo(jobAmazonAdLog.getCompanyId())
                                .andAccountIdEqualTo(jobAmazonAdLog.getAccountId())
                                .example());

                        AmazonAdAuth amazonAdAuth = JSON.parseObject(dcBaseCompanyAccount.getAmazonAdAuthJson(), AmazonAdAuth.class);

                        Request request = new Request.Builder()
                                .url(AmazonAdGenerateReportIdJob.switchSiteUrl(jobAmazonAdLog.getSiteEn(), jobAmazonAdLog.getReportId()))
                                .get()
                                .addHeader("Authorization", amazonAdAuth.getAccessToken())
                                .addHeader("Amazon-Advertising-API-ClientId", amazonAdAuth.getClientId())
                                .addHeader("Amazon-Advertising-API-Scope", amazonAdAuth.getProfileId())
                                .addHeader("Content-Type", "application/json")
                                .build();

                        try (Response response = client.newCall(request).execute()) {
                            if (response.isSuccessful() && response.body() != null) {

                                log.info("解析报告成功 账号Id：{} 报告时间：{} ，文件大小为:{} ",
                                        jobAmazonAdLog.getAccountId(),
                                        jobAmazonAdLog.getReportDate(),
                                        response.body().contentLength()
                                );
                                try (GZIPInputStream gzipInputStream = new GZIPInputStream(response.body().byteStream())) {
                                    Type type = new TypeToken<List<AmazonAdProduct>>() {
                                    }.getType();
                                    List<AmazonAdProduct> amazonAdProductList = JSON.parseObject(gzipInputStream, type);
                                    amazonAdProductList = amazonAdProductList.stream()
                                            .filter(amazonAdProduct -> amazonAdProduct.getCost() != null)
                                            .filter(amazonAdProduct -> amazonAdProduct.getCost().compareTo(BigDecimal.ZERO) > 0)
                                            .collect(Collectors.toList());

                                    for (AmazonAdProduct amazonAdProduct : amazonAdProductList) {
                                        if (amazonAdProduct.getCost() != null && BigDecimal.ZERO.compareTo(amazonAdProduct.getCost()) < 0) {

                                            DcBaseFinanceAmazonAdProductExample example = DcBaseFinanceAmazonAdProductExample.newAndCreateCriteria()
                                                    .andCompanyIdEqualTo(jobAmazonAdLog.getCompanyId())
                                                    .andAccountIdEqualTo(jobAmazonAdLog.getAccountId())
                                                    .andReportDateEqualTo(jobAmazonAdLog.getReportDate())
                                                    .andCampaignIdEqualTo(amazonAdProduct.getCampaignId())
                                                    .andAdGroupIdEqualTo(amazonAdProduct.getAdGroupId())
                                                    .andTypeEqualTo(jobAmazonAdLog.getType())
                                                    .andSkuEqualTo(amazonAdProduct.getSku())
                                                    .example();

                                            DcBaseFinanceAmazonAdProduct dcBaseFinanceAmazonAdProduct = dcBaseFinanceAmazonAdProductMapper.selectOneByExample(example);
                                            if (dcBaseFinanceAmazonAdProduct == null) {
                                                dcBaseFinanceAmazonAdProduct = new DcBaseFinanceAmazonAdProduct();
                                            }
                                            BeanUtils.copyProperties(dcBaseFinanceAmazonAdProduct, amazonAdProduct);

                                            dcBaseFinanceAmazonAdProduct.setAccountId(jobAmazonAdLog.getAccountId());
                                            dcBaseFinanceAmazonAdProduct.setCompanyId(jobAmazonAdLog.getCompanyId());
                                            dcBaseFinanceAmazonAdProduct.setReportDate(jobAmazonAdLog.getReportDate());
                                            dcBaseFinanceAmazonAdProduct.setExchangeRate(CallBailunSystem.getExchangeRate(dcBaseFinanceAmazonAdProduct.getCurrency(), CurrencyType.CNY.value(), jobAmazonAdLog.getReportDate().atStartOfDay()));
                                            dcBaseFinanceAmazonAdProduct.setExchangeRateUsd(CallBailunSystem.getExchangeRate(dcBaseFinanceAmazonAdProduct.getCurrency(), CurrencyType.USD.value(), jobAmazonAdLog.getReportDate().atStartOfDay()));
                                            dcBaseFinanceAmazonAdProduct.setBjModifyTime(LocalDateTime.now());
                                            dcBaseFinanceAmazonAdProduct.setType(jobAmazonAdLog.getType());

                                            dcBaseFinanceAmazonAdProductMapper.upsertSelective(dcBaseFinanceAmazonAdProduct);
                                        }
                                    }

                                    jobAmazonAdLog.setStatus(true);
                                    jobAmazonAdLog.setBjModified(LocalDateTime.now());
                                    jobAmazonAdLogMapper.updateByPrimaryKeySelective(jobAmazonAdLog);
                                }
                            } else {
                                log.error("解析报告失败 账号Id：{} 报告时间：{},response:{}",
                                        jobAmazonAdLog.getAccountId(),
                                        jobAmazonAdLog.getReportDate(),
                                        response.body().string()
                                );
                            }

                        } catch (Exception ex) {
                            log.error("下载报表失败:{}", ex.getMessage(), ex);
                        }
                    });

        } finally {
            sqlSession.close();
        }
    }

}
