package com.ytpm.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.ytpm.advertise.enums.AdPlatformTypeEnum;
import com.ytpm.advertise.param.AddPlacementParam;
import com.ytpm.advertise.param.AppAuthContent;
import com.ytpm.advertise.param.AuthContent;
import com.ytpm.advertise.param.ComprehensiveReportParam;
import com.ytpm.advertise.param.HourReportParam;
import com.ytpm.advertise.param.Network;
import com.ytpm.advertise.param.NetworkAppInfo;
import com.ytpm.advertise.param.RelativeChannelParam;
import com.ytpm.advertise.param.RoiReportParam;
import com.ytpm.advertise.param.UnitsListParam;
import com.ytpm.advertise.param.UnitsParam;
import com.ytpm.advertise.view.*;
import com.ytpm.agent.param.ChannelParam;
import com.ytpm.advertise.enums.OpenReportEnum;
import com.ytpm.general.RepMessage;
import com.ytpm.general.Result;
import com.ytpm.general.ResultTable;
import com.ytpm.advertise.param.AddAppParam;
import com.ytpm.service.TakuApiService;
import com.ytpm.util.TakuRequestUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j(topic = "Taku API 服务")
@Service
public class TakuApiServiceImpl implements TakuApiService {

    private final static String API_VERSION_V1 = "/v1";
    private final static String API_VERSION_V2 = "/v2";
    private final static String API_VERSION_V3 = "/v3";

    // 创建固定大小的线程池（10个线程）
    private static final ExecutorService executor = Executors.newFixedThreadPool(10);
    /**
     * 新增或修改应用
     */
    @Override
    public Result<AddAppResponse> saveApp(AddAppParam param) {
        //API支持多个添加，我们这里只添加一个
        JSONObject object = new JSONObject();
        object.put("items", Collections.singletonList(param));
        //若添加成功，API返回应用uuid和 app_key
        //修改时应该使用put 新增使用post
        String res=TakuRequestUtil.doRequest(StringUtils.isNotBlank(param.getUuid())? HttpPut.METHOD_NAME:HttpPost.METHOD_NAME, API_VERSION_V3 + "/apps", object.toJSONString(),param.getTakuPublicKey());
        JSONObject jsonObject = JSON.parseObject(res);
        // 1. 优先检查错误列表 (errs)
        if (jsonObject.containsKey("errs")) {
            JSONArray errsArray = jsonObject.getJSONArray("errs");
            if (errsArray != null && !errsArray.isEmpty()) {
                // 处理错误情况 - 提取第一个错误信息
                JSONObject firstError = errsArray.getJSONObject(0);
                Integer errorCode = firstError.getInteger("code");
                String errorMsg = firstError.getString("msg");
                throw new RuntimeException("错误码：" + errorCode + "\n message：" + errorMsg);
            }
        }
        // 2. 检查成功返回的项目 (items)
        if (jsonObject.containsKey("items")) {
            JSONArray itemsArray = jsonObject.getJSONArray("items");
            if (itemsArray != null && !itemsArray.isEmpty()) {
                JSONObject successItem = itemsArray.getJSONObject(0);
                String uuid = successItem.getString("uuid");
                String appKey = successItem.getString("app_key");
                AddAppResponse response = new AddAppResponse();
                response.setApp_key(appKey);
                response.setUuid(uuid);
                return Result.resultOk(RepMessage.SAVE_SUCCESS, response);
            }
        }
        return Result.resultErr("未知错误");
    }

    /**
     * 查询应用列表
     */
    @Override
    public ResultTable<AppV1View> getAppList(String takuPublicKey) {
        String res = TakuRequestUtil.doRequest(HttpGet.METHOD_NAME, API_VERSION_V1 + "/apps", null,takuPublicKey);
        List<AppV1View> v1View = JSONArray.parseArray(res, AppV1View.class);
        return ResultTable.resultTableOk(new PageInfo<>(v1View));
    }

    /**
     * 删除应用
     */
    @Override
    public Result<AddAppResponse> delApp(String appId,String takuPublicKey) {
        JSONObject object = new JSONObject();
        object.put("app_ids", Collections.singletonList(appId));
        TakuRequestUtil.doRequest(HttpPost.METHOD_NAME, API_VERSION_V1 + "/del_apps", object.toJSONString(),takuPublicKey);
        return Result.resultOk(RepMessage.DELETE_SUCCESS);
    }

    /**
     * Taku应用关联广告平台
     */
    @Override
    public Result<?> relativePlatform(RelativeChannelParam channelParam) {
        Network network = new Network();
        network.setNw_firm_id(channelParam.getAdPlatformType());
        network.setIs_open_report(OpenReportEnum.TRUE.getCode());
        //设置广告平台API认证信息  目前只有优量汇
        AuthContent authContent = new AuthContent();
        authContent.setAccount_id(channelParam.getChannelAccount());
        authContent.setSecret_key(channelParam.getApiSecret());
        if (channelParam.getAdPlatformType().equals(AdPlatformTypeEnum.KUAI_SHOU.getCode())) {
            authContent.setAccess_key(channelParam.getApiKey());
        }
        network.setAuth_content(authContent);
        //设置Taku应用ID
        NetworkAppInfo networkAppInfo = new NetworkAppInfo();
        networkAppInfo.setApp_id(channelParam.getAppId());
        //设置广告平台应用信息
        AppAuthContent appAuthContent = new AppAuthContent();
        appAuthContent.setApp_id(channelParam.getNetworkAppId());
        networkAppInfo.setApp_auth_content(appAuthContent);
        network.setNetwork_app_info(Collections.singletonList(networkAppInfo));
        String res = TakuRequestUtil.doRequest(HttpPost.METHOD_NAME, API_VERSION_V1 + "/set_networks", JSONObject.toJSONString(network),channelParam.getTakuPublicKey());
        Network result = JSONObject.parseObject(res, Network.class);
        return Result.resultOk(RepMessage.RELATIVE_SUCCESS, result);
    }

    /**
     * 获取广告平台维度信息
     */
    @Override
    public ResultTable<Network> getNetworks(String takuPublicKey) {
        // 这个接口虽然没有参数但是要设置为 " ", 如果reqBody设置为NULL会报601
        String res = TakuRequestUtil.doRequest(HttpGet.METHOD_NAME, API_VERSION_V1 + "/networks", "",takuPublicKey);
        return ResultTable.resultTableOk(new PageInfo<>(JSON.parseArray(res, Network.class)));
    }

    /**
     * 新增或修改广告位
     */
    @Override
    public ResultTable<AddPlacementResponse> addPlacements(AddPlacementParam param) {
        String res = TakuRequestUtil.doRequest(HttpPost.METHOD_NAME, API_VERSION_V1 + "/deal_placement", JSON.toJSONString(param),param.getTakuPublicKey());
        List<AddPlacementResponse> placements = JSONArray.parseArray(res, AddPlacementResponse.class);
        return ResultTable.resultTableOk(new PageInfo<>(placements));
    }

    /**
     * 获取广告位列表
     */
    @Override
    public ResultTable<?> getPlacementList(AddPlacementParam param) {
        String res = TakuRequestUtil.doRequest(HttpGet.METHOD_NAME, API_VERSION_V1 + "/placements", JSON.toJSONString(param),param.getTakuPublicKey());
        List<AddPlacementResponse> placements = JSONArray.parseArray(res, AddPlacementResponse.class);
        return ResultTable.resultTableOk(new PageInfo<>(placements));
    }

    /**
     * 删除广告位
     */
    @Override
    public Result<?> delPlacement(List<String> placementIds,String takuPublicKey) {
        JSONObject object = new JSONObject();
        object.put("placement_ids", placementIds);
        TakuRequestUtil.doRequest(HttpPost.METHOD_NAME, API_VERSION_V1 + "/del_placements", object.toJSONString(),takuPublicKey);
        return Result.resultOk(RepMessage.DELETE_SUCCESS);
    }

    /**
     * 获取广告源列表
     */
    @Override
    public ResultTable<UnitsListView> getUnitsList(UnitsListParam unitsListParam) {
        String result = TakuRequestUtil.doRequest(HttpGet.METHOD_NAME, API_VERSION_V3 + "/units/list", JSON.toJSONString(unitsListParam),unitsListParam.getTakuPublicKey());
        return ResultTable.resultTableOk(new PageInfo<>(JSON.parseArray(result, UnitsListView.class)));
    }

    /**
     * 查询广告源详情
     */
    @Override
    public ResultTable<UnitsView> getUnitsView(List<Integer> ids,String takuPublicKey) {
        JSONObject object = new JSONObject();
        object.put("ids", ids);
        String result = TakuRequestUtil.doRequest(HttpGet.METHOD_NAME, API_VERSION_V3 + "/units", JSON.toJSONString(object),takuPublicKey);
        return ResultTable.resultTableOk(new PageInfo<>(JSON.parseArray(result, UnitsView.class)));
    }

    /**
     * 保存广告源信息
     */
    @Override
    public Result<?> saveUnits(UnitsParam param) {
        String result = TakuRequestUtil.doRequest(HttpPost.METHOD_NAME, API_VERSION_V3 + "/units", JSON.toJSONString(param),param.getTakuPublicKey());
        return Result.resultObjOk(JSONObject.parseObject(result, UnitsAddResponse.class));
    }

    /**
     * 修改广告源信息
     */
    @Override
    public Result<?> updateUnits(UnitsParam param) {
        String result = TakuRequestUtil.doRequest(HttpPost.METHOD_NAME, API_VERSION_V3 + "/units", JSON.toJSONString(param),param.getTakuPublicKey());
        return Result.resultObjOk(JSONObject.parseObject(result, UnitsUpdateResponse.class));
    }

    /**
     * 删除广告源
     */
    @Override
    public Result<?> delUnits(List<Integer> adsource_ids,String takuPublicKey) {
        JSONObject object = new JSONObject();
        object.put("adsource_ids", adsource_ids);
        TakuRequestUtil.doRequest(HttpPost.METHOD_NAME, API_VERSION_V1 + "/del_units", JSON.toJSONString(object),takuPublicKey);
        return Result.resultOk(RepMessage.DELETE_SUCCESS);
    }

    /**
     * 查询综合报表
     */
    @Override
    public Result<ComprehensiveReportView> comprehensiveReport(ComprehensiveReportParam param) {
        String result = TakuRequestUtil.doRequest(HttpPost.METHOD_NAME, API_VERSION_V2+"/fullreport", JSON.toJSONString(param),param.getTakuPublicKey());
        return Result.resultObjOk(JSONObject.parseObject(result, ComprehensiveReportView.class));
    }

    /**
     * 查询APP综合报表
     */
    @Override
    public List<ComprehensiveAppReport> getAppReport(ComprehensiveReportParam param) {
        String result = TakuRequestUtil.doRequest(HttpPost.METHOD_NAME, "/v2/fullreport", JSON.toJSONString(param),param.getTakuPublicKey());
        JSONObject object = JSONObject.parseObject(result);
        String records = object.getString("records");
        List<ComprehensiveAppReport> appReports = JSONArray.parseArray(records, ComprehensiveAppReport.class);
        return appReports;
    }

    /**
     * 查询Roi报表
     */
    @Override
    public ResultTable<ReportRoiView> getReportRoi(RoiReportParam param) {
        String result = TakuRequestUtil.doRequest(HttpPost.METHOD_NAME, API_VERSION_V3+"/report/roi", JSON.toJSONString(param),param.getTakuPublicKey());
        JSONObject object = JSONObject.parseObject(result);
        Integer count = object.getInteger("count");
        if(Objects.nonNull(count)){
            String records = object.getString("records");
            List<ReportRoiView> roiViewList = JSONArray.parseArray(records, ReportRoiView.class);
            return ResultTable.resultTableOk(new PageInfo<ReportRoiView>(roiViewList));
        }
        return ResultTable.resultTableOk(new PageInfo<ReportRoiView>(new ArrayList<>()));
    }

    /**
     * 查询Roi报表
     */
    @Override
    public ResultTable<ReportRoiView> getReportRoiLtv(RoiReportParam param) {
        String result = TakuRequestUtil.doRequest(HttpPost.METHOD_NAME, API_VERSION_V3+"/report/roi_ltv", JSON.toJSONString(param),param.getTakuPublicKey());
        JSONObject object = JSONObject.parseObject(result);
        Integer count = object.getInteger("count");
        if(Objects.nonNull(count)){
            String records = object.getString("records");
            List<ReportRoiView> roiViewList = JSONArray.parseArray(records, ReportRoiView.class);
            return ResultTable.resultTableOk(new PageInfo<ReportRoiView>(roiViewList));
        }
        return ResultTable.resultTableOk(new PageInfo<ReportRoiView>(new ArrayList<>()));
    }

    /**
     * 查询分小时报表
     */
    @Override
    public ResultTable<HourReportView> hourReport(HourReportParam param) {
        String result = TakuRequestUtil.doRequest(HttpPost.METHOD_NAME, API_VERSION_V3+"/report/tk_hour", JSON.toJSONString(param),param.getTakuPublicKey());
        JSONObject object = JSONObject.parseObject(result);
        Integer count = object.getInteger("count");
        if(Objects.nonNull(count)){
            String records = object.getString("data");
            List<HourReportView> hourReportViews = JSONArray.parseArray(records, HourReportView.class);
            return ResultTable.resultTableOk(new PageInfo<>(hourReportViews));
        }
        return ResultTable.resultTableOk(new PageInfo<>(new ArrayList<>()));
    }

    public Result<List<HourReportRes>> concurrentHourReports(List<HourReportParam> paramList) {
        ExecutorService executor = Executors.newCachedThreadPool();
        List<CompletableFuture<HourReportRes>> futures = new ArrayList<>();

        for (HourReportParam param : paramList) {
            CompletableFuture<HourReportRes> future = CompletableFuture.supplyAsync(() -> {
                try {
                    ResultTable<HourReportView> resultTable = hourReport(param);
                    List<HourReportView> data = resultTable.getData();
                    HourReportRes hourReportRes = new HourReportRes();
                    hourReportRes.setNetworkId(param.getNetwork_id_list().get(0)); // 确保 list 非空
                    hourReportRes.setList(data);
                    hourReportRes.setChannelName(param.getChannelName());
                    return hourReportRes;
                } catch (Exception e) {
                    log.error("Error during hourReport call with param: {}", JSON.toJSONString(param), e);

                    HourReportRes emptyRes = new HourReportRes();
                    emptyRes.setNetworkId(param.getNetwork_id_list().get(0));
                    emptyRes.setList(Collections.emptyList());
                    return emptyRes;
                }
            }, executor);

            futures.add(future);
        }

        // 收集所有 HourReportRes 对象
        List<HourReportRes> resultList = futures.stream()
                .map(CompletableFuture::join)
                .collect(Collectors.toList());

        executor.shutdown();
        try {
            if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
                executor.shutdownNow();
            }
        } catch (InterruptedException e) {
            executor.shutdownNow();
            Thread.currentThread().interrupt();
        }
        return Result.resultObjOk(resultList);
    }


}
