package com.dsk.system.dskService;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.dsk.acc.openapi.client.util.CommonUtils;
import com.dsk.common.constant.CacheConstants;
import com.dsk.common.core.domain.R;
import com.dsk.common.core.domain.model.*;
import com.dsk.common.core.page.TableDataInfo;
import com.dsk.common.core.redis.RedisCache;
import com.dsk.common.utils.DskOpenApiUtil;
import com.dsk.common.utils.EncodeIdUtil;
import com.dsk.system.domain.customer.vo.CustomerStatusListVo;
import com.dsk.system.service.ICustomerService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName enterpriseService
 * @Description TODO
 * @Author zhangyi
 * @Date 2023/5/15 12:00
 * @Version 1.0
 */
@Service
public class EnterpriseService {

    private static final Logger log = LoggerFactory.getLogger(EnterpriseService.class);

    @Autowired
    private DskOpenApiUtil dskOpenApiUtil;

    @Autowired
    ICustomerService iCustomerService;

    @Autowired
    private RedisCache redisCache;

    public R infoHeader(EnterpriseInfoHeaderBody body) throws Exception {
        if (body.isVaildCid()) return R.ok();
        Map<String, Object> companyMap = dskOpenApiUtil.requestBody("/api/jsk/enterprise/infoHeader", BeanUtil.beanToMap(body, false, false));
        Integer companyCode = MapUtils.getInteger(companyMap, "code", 300);
        if (200 != companyCode) return R.ok();

        Map companyData = MapUtils.getMap(companyMap, "data", null);
        companyData.put("uipId", null);
        companyData.put("claimStatus", 0);
        companyData.put("bratingSubjectLevel", null);

        Map<String, Object> map = BeanUtil.beanToMap(body, false, false);
        map.put("cid", body.getCompanyId());

        Map<String, Object> uipMap = dskOpenApiUtil.requestBody("/operate/enterprise/financial", map);
        Integer uipCode = MapUtils.getInteger(uipMap, "code", 300);
        if (200 != uipCode) return R.ok(companyData);

        Map uipData = MapUtils.getMap(uipMap, "data", new HashMap<>());
        String uipId = MapUtils.getString(uipData, "uipId", null);
        companyData.put("uipId", uipId);
        if (!ObjectUtil.isEmpty(uipId)) {
            ArrayList<String> uipIds = new ArrayList<>();
            uipIds.add(uipId);
            companyData.put("claimStatus", CollectionUtils.isEmpty(iCustomerService.selectStatusList(uipIds)) ? 0 : 1);
        }

        Map<String, Object> bondCreditRatingMap = dskOpenApiUtil.requestBody("/operate/enterprise/bondCreditRating", map);
        Integer bondCreditRatingCode = MapUtils.getInteger(bondCreditRatingMap, "code", 300);
        if (200 != bondCreditRatingCode) return R.ok(companyData);

        List<Map<String, Object>> bondCreditRatingList = (List<Map<String, Object>>)MapUtils.getObject(bondCreditRatingMap, "data", new ArrayList<>());
        if (CollectionUtils.isEmpty(bondCreditRatingList)) return R.ok(companyData);

        companyData.put("bratingSubjectLevel", MapUtils.getString(bondCreditRatingList.get(0), "bratingSubjectLevel", null));

        return R.ok(companyData);
    }

    public R statistic(EnterpriseStatisticBody body) throws Exception {
        if (body.isVaildCid()) return R.ok();
        Map<String, Object> statisticMap = dskOpenApiUtil.requestBody("/api/jsk/enterprise/statistic", BeanUtil.beanToMap(body, false, false));

        Integer statisticMapCode = MapUtils.getInteger(statisticMap, "code", 300);
        if (200 != statisticMapCode) throw new RuntimeException();

        Map statisticMapData = MapUtils.getMap(statisticMap, "data", null);
        if (MapUtils.isEmpty(statisticMapData)) return R.ok();

        Map performance = MapUtils.getMap(statisticMapData, "performance");
        Map business = MapUtils.getMap(statisticMapData, "business");

        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("cid", body.getCompanyId());
        Map<String, Object> projectStatisticMap = dskOpenApiUtil.requestBody("/operate/enterpriseProject/statistic", paramMap);
        Integer projectStatisticMapCode = MapUtils.getInteger(projectStatisticMap, "code", 300);
        if (200 != projectStatisticMapCode) return R.ok(statisticMapData);

        Map projectStatisticMapData = MapUtils.getMap(projectStatisticMap, "data", null);

        performance.put("specialDebt", MapUtils.getInteger(projectStatisticMapData, "specialDebt", 0));
        performance.put("bidPlan", MapUtils.getInteger(projectStatisticMapData, "bidPlan", 0));
        business.put("historySend", MapUtils.getInteger(projectStatisticMapData, "historySend", 0));

        statisticMapData.put("performance", performance);
        statisticMapData.put("business", business);

        return R.ok(statisticMapData);
    }

    public R bidDataGroup(EnterpriseBidDataGroupBody body) throws Exception {
        if (body.isVaildCid()) return R.ok();
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/enterprise/bidDataGroup", BeanUtil.beanToMap(body, false, false));
        return BeanUtil.toBean(map, R.class);
    }

    public R projectTenderDataGroup(EnterpriseProjectTenderDataGroupBody body) throws Exception {
        if (body.isVaildCid()) return R.ok();
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/enterprise/projectTenderDataGroup", BeanUtil.beanToMap(body, false, false));
        return BeanUtil.toBean(map, R.class);
    }

    //todo 新数据，待入库
    public TableDataInfo partners(EnterprisePartnersBody body) throws Exception {
        if (body.isVaildCid()) return new TableDataInfo(new ArrayList<>(), 0);
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/enterprise/partners", BeanUtil.beanToMap(body, false, false));
        return dskOpenApiUtil.responsePage(map);
    }

    public TableDataInfo investment(EnterpriseInvestmentBody body) throws Exception {
        if (body.isVaildCid()) return new TableDataInfo(new ArrayList<>(), 0);
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/enterprise/investment", BeanUtil.beanToMap(body, false, false));
        return dskOpenApiUtil.responsePage(map);
    }

    public TableDataInfo affiliates(EnterpriseAffiliatesBody body) throws Exception {
        if (body.isVaildCid()) return new TableDataInfo(new ArrayList<>(), 0);
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/enterprise/affiliates", BeanUtil.beanToMap(body, false, false));
        return dskOpenApiUtil.responsePage(map);
    }

    public TableDataInfo dynamicPage(EnterpriseDynamicPageBody body) throws Exception {
        if (body.isVaildCid()) return new TableDataInfo(new ArrayList<>(), 0);
        Map<String, Object> map = dskOpenApiUtil.requestBody("/api/jsk/enterprise/dynamic", BeanUtil.beanToMap(body, false, false));
        //底层接口写死了pageSize为10，这里前端只要5条
//        return dskOpenApiUtil.responsePage(map);

        Integer code = MapUtils.getInteger(map, "code", 300);
        Map data = MapUtils.getMap(map, "data", null);
        if (200 != code) throw new RuntimeException();
        Integer count = MapUtils.getInteger(data, "totalCount", 0);
        List<Object> list = CommonUtils.assertAsArray(MapUtils.getObject(data, "list", ""));

        return new TableDataInfo(body.getPageSize() <= list.size() ? list.subList(0, body.getPageSize()) : list, count);
    }

    public R icInfo(EnterpriseIcInfoBody body) throws Exception {
        if (body.isVaildCid()) return R.ok();
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/enterprise/icInfo", BeanUtil.beanToMap(body, false, false));
        return BeanUtil.toBean(map, R.class);
    }

    public TableDataInfo changeInfo(EnterpriseChangeInfoBody body) throws Exception {
        if (body.isVaildCid()) return new TableDataInfo(new ArrayList<>(), 0);
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/enterprise/changeInfo", BeanUtil.beanToMap(body, false, false));
        return dskOpenApiUtil.responsePage(map);
    }

    public TableDataInfo keymembers(EnterpriseKeymembersBody body) throws Exception {
        if (body.isVaildCid()) return new TableDataInfo(new ArrayList<>(), 0);
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/enterprise/keymembers", BeanUtil.beanToMap(body, false, false));
        return dskOpenApiUtil.responsePage(map);
    }

    public TableDataInfo bestStockPage(EnterpriseBestStockPageBody body) throws Exception {
        if (body.isVaildCid()) return new TableDataInfo(new ArrayList<>(), 0);
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/enterprise/bestStockPage", BeanUtil.beanToMap(body, false, false));
        return dskOpenApiUtil.responsePage(map);
    }

    public R financial(EnterpriseFinancialBody body) throws Exception {
        if (body.isVaildCid()) return R.ok();
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/enterprise/financial", BeanUtil.beanToMap(body, false, false));
        return BeanUtil.toBean(map, R.class);
    }

    public R getUipId(String companyName) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("companyName", companyName);
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/enterprise/getUipId", params);
        return BeanUtil.toBean(map, R.class);
    }

    public TableDataInfo uipSerach(EnterpriseUipSearchBody body) throws Exception {
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/enterprise/uipSerach", BeanUtil.beanToMap(body, false, false));
        Integer code = MapUtils.getInteger(map, "code", 300);
        if (200 != code) throw new RuntimeException();

        Map data = MapUtils.getMap(map, "data", null);
        List<Object> list = CommonUtils.assertAsArray(MapUtils.getObject(data, "list", ""));

        if (CollectionUtils.isEmpty(list)) {
            return new TableDataInfo(list, 0);
        }

        ArrayList<String> uipIds = new ArrayList<>();
        for (Object dataMap : list) {
            uipIds.add(MapUtils.getString(CommonUtils.assertAsMap(dataMap), "uipId"));
        }

        List<CustomerStatusListVo> claimStatusList = iCustomerService.selectStatusList(uipIds);

        //按照城投企业id合并两个list
        for (Object companyObj : list) {
            Map<String, Object> companyMap = CommonUtils.assertAsMap(companyObj);
            String uipId = MapUtils.getString(companyMap, "uipId");
            companyMap.put("claimStatus", 0);
            for (CustomerStatusListVo vo : claimStatusList) {
                if (uipId.equals(vo.getUipId())) {
                    companyMap.put("claimStatus", 1);
                }
            }
        }

        return new TableDataInfo(list, MapUtils.getInteger(data, "totalCount", 0));
    }

    public R uipGroupData() throws Exception {
        String redisKey = CacheConstants.DATA_UIPGROUPDATA;

        Map<String, Object> cacheMap = redisCache.getCacheMap(redisKey);
        if (MapUtils.isNotEmpty(cacheMap)) {
            return R.ok(cacheMap);
        }

        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/enterprise/uipGroupData", new HashMap<>());
        Integer code = MapUtils.getInteger(map, "code", 300);
        if (200 != code) throw new RuntimeException();

        Map data = MapUtils.getMap(map, "data", null);
        redisCache.setCacheMap(redisKey, data);
        redisCache.expire(redisKey, 24, TimeUnit.HOURS);

        return BeanUtil.toBean(map, R.class);
    }

    public R remark(EnterpriseRemarkBody vo) throws Exception {
        return R.ok(EncodeIdUtil.avDecode(EncodeIdUtil.binaryToUnicode(vo.mark)));
    }

    public R bondCreditRating(EnterpriseBondCreditRatingBody body) throws Exception {
        if (body.isVaildCid()) return R.ok();
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/enterprise/bondCreditRating", BeanUtil.beanToMap(body, false, false));
        return BeanUtil.toBean(map, R.class);
    }
    public R getUipIdByCid(List<Integer> body) throws Exception {
        if (CollectionUtils.isEmpty(body)) return R.ok();
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("ids", body);
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/enterprise/getUipIdByCid", paramMap);
        return BeanUtil.toBean(map, R.class);
    }
}
