package com.fs.baidu.api;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fs.ad.domain.AdHtmlClickLog;
import com.fs.ad.domain.BdCreativeStatistics;
import com.fs.ad.domain.BdReportData;
import com.fs.ad.mapper.AdHtmlClickLogMapper;
import com.fs.ad.mapper.BdReportDataMapper;
import com.fs.ad.service.IBdCreativeStatisticsService;
import com.fs.ad.service.IBdReportDataService;
import com.fs.baidu.domain.*;
import com.fs.baidu.param.*;
import com.fs.baidu.service.*;
import com.fs.baidu.utils.BdApiRequest;
import com.fs.baidu.vo.*;
import com.fs.common.core.domain.R;
import com.fs.common.utils.PubFun;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

@Slf4j
@Service
@AllArgsConstructor
public class BaiduApis {

    private final BdApiRequest request;
    private final IBdAccountService accountService;
    private final IBdPlanService planService;
    private final IBdCreativeService creativeService;
    private final IBdUnitService unitService;
    public final IBdApiService apiService;
    private final AdHtmlClickLogMapper adHtmlClickLogMapper;
    private final BdReportDataMapper bdReportDataMapper;
    private final IBdCreativeStatisticsService bdCreativeStatisticsService;

    /**
     * 查询账户列表
     * @param apiId    apiId
     */
    public void listAccount(Long apiId, Long accountId){
        String url = "https://api.baidu.com/json/feed/v1/AccountFeedService/getAccountFeed";
        List<BdAccount> accountList;
        if (accountId == null) {
            accountList = accountService.listByApiId(apiId);
        }else{
            BdAccount account = accountService.getById(accountId);
            if(account == null) return;
            accountList = Collections.singletonList(account);
        }
        if(accountList.isEmpty()){
            return;
        }
        accountList = accountList.stream().filter(e -> e.getLoading() == 0).collect(Collectors.toList());
        if(accountList.isEmpty()){
            return;
        }
        accountList.forEach(account -> {
            try {
                String resultStr = request.request(url, apiId, account.getAccountName(), new QueryAccountParam());
                AccountResultVo accountResultVo = JSON.parseObject(resultStr).getJSONArray("data").toJavaList(AccountResultVo.class).get(0);
                account.setLoading(1);
                account.setAccountId(accountResultVo.getUserId());
                account.setSync(true);
            }catch (Exception ex){
                log.error("同步失败", ex);
            }
        });
        accountService.updateBatchById(accountList);
        List<BdAccount> list = accountList.stream().filter(BdAccount::isSync).collect(Collectors.toList());
        list.parallelStream().forEach(e -> {
            try {
                new Thread(() -> {
                    listPlan(e);
                    e.setLoading(0);
                    accountService.updateById(e);
                }).start();
            }catch (Exception ex){
                log.error("同步失败", ex);
            }
        });
    }
    /**
     * 查询计划列表
     * @param account 查询账户
     */
    public void listPlan(BdAccount account){
        String url = "https://api.baidu.com/json/feed/v1/CampaignFeedService/getCampaignFeed";
        String resultStr = request.request(url, account.getApiId(), account.getAccountName(), new QueryPlanParam());
        List<CampaignFeedVo> list = JSON.parseObject(resultStr).getJSONArray("data").toJavaList(CampaignFeedVo.class);
        if(list.isEmpty()){
            return;
        }
        List<BdPlan> saveOrUpdate = list.stream().map(e -> {
            BdPlan bdPlan = new BdPlan();
            bdPlan.setCampaignFeedId(e.getCampaignFeedId());
            bdPlan.setCampaignFeedName(e.getCampaignFeedName());
            bdPlan.setSubject(e.getSubject());
            bdPlan.setAppinfo(JSON.toJSONString(e.getAppinfo()));
            bdPlan.setSchedule(JSON.toJSONString(e.getSchedule()));
            bdPlan.setEshopType(e.getEshopType());
            bdPlan.setCampaignOcpxStatus(e.getCampaignOcpxStatus());
            bdPlan.setUseLiftBudget(e.getUseLiftBudget());
            bdPlan.setLiftBudget(e.getLiftBudget());
            bdPlan.setLiftStatus(e.getLiftStatus());
            bdPlan.setDeliveryType(e.getEshopType());
            bdPlan.setAppSubType(e.getAppSubType());
            bdPlan.setMiniProgramType(e.getMiniProgramType());
            bdPlan.setBidMode(e.getBidMode());
            bdPlan.setProductIds(e.getProductIds());
            bdPlan.setSaleType(e.getSaleType());
            bdPlan.setAccountId(account.getAccountId());
            bdPlan.setAccountName(account.getAccountName());
            bdPlan.setJson(JSON.toJSONString(e));
            return bdPlan;
        }).collect(Collectors.toList());
        if(!saveOrUpdate.isEmpty()){
            planService.saveOrUpdateBatch(saveOrUpdate);
        }

        PubFun.batchProcessing(50, list, batch -> {
            try {
                listUnit(PubFun.listToNewList(batch, CampaignFeedVo::getCampaignFeedId), 1, account);
            }catch (Exception ex){
                log.error("同步失败", ex);
            }
        });
    }

    /**
     * 查询单元列表
     * @param ids      查询ID集合
     * @param idType   ID类型1计划2单元
     * @param account 查询账户
     */
    public void listUnit(List<Long> ids, Integer idType, BdAccount account){
        String url = "https://api.baidu.com/json/feed/v1/AdgroupFeedService/getAdgroupFeed";
        QueryUnitParam param = new QueryUnitParam();
        param.setIdType(idType);
        param.setIds(ids);
        String resultStr = request.request(url, account.getApiId(), account.getAccountName(), param);
        List<UnitResultVo> list = JSON.parseObject(resultStr).getJSONArray("data").toJavaList(UnitResultVo.class);
        if(list.isEmpty()){
            return;
        }
        List<BdUnit> saveOrUpdate = list.stream().map(e -> {
            BdUnit unit = new BdUnit();
            unit.setAdgroupFeedId(e.getAdgroupFeedId());
            unit.setAccountId(account.getAccountId());
            unit.setAccountName(account.getAccountName());
            unit.setCampaignFeedId(e.getCampaignFeedId());
            unit.setAdgroupFeedName(e.getAdgroupFeedName());
            unit.setPause(e.getPause());
            unit.setStatus(e.getStatus());
            unit.setBid(e.getBid());
            unit.setBidtype(e.getBidtype());
            unit.setJson(JSON.toJSONString(e));
            return unit;
        }).collect(Collectors.toList());
        if(!saveOrUpdate.isEmpty()){
            unitService.saveOrUpdateBatch(saveOrUpdate);
        }


        PubFun.batchProcessing(50, list, batch -> {
            try {
                listCreative(PubFun.listToNewList(batch, UnitResultVo::getAdgroupFeedId), 2, account);
            }catch (Exception ex){
                log.error("同步失败", ex);
            }
        });
    }

    /**
     * 查询创意
     * @param ids      ID集合
     * @param idType   ID类型1计划ID，2单元ID，3创意ID
     * @param account  查询账户
     */
    public void listCreative(List<Long> ids, Integer idType, BdAccount account){
        String url = "https://api.baidu.com/json/feed/v1/CreativeFeedService/getCreativeFeed";
        QueryCreativeParam param = new QueryCreativeParam();
        param.setIdType(idType);
        param.setIds(ids);
        String resultStr = request.request(url, account.getApiId(), account.getAccountName(), param);
        List<CreativeResultVo> list = JSON.parseObject(resultStr).getJSONArray("data").toJavaList(CreativeResultVo.class);
        if(list.isEmpty()){
            return;
        }
        List<BdCreative> saveOrUpdate = list.stream().map(e -> {
            BdCreative creative = new BdCreative();
            creative.setCreativeFeedId(e.getCreativeFeedId());
            creative.setAccountId(account.getAccountId());
            creative.setAccountName(account.getAccountName());
            creative.setAdgroupFeedId(e.getAdgroupFeedId());
            creative.setMaterialstyle(e.getCreativeFeedId());
            creative.setCreativeFeedName(e.getCreativeFeedName());
            creative.setPause(e.getPause());
            creative.setStatus(e.getStatus());
            creative.setMaterial(e.getMaterial());
            creative.setRefusereason(e.getRefusereason());
            creative.setCommentnum(e.getCommentnum());
            creative.setReadnum(e.getReadnum());
            creative.setPlaynum(e.getPlaynum());
            creative.setIdeaType(e.getIdeaType());
            creative.setShowMt(e.getShowMt());
            creative.setAddtime(e.getAddtime());
            creative.setProgFlag(JSON.toJSONString(e.getProgFlag()));
            creative.setVideoId(e.getVideoId());
            creative.setVideoUrl(e.getVideoUrl());
            creative.setTemplateJson(JSON.toJSONString(e.getTemplate()));
            creative.setJson(JSON.toJSONString(e));
            return creative;
        }).collect(Collectors.toList());
        if(!saveOrUpdate.isEmpty()){
            creativeService.saveOrUpdateBatch(saveOrUpdate);
        }
    }



    public void getReportDataAll(BdAccount account, QueryReportDataParam paramData){
        Supplier<Integer> getType = () -> {
            if(paramData.getReportType() == 2324048) return 0;
            if(paramData.getReportType() == 2503330) return 1;
            if(paramData.getReportType() == 2510393) return 2;
            if(paramData.getReportType() == 2532512) return 3;
            if(paramData.getReportType() == 2094816) return 4;
            return 99;
        };
        List<ReportDataVo> allData = new ArrayList<>();
        BdApi byId = apiService.getById(account.getApiId());
        boolean data = true;
        String dataJson = JSON.toJSONString(paramData);
        for (int page = 1 ; data ; page++) {
            QueryReportDataParam params = JSON.parseObject(dataJson, QueryReportDataParam.class);
            // 设置分页参数
            params.setPage(page);
            R result = getReportData(byId.getAccessToken(), account.getAccountName(), params);
            // 处理第一次请求时获取总行数
            List<ReportDataVo> list = (List<ReportDataVo>) result.get("data");
            if(!list.isEmpty()){
                list.forEach(e -> e.setType(getType.get()));
                allData.addAll(list);
            }
            data = list.size() == paramData.getRowCount();
        }
        List<BdReportData> collect = allData.stream().map(e -> {
            BdReportData bdReportData = new BdReportData();
            bdReportData.setType(e.getType());
            bdReportData.setDate(LocalDate.now());
            bdReportData.setUserName(e.getUserName());
            bdReportData.setUserId(e.getUserId());
            bdReportData.setCampaignId(e.getCampaignId());
            bdReportData.setCampaignName(e.getCampaignName());
            if(e.getCampaignStatus() != null){
                bdReportData.setCampaignStatus(e.getCampaignStatus().getCode());
                bdReportData.setCampaignNameStatus(e.getCampaignStatus().getCode());
            }
            bdReportData.setAdGroupId(e.getAdGroupId());
            bdReportData.setAdGroupName(e.getAdGroupName());
            if(e.getAdGroupStatus() != null){
                bdReportData.setAdGroupStatus(e.getAdGroupStatus().getCode());
            }
            bdReportData.setAdGroupNameStatus(e.getAdGroupNameStatus());
            if(e.getProv() != null){
                bdReportData.setProvinceId(Long.parseLong(e.getProv().getProvinceId()));
                bdReportData.setProvinceName(e.getProv().getProvinceName());
            }
            bdReportData.setGenderName(e.getGenderName());
            bdReportData.setAge(e.getAgeName());
            bdReportData.setShowWord(e.getShowWord());
            bdReportData.setFeedWord(e.getFeedWord());

            bdReportData.setImpression(e.getImpression());
            bdReportData.setClick(e.getClick());
            bdReportData.setCost(e.getCost());
            bdReportData.setCtr(e.getCtr());
            bdReportData.setCpc(e.getCpc());
            bdReportData.setCpm(e.getCpm());
            return bdReportData;
        }).collect(Collectors.toList());
        collect.parallelStream().forEach(bdReportDataMapper::insert);
    }

    public void getCreativeStatisticsAll(BdAccount account, QueryReportDataParam params){
        params.setColumns(Arrays.asList("date", "userId", "userName", "campaignNameStatus", "adGroupNameStatus", "ideaInfo", "ideaNameStatus", "feedSubjectEnum", "impression", "click", "cost", "ctr", "cpc", "cpm", "iaaCost", "iaaPayRoi", "phoneButtonClicks", "interaction"));
        BdApi byId = apiService.getById(account.getApiId());
        String url = "https://api.baidu.com/json/sms/service/OpenApiReportService/getReportData";
        if(params.getPage() != null && params.getRowCount() != null){
            params.setStartRow(params.getPage() * params.getRowCount());
        }
        String resultStr = request.requestToken(url, byId.getAccessToken(), account.getAccountName(), params);
        JSONObject data = JSON.parseObject(resultStr).getJSONArray("data").getJSONObject(0);
        Integer total = data.getInteger("totalRowCount");
        List<ReportVO> list = data.getJSONArray("rows").toJavaList(ReportVO.class);
        List<BdCreativeStatistics> collect = list.parallelStream().map(e -> {
            BdCreativeStatistics entity = new BdCreativeStatistics();
            entity.setDate(e.getDate());
            entity.setUserId(e.getUserId());
            entity.setUserName(e.getUserName());
            entity.setCampaignNameStatus(e.getCampaignNameStatus());
            entity.setAdGroupNameStatus(e.getAdGroupNameStatus());
            entity.setIdeaInfo(e.getIdeaInfo());
            entity.setIdeaNameStatus(e.getIdeaNameStatus());
            if(e.getFeedSubjectEnum() != null){
                entity.setFeedSubjectEnum(e.getFeedSubjectEnum().getValue());
            }
            entity.setImpression(e.getImpression());
            entity.setClick(e.getClick());
            entity.setCost(e.getCost());
            entity.setCtr(e.getCtr());
            entity.setCpc(e.getCpc());
            entity.setCpm(e.getCpm());
            entity.setIaaCost(e.getIaaCost());
            entity.setIaaPayRoi(e.getIaaPayRoi());
            entity.setPhoneButtonClicks(e.getPhoneButtonClicks());
            entity.setInteraction(e.getInteraction());
            return entity;
        }).collect(Collectors.toList());
        boolean b = bdCreativeStatisticsService.saveBatch(collect);
        log.info("是否添加成功：{}", b);

    }



    public R getReportData(String token, String name, QueryReportDataParam params){
        String url = "https://api.baidu.com/json/sms/service/OpenApiReportService/getReportData";
        if(params.getReportType() == 2324048){
            params.getColumns().add("prov");
//            params.getColumns().add("city");
        }
        if(params.getReportType() == 2503330){
            params.getColumns().add("genderName");
        }
        if(params.getReportType() == 2510393){
            params.getColumns().add("ageName");
        }
        if(params.getReportType() == 2532512){
            params.getColumns().add("showWord");
            params.getColumns().add("feedWord");
        }
        if(params.getReportType() == 114718){
            params.getColumns().add("ideaId");
            params.getColumns().add("videoId");
            params.getColumns().add("videoNameStatus");
            params.getColumns().add("videoInfo");
            params.getColumns().add("ideaNameStatus");
        }
        if(params.getReportType() == 2094817){
            params.getColumns().add("imageUrl");
            params.getColumns().add("imageId");
            params.getColumns().add("ideaNameStatus");
        }
        if(params.getPage() != null && params.getRowCount() != null){
            params.setStartRow((params.getPage() - 1) * params.getRowCount());
        }
        String resultStr = request.requestToken(url, token, name, params);
        JSONObject data = JSON.parseObject(resultStr).getJSONArray("data").getJSONObject(0);
        Integer total = data.getInteger("totalRowCount");
        List<ReportDataVo> list = data.getJSONArray("rows").toJavaList(ReportDataVo.class);
        if(!list.isEmpty()){
            list.forEach(e -> {
                if(e.getCost() != null){
                    e.setCost(e.getCost().setScale(2, RoundingMode.HALF_UP));
                }
                if(e.getCpc() != null){
                    e.setCpc(e.getCpc().setScale(2, RoundingMode.HALF_UP));
                }
                if(e.getCpm() != null){
                    e.setCpm(e.getCpm().setScale(2, RoundingMode.HALF_UP));
                }
                if(e.getCtr() != null){
                    e.setCtr(e.getCtr().setScale(4, RoundingMode.HALF_UP));
                }
                if(e.getWeixinFollowSuccessConversionsCost() != null){
                    e.setWeixinFollowSuccessConversionsCost(e.getWeixinFollowSuccessConversionsCost().setScale(2, RoundingMode.HALF_UP));
                }
                if(e.getFeedOCPCConversionsDetail133Cost() != null){
                    e.setFeedOCPCConversionsDetail133Cost(e.getFeedOCPCConversionsDetail133Cost().setScale(2, RoundingMode.HALF_UP));
                }
            });
            list.stream().filter(e -> e.getCtr().doubleValue() > 0).forEach(e -> {
                e.setCtr(e.getCtr().multiply(BigDecimal.valueOf(100)));
            });
        }
//        if(!list.isEmpty()){
//            List<Long> uidList = PubFun.listToNewList(list, ReportDataVo::getAdGroupId);
//            List<AdHtmlClickLog> logList = adHtmlClickLogMapper.staticData(uidList);
//            if(!logList.isEmpty()){
//
//            }
//        }
        return R.ok().put("data", list).put("total", total);
    }

    public R bdDataStatic() {
        return R.ok();
    }
}
