package com.bailuntec.job;

import com.alibaba.fastjson.JSON;
import com.bailuntec.domain.AccountTokenInfo;
import com.bailuntec.domain.entity.DcBaseFinanceAmazon;
import com.bailuntec.domain.entity.JobPointLog;
import com.bailuntec.domain.enumerate.CurrencyType;
import com.bailuntec.mapper.DcBaseFinanceAmazonMapper;
import com.bailuntec.support.CallBailunSystem;
import com.bailuntec.support.PointJob;
import com.bailuntec.utils.OkHttpUtil;
import com.bailuntec.utils.PropertiesUtil;
import com.bailuntec.utils.SessionUtil;
import com.dangdang.ddframe.job.api.ShardingContext;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipException;

@Slf4j
public class AdvertAddTaskSyncJob extends PointJob {

    private PropertiesUtil propertiesUtil = PropertiesUtil.getInstance("const");
    private OkHttpClient client = OkHttpUtil.getInstance();

    @Override
    public void executeJob(ShardingContext shardingContext, JobPointLog jobPointLog) {
        callAddTask(jobPointLog);
    }

    public void callAddTask(JobPointLog job) {
        LocalDateTime localDateTime = job.getStartTime();
        MediaType mediaType = MediaType.parse("application/json");
        Response response = null;
        try {
            do {
                List<Map> list = null;
                try{
                    Request request0 = new Request.Builder()
                            .url(propertiesUtil.getPropertyAsString("ACCOUNT_API"))
                            .addHeader("Content-Type", "application/json")
                            .build();
                    response = client.newCall(request0).execute();
                    AccountTokenInfo resultMap0 = JSON.parseObject(response.body().string(), AccountTokenInfo.class);
                    list = resultMap0.getData();
                }catch (IOException e){
                    throw new RuntimeException("调用百伦授权接口失败,详情:" + transform(e));
                }
                Map<String, String> authJsonMap = new HashMap<String, String>();
                if(list != null && list.size() > 0) {
                    for(Map map0 : list) {
                        String authStr = ((String) map0.get("AmazonAdAuthJson"));
                        if(StringUtils.isBlank(authStr)){
                            continue;
                        }
                        authJsonMap = JSON.parseObject(authStr, Map.class);
                        Map<String, String> resultMap = new HashMap<>();
                        try{
                            Map<String, String> map = new HashMap<>();
                            map.put("reportDate", localDateTime.format(DateTimeFormatter.ofPattern("yyyyMMdd")));
                            map.put("metrics", propertiesUtil.getPropertyAsString("METRICS"));
                            RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(map));
                            Request request = new Request.Builder()
                                    .url(propertiesUtil.getPropertyAsString("CAMPAIGNS_REPORT"))
                                    .post(body)
                                    .addHeader("Authorization", "Bearer " + authJsonMap.get("access_token"))
                                    .addHeader("Amazon-Advertising-API-ClientId", authJsonMap.get("client_id"))
                                    .addHeader("Amazon-Advertising-API-Scope", authJsonMap.get("profile_id"))
                                    .addHeader("Content-Type", "application/json")
                                    .build();
                            response = client.newCall(request).execute();
                            resultMap = JSON.parseObject(response.body().string(), Map.class);
                        }catch (IOException e){
                            throw new RuntimeException("调用广告费报告任务下发接口失败,错误详情:" + transform(e));
                        }
                        if("IN_PROGRESS".equals(resultMap.get("status"))) {
                            Map<String, String> resultMap2 = new HashMap<>();
                            try{
                                Request request2 = new Request.Builder()
                                        .url(propertiesUtil.getPropertyAsString("V2_REPORTS") + resultMap.get("reportId"))
                                        .addHeader("Authorization", "Bearer " + authJsonMap.get("access_token"))
                                        .addHeader("Amazon-Advertising-API-ClientId", authJsonMap.get("client_id"))
                                        .addHeader("Amazon-Advertising-API-Scope", authJsonMap.get("profile_id"))
                                        .addHeader("Content-Type", "application/json")
                                        .build();
                                response = client.newCall(request2).execute();
                                resultMap2 = JSON.parseObject(response.body().string(), Map.class);
                            }catch (IOException e){
                                throw new RuntimeException("调用广告费报告下载路径错误,错误详情:" + transform(e));
                            }
                            if("SUCCESS".equals(resultMap2.get("status"))) {
                                try{
                                    String location = resultMap2.get("location");
                                    Request request3 = new Request.Builder()
                                            .url(location)
                                            .addHeader("Authorization", "Bearer " + authJsonMap.get("access_token"))
                                            .addHeader("Amazon-Advertising-API-ClientId", authJsonMap.get("client_id"))
                                            .addHeader("Amazon-Advertising-API-Scope", authJsonMap.get("profile_id"))
                                            .addHeader("Content-Type", "application/json")
                                            .build();
                                    response = client.newCall(request3).execute();
                                    GZIPInputStream gzin = new GZIPInputStream(response.body().byteStream());
                                    InputStreamReader isr = new InputStreamReader(gzin, "utf8");
                                    BufferedReader bufferedReader = new BufferedReader(isr);
                                    String str = null;
                                    StringBuffer sb = new StringBuffer();
                                    while((str = bufferedReader.readLine()) != null){
                                        sb.append(str);
                                    }
                                    List<DcBaseFinanceAmazon> amazonAdverts = JSON.parseArray(sb.toString(), DcBaseFinanceAmazon.class);
                                    for(DcBaseFinanceAmazon amazonAdvert : amazonAdverts) {
                                        if(BigDecimal.ZERO.compareTo(amazonAdvert.getCost()) == -1) {
                                            amazonAdvert.setAccountId((Integer) map0.get("Id"));
                                            amazonAdvert.setCompanyId((Integer) map0.get("UserId"));
                                            amazonAdvert.setReportDate(localDateTime.toLocalDate());
                                            if(amazonAdvert.getCurrency() != null) {
                                                BigDecimal exchangeRate = CallBailunSystem.getExchangeRate(amazonAdvert.getCurrency(), CurrencyType.CNY.value(), localDateTime);
                                                amazonAdvert.setOtherToCnyExchangeRate(exchangeRate);
                                            }
                                       //     amazonAdvert.setReportType(reportType);
                                            try {
                                                DcBaseFinanceAmazonMapper dcBaseFinanceAmazonMapper = SessionUtil.getSession().getMapper(DcBaseFinanceAmazonMapper.class);
                                                dcBaseFinanceAmazonMapper.upsertSelective(amazonAdvert);
                                            } catch (Exception e) {
                                                e.printStackTrace();
                                                throw new RuntimeException("Mybatis操作DB插入任务记录失败,错误详情:" + transform(e));
                                            } finally {
                                                SessionUtil.closeSession();
                                            }
                                        }
                                    }
                                    gzin.close();
                                    isr.close();
                                }catch (ZipException e){
                                    log.warn("返回数据为非gz压缩格式", response.body().toString());
                                }catch (IOException e){
                                    throw new RuntimeException("调用广告费报告解析接口报错,错误详情:" + transform(e));
                                }
                            }
                        }else{
                            if(job.getPageIndex() == 2) {
                                try{
                                    Map errorMap = new HashMap();
                                    Map contentMap = new HashMap();
                                    contentMap.put("content", "帐号id:"+ map0.get("Id")+"授权失败,错误详情:"+resultMap);
                                    errorMap.put("msgtype", "text");
                                    errorMap.put("text", contentMap);
                                    RequestBody errorBody = RequestBody.create(mediaType, JSON.toJSONString(errorMap));
                                    Request request2 = new Request.Builder()
                                            .url(propertiesUtil.getPropertyAsString("WARN_API"))
                                            .post(errorBody)
                                            .addHeader("Content-Type", "application/json")
                                            .build();
                                    response = client.newCall(request2).execute();
                                }catch (Exception e){
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                }
                localDateTime = localDateTime.plusDays(1L);
            } while (!localDateTime.isAfter(job.getEndTime()));
            job.setStartTime(job.getEndTime());
            job.setEndTime(job.getStartTime().plusDays(job.getIntervalTime()).isAfter(LocalDateTime.now()) ? LocalDateTime.now() : job.getEndTime().plusDays(job.getIntervalTime()));
        } catch (Exception e) {
            throw new RuntimeException( e);
        } finally {
            if (response != null) {
                response.close();
            }
        }
    }

    public String transform(final Throwable cause) {
        if (null == cause) {
            return "";
        }
        StringWriter result = new StringWriter();
        try (PrintWriter writer = new PrintWriter(result)) {
            cause.printStackTrace(writer);
        }
        return result.toString();
    }
}
