package cn.superdesk.uniorder.service._dashboard.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.dao.entity.organisation.SysOrganization;
import cn.superdesk.uniorder.dao.mapper._dashboard.TvDashboardMapper;
import cn.superdesk.uniorder.dto.param._dashboard.TvHeadDataQueryCriteria;
import cn.superdesk.uniorder.dto.param._dashboard.TvMapDataQueryCriteria;
import cn.superdesk.uniorder.dto.vo._dashboard.TvHeadDataVo;
import cn.superdesk.uniorder.dto.vo._dashboard.TvMapDataVo;
import cn.superdesk.uniorder.openapicall.superdeskapp.service.SuperdeskCloudOpenDataCallService;
import cn.superdesk.uniorder.openapicall.superdeskmall.service.FlscCallService;
import cn.superdesk.uniorder.openapicall.superdeskmall.service.FlscQchCallService;
import cn.superdesk.uniorder.openapicall.superdeskmall.service.QyngCallService;
import cn.superdesk.uniorder.openapicall.superdeskuniorder.service.OctlifeUniOrderCallApiService;
import cn.superdesk.uniorder.service._dashboard.TvDashboardService;
import cn.superdesk.uniorder.service.organisation.SysEnterpriseService;
import cn.superdesk.uniorder.service.organisation.SysOrganizationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: Java类作用描述
 * @Author: linjinyu
 * @CreateDate: 2021/9/23 下午3:24
 * @UpdateUser: linjinyu
 * @UpdateDate: 2021/9/23 下午3:24
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class TvDashboardServiceImpl implements TvDashboardService {

	@Autowired
	private TvDashboardMapper      tvDashboardMapper;


	/****************************************** call open api start ******************************************/
	@Autowired
	private OctlifeUniOrderCallApiService octlifeUniOrderCallApiService;

	@Autowired
	private SuperdeskCloudOpenDataCallService superdeskCloudOpenDataCallService;

	@Autowired
	private FlscCallService    flscCallbackService;
	@Autowired
	private FlscQchCallService flscQchCallbackService;
	@Autowired
	private QyngCallService    qyngCallbackService;

	@Autowired
	private SysEnterpriseService   sysEnterpriseService;
	@Autowired
	private SysOrganizationService sysOrganizationService;


	private static final Integer SPECIAL_HANDLE_CALL_OCT       = 167;
	private static final Integer SPECIAL_HANDLE_CALL_USERCOUNT = 168;

	@Override
	public TvHeadDataVo getHeadData(TvHeadDataQueryCriteria queryCriteria) {

		log.info("TvDashboardServiceImpl getHeadData queryCriteria\n{}", AnJsonUtils.toJson(queryCriteria));

//		String octAccessToken = octlifeUniOrderCallApiService.loginBySupplier(1L, "前台优选");


		/****************************************** 初始 start ******************************************/

		TvHeadDataVo responseDate = new TvHeadDataVo();
		TvHeadDataVo localDate    = null;
		TvHeadDataVo octDate      = null;

		List<TvHeadDataVo> countDateList = new ArrayList<>();


		/****************************************** 本地数据 start ******************************************/

		localDate = tvDashboardMapper.getHeadData(queryCriteria);
		countDateList.add(localDate);
		responseDate.setUniTvHeadDataVo(localDate);

		localDate.setRegisterOrgCount(sysOrganizationService.countOutOrg());
		localDate.setRegisterVirtCount(sysEnterpriseService.countOutVirt());

		/****************************************** 侨城汇数据 start ******************************************/

		if (ObjectUtil.isNotNull(queryCriteria.getSpecialHandleCallOct()) && queryCriteria.getSpecialHandleCallOct().compareTo(SPECIAL_HANDLE_CALL_OCT) == 0) {

			R<TvHeadDataVo> octResponse = octlifeUniOrderCallApiService.dashboardTvGetHeadDataOct("", queryCriteria);

			if (ObjectUtil.isNotNull(octResponse)) {

				octDate = octResponse.getData();

				log.info("octDate response date \n{}", AnJsonUtils.toJson(octDate));

				if (ObjectUtil.isNotNull(octDate)) {
					countDateList.add(octDate);
					responseDate.setOctTvHeadDataVo(octDate);
				}
			}

		}

		/****************************************** 累计服务客户 start ******************************************/


		// 用户数(累计服务客户(目前三个外调接口获取 服务之窗 福利商城 福利商城(侨城汇)))
		Long registerUserCount = 0L;

		// 用户数(累计服务客户(后端外调接口获取 服务之窗))
		Long registerUserSuperCount    = 0L;
		Date registerUserSuperCallTime = DateUtil.date();

		// 用户数(累计服务客户(后端外调接口获取 福利商城))
		Long registerUserFlscCount    = 0L;
		Date registerUserFlscCallTime = DateUtil.date();

		// 用户数(累计服务客户(后端外调接口获取 福利商城(侨城汇)))
		Long registerUserFlscQchCount    = 0L;
		Date registerUserFlscQchCallTime = DateUtil.date();


		if (ObjectUtil.isNotNull(queryCriteria.getSpecialHandleCallUserCount()) && queryCriteria.getSpecialHandleCallUserCount().compareTo(SPECIAL_HANDLE_CALL_USERCOUNT) == 0) {

			registerUserSuperCount = superdeskCloudOpenDataCallService.dashboardTvGetUserCount("");
			registerUserFlscCount = flscCallbackService.dashboardTvGetUserCount("");
			registerUserFlscQchCount = flscQchCallbackService.dashboardTvGetUserCount("");

		}

		responseDate.setRegisterUserSuperCount(registerUserSuperCount);
		responseDate.setRegisterUserSuperCallTime(registerUserSuperCallTime);

		responseDate.setRegisterUserFlscCount(registerUserFlscCount);
		responseDate.setRegisterUserFlscCallTime(registerUserFlscCallTime);

		responseDate.setRegisterUserFlscQchCount(registerUserFlscQchCount);
		responseDate.setRegisterUserFlscQchCallTime(registerUserFlscQchCallTime);

		registerUserCount = registerUserSuperCount + registerUserFlscCount + registerUserFlscQchCount;
		responseDate.setRegisterUserCount(registerUserCount);


		/****************************************** 合并 start ******************************************/


		responseDate.setRegisterOrgCount(countDateList.stream().map(item -> null == item.getRegisterOrgCount() ? 0L : item.getRegisterOrgCount()).reduce(0L, Long::sum));
		responseDate.setRegisterVirtCount(countDateList.stream().map(item -> null == item.getRegisterVirtCount() ? 0L : item.getRegisterVirtCount()).reduce(0L, Long::sum));

		responseDate.setOrgCount(countDateList.stream().map(item -> null == item.getOrgCount() ? 0L : item.getOrgCount()).reduce(0L, Long::sum));
		responseDate.setOrgNameCount(countDateList.stream().map(item -> null == item.getOrgNameCount() ? 0L : item.getOrgNameCount()).reduce(0L, Long::sum));

		responseDate.setVirtCount(countDateList.stream().map(item -> null == item.getVirtCount() ? 0L : item.getVirtCount()).reduce(0L, Long::sum));
		responseDate.setUserCount(countDateList.stream().map(item -> null == item.getUserCount() ? 0L : item.getUserCount()).reduce(0L, Long::sum));
		responseDate.setOrderCount(countDateList.stream().map(item -> null == item.getOrderCount() ? 0L : item.getOrderCount()).reduce(0L, Long::sum));

		responseDate.setOrderAmountSumIf(countDateList.stream().map(item -> null == item.getOrderAmountSumIf() ? BigDecimal.ZERO : item.getOrderAmountSumIf()).reduce(BigDecimal.ZERO, BigDecimal::add));

		responseDate.setOrderAmount(countDateList.stream().map(item -> null == item.getOrderAmount() ? BigDecimal.ZERO : item.getOrderAmount()).reduce(BigDecimal.ZERO, BigDecimal::add));
		responseDate.setOrderCostAmount(countDateList.stream().map(item -> null == item.getOrderCostAmount() ? BigDecimal.ZERO : item.getOrderCostAmount()).reduce(BigDecimal.ZERO, BigDecimal::add));
		responseDate.setOrderTransportAmount(countDateList.stream().map(item -> null == item.getOrderTransportAmount() ? BigDecimal.ZERO : item.getOrderTransportAmount()).reduce(BigDecimal.ZERO, BigDecimal::add));
		responseDate.setOrderRefundAmount(countDateList.stream().map(item -> null == item.getOrderRefundAmount() ? BigDecimal.ZERO : item.getOrderRefundAmount()).reduce(BigDecimal.ZERO, BigDecimal::add));
		responseDate.setOrderRefundCostAmount(countDateList.stream().map(item -> null == item.getOrderRefundCostAmount() ? BigDecimal.ZERO : item.getOrderRefundCostAmount()).reduce(BigDecimal.ZERO, BigDecimal::add));

		responseDate.setGoodsAmount(countDateList.stream().map(item -> null == item.getGoodsAmount() ? BigDecimal.ZERO : item.getGoodsAmount()).reduce(BigDecimal.ZERO, BigDecimal::add));
		responseDate.setGoodsCostAmount(countDateList.stream().map(item -> null == item.getGoodsCostAmount() ? BigDecimal.ZERO : item.getGoodsCostAmount()).reduce(BigDecimal.ZERO, BigDecimal::add));
		responseDate.setGoodsTransportAmount(countDateList.stream().map(item -> null == item.getGoodsTransportAmount() ? BigDecimal.ZERO : item.getGoodsTransportAmount()).reduce(BigDecimal.ZERO, BigDecimal::add));
		responseDate.setGoodsRefundAmount(countDateList.stream().map(item -> null == item.getGoodsRefundAmount() ? BigDecimal.ZERO : item.getGoodsRefundAmount()).reduce(BigDecimal.ZERO, BigDecimal::add));
		responseDate.setGoodsRefundCostAmount(countDateList.stream().map(item -> null == item.getGoodsRefundCostAmount() ? BigDecimal.ZERO : item.getGoodsRefundCostAmount()).reduce(BigDecimal.ZERO, BigDecimal::add));

		return responseDate;
	}

	@Override
	public TvHeadDataVo getHeadDataOct(TvHeadDataQueryCriteria queryCriteria) {

		log.info("TvDashboardServiceImpl getHeadDataOct queryCriteria\n{}", AnJsonUtils.toJson(queryCriteria));


		/****************************************** 初始 start ******************************************/

		TvHeadDataVo localDate = null;

		/****************************************** 本地数据 start ******************************************/

		localDate = tvDashboardMapper.getHeadData(queryCriteria);

		localDate.setRegisterOrgCount(sysOrganizationService.countOutOrg());
		localDate.setRegisterVirtCount(sysEnterpriseService.countOutVirt());

		if (ObjectUtil.isEmpty(localDate.getRegisterOrgCount()) || localDate.getRegisterOrgCount().equals(0L)) {
			localDate.setRegisterOrgCount(1L);
		}

		return localDate;
	}

	@Override
	public List<TvMapDataVo> getMapData(TvMapDataQueryCriteria queryCriteria) {

		/****************************************** 初始 start ******************************************/

		List<TvMapDataVo> responseDate = new ArrayList<>();

		List<TvMapDataVo> localDate = tvDashboardMapper.getMapData(queryCriteria);

		Map<Long, TvMapDataVo> resultMap = convertTvMapDataVoList2MapOutOrgIdEntity(localDate);

		/****************************************** 点位 start ******************************************/

		List<SysOrganization> pointList = sysOrganizationService.findByTvHeadData();

		pointList.forEach(item -> {

			TvMapDataVo tmpVo = new TvMapDataVo();

			tmpVo.setOrgId(item.getOrganizationId());
			tmpVo.setOrgName(item.getOrganizationName());
			tmpVo.setLat(item.getLat());
			tmpVo.setLng(item.getLng());
			tmpVo.setOrderAmount(BigDecimal.ZERO);
			tmpVo.setOrderCount(0L);

			if (ObjectUtil.isNotNull(resultMap.get(item.getOrganizationId()))) {

				TvMapDataVo hitVo = resultMap.get(item.getOrganizationId());

				tmpVo.setOrderAmount(hitVo.getOrderAmount());
				tmpVo.setOrderCount(hitVo.getOrderCount());
			}

			responseDate.add(tmpVo);
		});

		/****************************************** 侨城汇 start ******************************************/

		if (ObjectUtil.isNotNull(queryCriteria.getSpecialHandleCallOct()) && queryCriteria.getSpecialHandleCallOct().compareTo(SPECIAL_HANDLE_CALL_OCT) == 0) {

			// ②显示侨城汇项目,统一订单虚拟项目数据:
			// ·项目ID"-100";
			// ·项目名称:深圳市侨城汇网络科技有限公司
			// ·经纬度:113.9304,22.5333
			R<List<TvMapDataVo>> octResponse = octlifeUniOrderCallApiService.dashboardTvGetMapDataOct("", queryCriteria);

			if (ObjectUtil.isNotNull(octResponse)) {

				List<TvMapDataVo> octDate = octResponse.getData();

				if (CollUtil.isNotEmpty(octDate)) {

					octDate.forEach(octItem -> {

						TvMapDataVo octTmpVo = new TvMapDataVo();

						octTmpVo.setOrgId(-100L);
						octTmpVo.setOrgName("深圳市侨城汇网络科技有限公司");
						octTmpVo.setLng(new BigDecimal(113.9304));
						octTmpVo.setLat(new BigDecimal(22.5333));
						octTmpVo.setOrderAmount(octItem.getOrderAmount());
						octTmpVo.setOrderCount(octItem.getOrderCount());

						responseDate.add(octTmpVo);
					});

				}
			}
		}


		// return tvDashboardMapper.getMapData(queryCriteria);
		return responseDate;
	}

	@Override
	public List<TvMapDataVo> getMapDataOct(TvMapDataQueryCriteria queryCriteria) {

		/****************************************** 初始 start ******************************************/

		List<TvMapDataVo> responseDate = new ArrayList<>();

		List<TvMapDataVo> localDate = tvDashboardMapper.getMapData(queryCriteria);

//		SELECT uo.project_id as org_id, pro.organization_name as org_name, sum(IFNULL(uo.amount,0)) as order_amount, COUNT(uo.id) as order_count, pro.lng, pro.lat from unified_order uo LEFT JOIN sys_organization pro on uo.project_id = pro.organization_id WHERE uo.complet_state in ( 1,2) and DATE_FORMAT(uo.create_time,'%Y-%m-%d') >= '2021-10-03' and DATE_FORMAT(uo.create_time,'%Y-%m-%d') <= '2021-11-02' GROUP BY uo.project_id ORDER BY sum(IFNULL(uo.amount,0)) desc

		if (CollUtil.isNotEmpty(localDate)) {
			localDate.forEach(octTmpVo -> {

				octTmpVo.setOrgId(-100L);
				octTmpVo.setOrgName("深圳市侨城汇网络科技有限公司");
				octTmpVo.setLng(new BigDecimal(113.9304));
				octTmpVo.setLat(new BigDecimal(22.5333));

				responseDate.add(octTmpVo);
			});
		}


		return responseDate;
	}

	private Map<Long, TvMapDataVo> convertTvMapDataVoList2MapOutOrgIdEntity(List<TvMapDataVo> localDate) {

		Map<Long, TvMapDataVo> resultMap = new HashMap<>();

		resultMap = localDate.stream().collect(Collectors.toMap(TvMapDataVo::getOrgId, v -> v, (k, v) -> v));

		return resultMap;
	}
}

