package com.reptileclient.jlifeapp.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.reptileclient.jlifeapp.constant.DyLifeConstants;
import com.reptileclient.jlifeapp.dao.jz.DyLaikeAccountShopMapInfoMapper;
import com.reptileclient.jlifeapp.dao.jz.DyLaikeShopEvaltionMapper;
import com.reptileclient.jlifeapp.dao.jz.DyLaikeShopThreeRateMapper;
import com.reptileclient.jlifeapp.dao.jz.DyLaikeTokenMapper;
import com.reptileclient.jlifeapp.entity.DyLaikeShopEvaltion;
import com.reptileclient.jlifeapp.entity.jz.DyLaikeAccountShopMapInfo;
import com.reptileclient.jlifeapp.entity.jz.DyLaikeShopThreeRate;
import com.reptileclient.jlifeapp.entity.jz.DyLaikeToken;
import com.reptileclient.jlifeapp.service.DyLaikeService;
import com.reptileclient.jlifeapp.util.OkHttpUtil;
import com.reptileclient.jlifeapp.util.ThreadPoolManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class DyLaikeServiceImpl implements DyLaikeService {


    @Autowired
    private DyLaikeTokenMapper dyLaikeTokenMapper;

    @Autowired
    private DyLaikeAccountShopMapInfoMapper shopMapInfoMapper;

    @Autowired
    private DyLaikeShopEvaltionMapper shopEvaltionMapper;

    @Autowired
    private DyLaikeShopThreeRateMapper shopThreeRateMapper;


    private String token;

    private String accountId = "7161316264890075172";

    private Integer batchId = 0;
    private Integer batchId2 = 0;
    private Integer shopEvaltionCount = 0;

    private final Integer pageSize = 2000;


    @Override
    public void syncShopAndPoi() {
        shopMapInfoMapper.clear();
        DyLaikeToken dyLaikeToken = dyLaikeTokenMapper.selectByPrimaryKey(1);
        token = dyLaikeToken.getToken();
        accountId = dyLaikeToken.getAccountId();
        String requestUrl = DyLifeConstants.shopList.replace("{root_life_account_id}", accountId);
        Map<String, Object> requestMap = new HashMap<>();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("claim_status", 1);
        jsonObject.put("open_status", 1);
        jsonObject.put("req_source", 1);
        jsonObject.put("role_list", "1");
        jsonObject.put("template_type", "open_multi_account");
        JSONObject jsonObject1 = new JSONObject();
        jsonObject1.put("page", 1);
        jsonObject1.put("page_size", 2000);
        jsonObject.put("page", jsonObject1);
        requestMap.put("param", jsonObject);

        String response = OkHttpUtil.post2Dy(requestUrl, requestMap, token);
        JSONObject x = JSONObject.parseObject(response);
        Integer code = x.getInteger("status_code");
        if (code != 0) {
            //休息2秒，准备重试
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            String secondResponse = OkHttpUtil.post2Dy(requestUrl, requestMap, token);
            JSONObject secondJsonObject = JSONObject.parseObject(secondResponse);
            Integer secondCode = secondJsonObject.getInteger("status_code");
            if (secondCode != 0) {
                //休息2秒，准备重试
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                String thirdResponse = OkHttpUtil.post2Dy(requestUrl, requestMap, token);
                JSONObject thirdJsonObject = JSONObject.parseObject(thirdResponse);
                Integer thirdCode = thirdJsonObject.getInteger("status_code");
                if (thirdCode != 0) {
                    System.out.println("三次请求都失败了，不再重试");
                    return;
                } else {
                    System.out.println("第三次请求成功了");
                    realStart(requestUrl, thirdJsonObject);
                }
            } else {
                System.out.println("第二次请求成功了");
                realStart(requestUrl, secondJsonObject);
            }
        }
        realStart(requestUrl, x);
    }

    private void realStart(String requestUrl, JSONObject thirdJsonObject) {
        JSONObject pageInfo = thirdJsonObject.getJSONObject("data").getJSONObject("pagination");
        Integer count = pageInfo.getInteger("total_count");
        //计算需要请求的次数
        int requestTimes = count / pageSize;
        if (requestTimes == 0) {
            //只有一页，直接处理本次返回的数据
            JSONArray jsonArray = thirdJsonObject.getJSONObject("data").getJSONArray("claim_pois");
            String relationUrl = DyLifeConstants.relationList.replace("{root_life_account_id}", accountId);

            String json = "{\"search_params\":{\"parent_life_account_ids\":[\"10000\"],\"relation_types\":[1,6]},\"page_index\":1,\"page_size\":200}";
            String s = OkHttpUtil.post2Dy(relationUrl, json, token);
            JSONObject jsonObject = JSONObject.parseObject(s);
            JSONArray array = jsonObject.getJSONObject("data").getJSONArray("list");


            for (int i = 0; i <= 6; i++) {
                json = "{\"search_params\":{\"parent_life_account_ids\":[\"10000\"],\"relation_types\":[1,6]},\"page_index\":" + (i + 1) + ",\"page_size\":200}";
                String s1 = OkHttpUtil.post2Dy(relationUrl, json, token);
                JSONObject jsonObject1 = JSONObject.parseObject(s1);
                JSONArray array1 = jsonObject1.getJSONObject("data").getJSONArray("list");
                array.addAll(array1);
            }


            for (Object o : jsonArray) {
                JSONObject js = (JSONObject) o;
                DyLaikeAccountShopMapInfo dyLaikeAccountShopMapInfo = new DyLaikeAccountShopMapInfo();
                array.forEach(a -> {
                    JSONObject j = (JSONObject) a;
                    if (j.getString("poi_id").equals(js.getString("poi_id"))) {
                        dyLaikeAccountShopMapInfo.setShopAccountId(j.getString("poi_life_account_id"));
                    }
                });
                dyLaikeAccountShopMapInfo.setDeleted(0);
                dyLaikeAccountShopMapInfo.setShopName(js.getString("poi_name"));
                dyLaikeAccountShopMapInfo.setShopPoiId(js.getString("poi_id"));
                shopMapInfoMapper.insertSelective(dyLaikeAccountShopMapInfo);
            }

            return;
        }
        if (count % pageSize != 0) {
            requestTimes++;
        }
        //开启多个线程一起请求

        JSONArray jsonArray = new JSONArray();
        for (int i = 0; i < requestTimes; i++) {
            int finalI = i;
            ThreadPoolManager.execute(() -> {
                Map<String, Object> requestMap = new HashMap<>();
                requestMap.put("page_size", pageSize);
                requestMap.put("page_index", finalI + 1);
                String response = OkHttpUtil.post2Dy(requestUrl, requestMap, token);
                JSONObject jsonObject = JSONObject.parseObject(response);
                JSONArray array = jsonObject.getJSONObject("data").getJSONArray("list");
                jsonArray.addAll(array);
            });
        }

        //等待所有线程执行完毕
        //最多等待6000
        int waitCount = 0;
        while (waitCount++ < 6000) {
            if (jsonArray.size() == count) {
                break;
            }
        }

        //开始处理数据
        for (Object o : jsonArray) {
            JSONObject js = (JSONObject) o;
            DyLaikeAccountShopMapInfo dyLaikeAccountShopMapInfo = new DyLaikeAccountShopMapInfo();
            dyLaikeAccountShopMapInfo.setShopAccountId(js.getString("poi_life_account_id"));
            dyLaikeAccountShopMapInfo.setDeleted(0);
            dyLaikeAccountShopMapInfo.setShopName(js.getString("poi_name"));
            dyLaikeAccountShopMapInfo.setShopPoiId(js.getString("poi_id"));
            shopMapInfoMapper.insertSelective(dyLaikeAccountShopMapInfo);
        }


    }

    @Override
    public void getReviewData() {
//        syncShopAndPoi();
        DyLaikeToken dyLaikeToken = dyLaikeTokenMapper.selectByPrimaryKey(1);
        token = dyLaikeToken.getToken();
        List<DyLaikeAccountShopMapInfo> shops = shopMapInfoMapper.selectAll();

        batchId = shopEvaltionMapper.getLastBatch();
        List<DyLaikeAccountShopMapInfo> failShopMaps = new ArrayList<>();
        for (DyLaikeAccountShopMapInfo shop : shops) {
            if (shop.getShopAccountId() == null) {
                continue;
            }
            String requestUrl = DyLifeConstants.reviewApi.replace("{shop_account_id}", shop.getShopAccountId())
                    .replace("{poi_id}", shop.getShopPoiId())
                    .replace("{root_life_account_id}", accountId);
            try {
                process(requestUrl, shop.getShopPoiId(), shop.getShopName());
            } catch (Exception e) {
                failShopMaps.add(shop);
            }
        }

        //等待所有线程执行完毕
        while (true) {
            if (shopEvaltionCount == shops.size()) {
                break;
            }
        }
        //对于失败的门店，再次请求

        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            for (DyLaikeAccountShopMapInfo failShopMap : failShopMaps) {
                String requestUrl = DyLifeConstants.reviewApi.replace("{shop_account_id}", failShopMap.getShopAccountId())
                        .replace("{poi_id}", failShopMap.getShopPoiId())
                        .replace("{root_life_account_id}", accountId);
                try {
                    process(requestUrl, failShopMap.getShopPoiId(), failShopMap.getShopName());
                } catch (Exception m) {
                    log.warn("门店评价数据获取失败，门店id为：{}", failShopMap.getShopPoiId());
                }
            }
        }


        //更新对应的fra_id和fra_name
        shopEvaltionMapper.updateLastBatch(batchId);
        shopEvaltionCount = 0;
    }

    @Override
    public void getThreeRate() {
//        syncShopAndPoi();
        DyLaikeToken dyLaikeToken = dyLaikeTokenMapper.selectByPrimaryKey(1);
        token = dyLaikeToken.getToken();
        List<DyLaikeAccountShopMapInfo> shops = shopMapInfoMapper.selectAll();

        batchId2 = shopEvaltionMapper.getLastBatch();
        // 30天
        String start_date = LocalDateTime.now().minusDays(30).withHour(0).withMinute(0).withSecond(0).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String end_date = LocalDateTime.now().minusDays(1).withHour(0).withMinute(0).withSecond(0).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        List<DyLaikeAccountShopMapInfo> failShopMaps = new ArrayList<>();
        for (DyLaikeAccountShopMapInfo shop : shops) {
            if (StringUtils.isEmpty(shop.getShopAccountId())) {
                continue;
            }
            String requestUrl = DyLifeConstants.threeRateApi.replace("{this_shop_id}", shop.getShopAccountId())
                    .replace("{root_life_account_id}", accountId)
                    .replace("{start_date}", start_date)
                    .replace("{end_date}", end_date);
            try {
                processThreeRate(requestUrl, shop.getShopPoiId(), shop.getShopName(), start_date, end_date);
            } catch (Exception e) {
                failShopMaps.add(shop);
            }
        }

        //等待所有线程执行完毕
        while (true) {
            if (shopEvaltionCount == shops.size()) {
                break;
            }
        }
        //对于失败的门店，再次请求

        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            for (DyLaikeAccountShopMapInfo failShopMap : failShopMaps) {
                String requestUrl = DyLifeConstants.threeRateApi.replace("{this_shop_id}", failShopMap.getShopAccountId())
                        .replace("{root_life_account_id}", accountId)
                        .replace("{start_date}", start_date)
                        .replace("{end_date}", end_date);
                try {
                    processThreeRate(requestUrl, failShopMap.getShopPoiId(), failShopMap.getShopName(), start_date, end_date);
                } catch (Exception m) {
                    log.warn("门店违规分数数据获取失败，门店id为：{}", failShopMap.getShopPoiId());
                }
            }
        }


        //更新对应的fra_id和fra_name
        shopThreeRateMapper.updateLastBatch(batchId2);
        shopEvaltionCount = 0;
    }

    private void processThreeRate(String requestUrl, String shopPoiId, String shopName, String start_date, String end_date) {
        ThreadPoolManager.execute(() -> {
            try {
                saveThreeRate(requestUrl, shopPoiId, shopName, start_date, end_date);
            } finally {
                shopEvaltionCount++;
            }
        });
    }

    private void saveThreeRate(String requestUrl, String shopPoiId, String shopName, String start_date, String end_date) {
        String s = OkHttpUtil.get2Dy(requestUrl, token);
        JSONObject jsonObject = JSONObject.parseObject(s);
        JSONObject data = jsonObject.getJSONObject("data");
        JSONObject data1 = data.getJSONObject("Data");
        BigDecimal badRadio = data1.getJSONObject("BadCommentRatio").getBigDecimal("AvgVal");
        BigDecimal complain = data1.getJSONObject("ComplaintRatio").getBigDecimal("AvgVal");
        BigDecimal refund = data1.getJSONObject("RefundRatio").getBigDecimal("AvgVal");
        DyLaikeShopThreeRate dyLaikeShopThreeRate = new DyLaikeShopThreeRate();
        dyLaikeShopThreeRate.setShopPoiId(shopPoiId);
        dyLaikeShopThreeRate.setShopName(shopName);
        dyLaikeShopThreeRate.setBadRate(badRadio);
        dyLaikeShopThreeRate.setComplaintRate(complain);
        dyLaikeShopThreeRate.setRefundRate(refund);
        dyLaikeShopThreeRate.setBatchId(batchId2);
        dyLaikeShopThreeRate.setEvaUpdateTime(LocalDateTime.now().minusDays(1));
        dyLaikeShopThreeRate.setEtlTime(LocalDateTime.now());
        dyLaikeShopThreeRate.setStartDate(start_date);
        dyLaikeShopThreeRate.setEndDate(end_date);
        shopThreeRateMapper.insertSelective(dyLaikeShopThreeRate);
    }


    private void process(String requestUrl, String shopPoiId, String shopName) {
        ThreadPoolManager.execute(() -> {
            try {
                saveData(requestUrl, shopPoiId, shopName);
            } finally {
                shopEvaltionCount++;
            }
        });
    }

    private void saveData(String requestUrl, String shopPoiId, String shopName) {
        String s = OkHttpUtil.get2Dy(requestUrl, token);
        JSONObject jsonObject = JSONObject.parseObject(s);
        JSONObject data = jsonObject.getJSONObject("data");
        DyLaikeShopEvaltion dyLaikeShopEvaltion = new DyLaikeShopEvaltion();
        dyLaikeShopEvaltion.setShopPoiId(shopPoiId);
        dyLaikeShopEvaltion.setShopName(shopName);
        dyLaikeShopEvaltion.setEvaCount(data.getInteger("comment_count"));
        dyLaikeShopEvaltion.setEvaLastMonthCount(data.getInteger("comment_cnt_last_month"));
        dyLaikeShopEvaltion.setEvaLastGoods(data.getInteger("positive_comment_cnt_last_month"));
        dyLaikeShopEvaltion.setEvaLastBad(data.getInteger("other_comment_cnt_last_month"));
        dyLaikeShopEvaltion.setScore(data.getBigDecimal("origin_score_t_1"));
        dyLaikeShopEvaltion.setBatchId(batchId);
        dyLaikeShopEvaltion.setEvaUpdateTime(LocalDateTime.ofEpochSecond(data.getLong("review_updated_time"), 0, ZoneId.systemDefault().getRules().getOffset(LocalDateTime.now())));
        dyLaikeShopEvaltion.setEtlTime(LocalDateTime.now());
        shopEvaltionMapper.insert(dyLaikeShopEvaltion);
    }
}
