package com.bailuntec.job;

import com.alibaba.fastjson.JSON;
import com.bailuntec.domain.WishAuth;
import com.bailuntec.domain.WishExceptionInfo;
import com.bailuntec.domain.WishInfo;
import com.bailuntec.domain.entity.*;
import com.bailuntec.domain.enumerate.AccountPlatformType;
import com.bailuntec.domain.enumerate.CurrencyType;
import com.bailuntec.domain.example.*;
import com.bailuntec.mapper.*;
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.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class WishSyncJob extends PointJob {

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

    @Override
    public void executeJob(ShardingContext shardingContext, JobPointLog jobPointLog) {
        int totalPage = getCount();
        try{
            JobAccountLogMapper jobAccountLogMapper = SessionUtil.getSession().getMapper(JobAccountLogMapper.class);
            int pageSize = totalPage % shardingContext.getShardingTotalCount() == 0 ? totalPage / shardingContext.getShardingTotalCount() : totalPage / shardingContext.getShardingTotalCount() + 1;
            List<JobAccountLog> listByPage = jobAccountLogMapper.getListByPage(AccountPlatformType.Wish.code(),pageSize * shardingContext.getShardingItem(), pageSize);
            if(listByPage != null && listByPage.size() > 0) {
                for (JobAccountLog jobAccountLog : listByPage) {
                    LocalDateTime localDateTime = jobAccountLog.getStartTime();
                    do{
                        if (jobAccountLog.getId() == null) {
                            BeanUtils.copyProperties(jobAccountLog, jobPointLog);
                            jobAccountLog.setId(null);
                        }
                        handleCampaign(jobAccountLog);
                        localDateTime = localDateTime.plusDays(1L);
                    }while (!localDateTime.isAfter(jobAccountLog.getEndTime()));
                    jobAccountLog.setStartTime(jobAccountLog.getEndTime());
                    jobAccountLog.setEndTime(jobAccountLog.getStartTime().plusDays(jobAccountLog.getIntervalTime()).isAfter(LocalDateTime.now()) ? LocalDateTime.now() : jobAccountLog.getEndTime().plusDays(jobAccountLog.getIntervalTime()));
                    jobAccountLogMapper = SessionUtil.getSession().getMapper(JobAccountLogMapper.class);
                    if (jobAccountLog.getId() == null) {
                        jobAccountLogMapper.insertSelective(jobAccountLog);
                    } else {
                        jobAccountLog.setBjModified(LocalDateTime.now());
                        jobAccountLogMapper.updateByExampleSelective(jobAccountLog, JobAccountLogExample.newAndCreateCriteria().andAccountIdEqualTo(jobAccountLog.getAccountId()).andJobNameEqualTo(jobAccountLog.getJobName()).example());
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            log.warn("Wish获取广告费接口错误", e);
        }
    }

    public void handleCampaign(JobAccountLog jobAccountLog) {
        LinkedHashMap<String, String> map = new LinkedHashMap<>(3);
        DcBaseCompanyAccount dcBaseCompanyAccount = getToken(jobAccountLog);
        new FBWFeeSyncJob().handleFBWFee(jobAccountLog, dcBaseCompanyAccount);
        new InfractionFeeSyncJob().handleInfractionFee(jobAccountLog,dcBaseCompanyAccount);
        WishAuth wishAuth = JSON.parseObject(dcBaseCompanyAccount.getAuthJson(), WishAuth.class);
        // map.put("start_time", DateTimeFormatter.ofPattern(CommonConstant.DATE_FORMAT).format(jobAccountLog.getStartTime()));
        map.put("access_token", wishAuth.getAccessToken());
        map.put("limit", String.valueOf(jobAccountLog.getPageSize()));
        String urlPath = OkHttpUtil.attachHttpGetParams(propertiesUtil.getPropertyAsString("MULTI_CAMPAIGN_GET_URL"), map);
        updateWishInfo(jobAccountLog, urlPath);
    }

    private int getCount()  {
        int i = 0;
        try {
            DcBaseCompanyAccountMapper accountMapper = SessionUtil.getSession().getMapper(DcBaseCompanyAccountMapper.class);
            i = (int)accountMapper.countByExample(DcBaseCompanyAccountExample.newAndCreateCriteria().andPlatformIdEqualTo(AccountPlatformType.Wish.code()).example());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            SessionUtil.closeSession();
        }
        return i;
    }

    private void updateWishInfo(JobAccountLog jobAccountLog, String urlPath) {
        Response response = null;
        String palResultStr = null;
        try {
            Request request = new Request.Builder()
                    .get()
                    .url(urlPath)
                    .addHeader("Content-Type", "application/json")
                    .build();
            response = okHttpClient.newCall(request).execute();
            palResultStr = response.body().string();
        } catch (IOException e) {
            throw new RuntimeException(urlPath + "请求wish接口失败" + response, e);
        } finally {
            if (response != null) {
                response.close();
            }
        }
        if(StringUtils.isNotBlank(palResultStr)) {
            WishExceptionInfo wishExceptionInfo = JSON.parseObject(palResultStr, WishExceptionInfo.class);
            if(wishExceptionInfo.getCode() == 0) {
                WishInfo wishAuthInfo = JSON.parseObject(palResultStr, WishInfo.class);
                List<Map<String, DcBaseFinanceWish>> mapList = wishAuthInfo.getData();
                for(Map<String, DcBaseFinanceWish> maps : mapList) {
                    DcBaseFinanceWish dcBaseFinanceWish = null;
                    boolean updateInsert = true;
                    try {
                        dcBaseFinanceWish = maps.get("Campaign");
                        BigDecimal exchangeRate = CallBailunSystem.getExchangeRate(CurrencyType.USD.value(), CurrencyType.CNY.value(), dcBaseFinanceWish.getStartTime());
                        dcBaseFinanceWish.setOtherToCnyExchangeRate(exchangeRate);
                        dcBaseFinanceWish.setAccountId(jobAccountLog.getAccountId());
                        dcBaseFinanceWish.setCompanyId(jobAccountLog.getCompanyId());
                        dcBaseFinanceWish.setRecordTime(jobAccountLog.getStartTime().toLocalDate());
                        DcBaseFinanceWishMapper mapper = SessionUtil.getSession().getMapper(DcBaseFinanceWishMapper.class);
                        int updateInt = mapper.updateDayByExampleSelective(dcBaseFinanceWish, DcBaseFinanceWishExample.newAndCreateCriteria().andCampaignIdEqualTo(dcBaseFinanceWish.getCampaignId()).andRecordTimeEqualTo(dcBaseFinanceWish.getRecordTime()).example());
                        if(updateInt == 0) {
                            DcBaseFinanceWishMapper mapper1 = SessionUtil.getSession().getMapper(DcBaseFinanceWishMapper.class);
                            DcBaseFinanceWish dcBaseFinanceWish1 = mapper1.selectOneByExample(DcBaseFinanceWishExample.newAndCreateCriteria().andCampaignIdEqualTo(dcBaseFinanceWish.getCampaignId()).andRecordTimeEqualTo(jobAccountLog.getStartTime().minusDays(1L).toLocalDate()).example());
                            if(dcBaseFinanceWish1 != null) {
                                mapper1.insertDaySelective(dcBaseFinanceWish);
                            }else{
                                mapper1.insertDaySelective0(dcBaseFinanceWish);
                            }
                            updateInsert = false;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        throw new RuntimeException("Mybatis操作DB插入任务记录失败", e);
                    } finally {
                        SessionUtil.closeSession();
                    }
                    try {
                        List<Map<String, DcBaseFinanceWishProduct>> listWishProduct = maps.get("Campaign").getListWishProduct();
                        if(updateInsert) {
                            DcBaseFinanceWishProductMapper dcBaseFinanceWishProductMapper = SessionUtil.getSession().getMapper(DcBaseFinanceWishProductMapper.class);
                            dcBaseFinanceWishProductMapper.deleteByExample(DcBaseFinanceWishProductExample.newAndCreateCriteria().andCampaignIdEqualTo(dcBaseFinanceWish.getCampaignId()).andRecordTimeEqualTo(dcBaseFinanceWish.getRecordTime()).example());
                        }
                        if(listWishProduct != null) {
                            for(Map<String, DcBaseFinanceWishProduct> dcBaseFinanceWishProductMap : listWishProduct) {
                                DcBaseFinanceWishProduct dcBaseFinanceWishProduct = dcBaseFinanceWishProductMap.get("Product");
                                dcBaseFinanceWishProduct.setCampaignId(dcBaseFinanceWish.getCampaignId());
                                dcBaseFinanceWishProduct.setRecordTime(dcBaseFinanceWish.getRecordTime());
                                DcBaseFinanceWishProductMapper dcBaseFinanceWishProductMapper = SessionUtil.getSession().getMapper(DcBaseFinanceWishProductMapper.class);
                                dcBaseFinanceWishProductMapper.insertSelective(dcBaseFinanceWishProduct);
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        throw new RuntimeException("Mybatis操作DB插入任务记录失败", e);
                    } finally {
                        SessionUtil.closeSession();
                    }

                    try {
                        if(updateInsert) {
                            DcBaseFinanceWishImpressionFeeMapper dcBaseFinanceWishImpressionFeeMapper = SessionUtil.getSession().getMapper(DcBaseFinanceWishImpressionFeeMapper.class);
                            dcBaseFinanceWishImpressionFeeMapper.deleteByExample(DcBaseFinanceWishImpressionFeeExample.newAndCreateCriteria().andCampaignIdEqualTo(dcBaseFinanceWish.getCampaignId()).example());
                        }
                        List<Map<String, DcBaseFinanceWishImpressionFee>> listWishImpressionFee = maps.get("Campaign").getListWishImpressionFee();
                        if(listWishImpressionFee != null) {
                            for(Map<String, DcBaseFinanceWishImpressionFee> dcBaseFinanceWishImpressionFeeMap : listWishImpressionFee) {
                                DcBaseFinanceWishImpressionFee dcBaseFinanceWishImpressionFee = dcBaseFinanceWishImpressionFeeMap.get("ImpressionFee");
                                dcBaseFinanceWishImpressionFee.setCampaignId(dcBaseFinanceWish.getCampaignId());
                                dcBaseFinanceWishImpressionFee.setRecordTime(dcBaseFinanceWish.getRecordTime());
                                DcBaseFinanceWishImpressionFeeMapper dcBaseFinanceWishImpressionFeeMapper = SessionUtil.getSession().getMapper(DcBaseFinanceWishImpressionFeeMapper.class);
                                dcBaseFinanceWishImpressionFeeMapper.insertSelective(dcBaseFinanceWishImpressionFee);
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        throw new RuntimeException("Mybatis操作DB插入任务记录失败", e);
                    } finally {
                        SessionUtil.closeSession();
                    }

                }
                if(wishAuthInfo.getPaging() != null) {
                    for(Map<String, String> stringMap : wishAuthInfo.getPaging()) {
                        if(stringMap.get("next") != null) {
                            updateWishInfo(jobAccountLog, stringMap.get("next"));
                        }
                    }
                }
                jobAccountLog.setMessage("执行成功");
            }else {
                jobAccountLog.setMessage(palResultStr);
            }
        }
    }

    private DcBaseCompanyAccount getToken(JobAccountLog jobAccountLog) {
        DcBaseCompanyAccountMapper mapper = SessionUtil.getSession().getMapper(DcBaseCompanyAccountMapper.class);
        return  mapper.selectOneByExample(DcBaseCompanyAccountExample.newAndCreateCriteria().andCompanyIdEqualTo(jobAccountLog.getCompanyId()).andAccountIdEqualTo(jobAccountLog.getAccountId()).example());
    }
}
