package cn.superdesk.uniorder.controller._dashboard;


import cn.superdesk.uniorder.common.exception.utils.ExceptionUtils;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.controller.base.BaseController;
import cn.superdesk.uniorder.dto.vo._function.select.SelectOptionOrg;
import cn.superdesk.uniorder.dto.vo._function.select.SelectOptionVirt;
import cn.superdesk.uniorder.dto.vo._dashboard.*;
import cn.superdesk.uniorder.dubbo.consumer._permission.PermissionDubboCustomerService;
import cn.superdesk.uniorder.dubbo.consumer._dashboard.BackendDashboardDubboConsumerService;
import cn.superdesk.uniorder.common.numerical.AnDateHelper;
import com.alibaba.fastjson2.JSON;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

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

/**
 * 看板
 * 查询 已完成 且 企业采购 订单
 */
@Api(value = "Dashboard-后端-首页", tags = "Dashboard-后端-首页")
@Slf4j
@RestController
@RequestMapping("/dashboard")
public class BackendDashboardController extends BaseController {

	@Autowired
	private BackendDashboardDubboConsumerService unifiedDashboardDubboConsumerService;

	@Autowired
	private PermissionDubboCustomerService permissionDubboCustomerService;


	/**
	 * 看板头部数据
	 *
	 * @return
	 */
	@PostMapping("/getDashboardHeadData")
	@ResponseBody
	public R<Map> getDashboardHeadData() {

		R<Map> result    = new R<>();
		Map    returnMap = new HashMap();

		try {


			Map<String, Object> params = new HashMap<>();
			params.put("virtIds", permissionDubboCustomerService.getPermOutVirtIds(getToken()));//用户权限企业

			log.info("getDashboardProjectPurchase 项目采购情况-参数params:{}", JSON.toJSONString(params));
			List<UnifiedDashboardHeadDataVo> allList = unifiedDashboardDubboConsumerService.getDashboardHeadData(params);


			String queryYearMonth = AnDateHelper.getCurrentDateStr("yyyy-MM");
			params.put("queryYearMonth", queryYearMonth);
			List<UnifiedDashboardHeadDataVo> monthList = unifiedDashboardDubboConsumerService.getDashboardHeadData(params);


			returnMap.put("allData", allList);
			returnMap.put("monthData", monthList);

			result.setSuccess(true);
			result.setData(returnMap);

			String                 permOutOrgIds        = permissionDubboCustomerService.getPermOutOrgIds(getToken());
			String                 permOutVirtIds       = permissionDubboCustomerService.getPermOutVirtIds(getToken());
			List<SelectOptionOrg>  listSelectOptionOrg  = permissionDubboCustomerService.getSelectPermOrgByToken(getToken());
			List<SelectOptionVirt> listSelectOptionVirt = permissionDubboCustomerService.getSelectPermVirtByToken(getToken());

			log.info("======>permOutOrgIds={}", permOutOrgIds);
			log.info("======>permOutVirtIds={}", permOutVirtIds);
			log.info("======>listSelectOptionOrg={}", JSON.toJSONString(listSelectOptionOrg));
			log.info("======>permOutOrgIds={}", JSON.toJSONString(listSelectOptionVirt));


		} catch (Exception e) {

			result.setCode(String.valueOf(e.hashCode()));
			result.setSuccess(false);
			result.setMessage(e.getMessage());

			log.error(ExceptionUtils.getMessage(e));
			e.printStackTrace();
		}

		return result;
	}


	/**
	 * 项目采购情况
	 *
	 * @return
	 */
	@PostMapping("/getDashboardProjectPurchase")
	@ResponseBody
	public R<List<UnifiedDashboardProjectPurchaseVo>> getDashboardProjectPurchase() {

		R<List<UnifiedDashboardProjectPurchaseVo>> result = new R<>();

		try {

			String queryYearMonth = getString("queryYearMonth");

			Map<String, Object> params = new HashMap<>();
			params.put("virtIds", permissionDubboCustomerService.getPermOutVirtIds(getToken()));//用户权限企业
			params.put("queryYearMonth", queryYearMonth);

			log.info("getDashboardProjectPurchase 项目采购情况-参数params:{}", JSON.toJSONString(params));
			List<UnifiedDashboardProjectPurchaseVo> list = unifiedDashboardDubboConsumerService.getDashboardProjectPurchase(params);

			result.setSuccess(true);
			result.setData(list);

		} catch (Exception e) {

			result.setCode(String.valueOf(e.hashCode()));
			result.setSuccess(false);
			result.setMessage(e.getMessage());

			log.error(ExceptionUtils.getMessage(e));
			e.printStackTrace();
		}

		return result;
	}


	/***
	 * 年度采购情况
	 * @return
	 */
	@PostMapping("/getDashboardYearPurchase")
	@ResponseBody
	public R<List<UnifiedDashboardYearPurchaseVo>> getDashboardYearPurchase() {

		R<List<UnifiedDashboardYearPurchaseVo>> result = new R<>();

		try {

			String queryYear = getString("queryYear");//年度

			Map<String, Object> params = new HashMap<>();
			params.put("queryYear", queryYear);
			params.put("projectId", getString("projectId"));
			params.put("virtId", getString("virtId"));//查询权限
			params.put("virtIds", permissionDubboCustomerService.getPermOutVirtIds(getToken()));//用户权限企业


			log.info("getDashboardYearPurchase 年度采购情况-参数params:{}", JSON.toJSONString(params));

			//获得1-12月采购情况-可能有的月份没有数据需处理
			//1	2039	138.92
			//2	2723	323.97
			//3	4213	208.66
			List<UnifiedDashboardYearPurchaseVo> list = unifiedDashboardDubboConsumerService.getDashboardYearPurchase(params);

			if (list.size() < 12) {//补充月份值
				List<Integer> listQueryMonth = list.stream().map(t -> t.getMonthNum()).collect(Collectors.toList());
				for (int i = 1; i <= 12; i++) {
					if (!listQueryMonth.contains(i)) {
						UnifiedDashboardYearPurchaseVo vo = new UnifiedDashboardYearPurchaseVo(i, 0, BigDecimal.ZERO);
						list.add(vo);
					}
				}
			}

			Integer        maxOrderNum    = list.stream().mapToInt(t -> t.getOrderNum()).max().getAsInt();
			Double         maxOrderAmount = Double.valueOf(0);
			OptionalDouble optionalDouble = list.stream().mapToDouble(t -> t.getOrderAmount().doubleValue()).max();
			if (optionalDouble.isPresent()) {
				maxOrderAmount = optionalDouble.getAsDouble();
			}

			Map<String, Object> headData = new HashMap<>();
			headData.put("maxOrderNum", maxOrderNum);//订单量最大数 --用于分级
			headData.put("maxOrderAmount", maxOrderAmount.intValue());//采购额最大数 --用于分级


			result.setSuccess(true);
			result.setData(list.stream().sorted(Comparator.comparing(UnifiedDashboardYearPurchaseVo::getMonthNum)).collect(Collectors.toList()));
			result.setHeadData(headData);

		} catch (Exception e) {

			result.setCode(String.valueOf(e.hashCode()));
			result.setSuccess(false);
			result.setMessage(e.getMessage());

			log.error(ExceptionUtils.getMessage(e));
			e.printStackTrace();
		}

		return result;
	}

	/***
	 * 项目采购对比分析<:3>
	 * @return
	 */
	@PostMapping("/getDashboardProjectPurchaseCompare")
	@ResponseBody
	public R<List<UnifiedDashboardProjectPurchaseCompareVo>> getDashboardProjectPurchaseCompare() {

		R<List<UnifiedDashboardProjectPurchaseCompareVo>> result = new R<>();

		try {

			String queryYearMonth = getString("queryYearMonth");

			Map<String, Object> params = new HashMap<>();
			params.put("checkedProjectIds", getString("checkedProjectIds"));
			params.put("virtIds", permissionDubboCustomerService.getPermOutVirtIds(getToken()));//用户权限企业
			params.put("queryYearMonth", queryYearMonth);


			log.info("getDashboardProjectPurchaseCompare 项目采购对比分析-参数params:{}", JSON.toJSONString(params));
			List<UnifiedDashboardProjectPurchaseCompareVo> list = unifiedDashboardDubboConsumerService.getDashboardProjectPurchaseCompare(params);

			result.setSuccess(true);
			result.setData(list);

		} catch (Exception e) {

			result.setCode(String.valueOf(e.hashCode()));
			result.setSuccess(false);
			result.setMessage(e.getMessage());

			log.error(ExceptionUtils.getMessage(e));
			e.printStackTrace();
		}

		return result;
	}


	/***
	 * 采购分类分析
	 * @return
	 */
	@PostMapping("/getDashboardPurchaseCateCompare")
	@ResponseBody
	public R<List<UnifiedDashboardPurchaseCateCompareVo>> getDashboardPurchaseCateCompare() {

		R<List<UnifiedDashboardPurchaseCateCompareVo>> result = new R<>();

		try {

			String queryYearMonth = getString("queryYearMonth");//月度

			Map<String, Object> params = new HashMap<>();
			params.put("queryYearMonth", queryYearMonth);
			params.put("projectId", getString("projectId"));
			params.put("virtId", getString("virtId"));//查询权限
			params.put("virtIds", permissionDubboCustomerService.getPermOutVirtIds(getToken()));//用户权限企业

			log.info("getDashboardPurchaseCateCompare 采购分类分析-参数params:{}", JSON.toJSONString(params));

			//获得1-12月采购情况-可能有的月份没有数据需处理
			//1	2039	138.92
			//2	2723	323.97
			//3	4213	208.66
			List<UnifiedDashboardPurchaseCateCompareVo> list       = unifiedDashboardDubboConsumerService.getDashboardPurchaseCateCompare(params);
			List<UnifiedDashboardPurchaseCateCompareVo> returnList = new ArrayList<>();


			Double         maxOrderAmount = Double.valueOf(0);
			OptionalDouble optionalDouble = list.stream().mapToDouble(t -> t.getOrderAmount().doubleValue()).max();//最大值
			if (optionalDouble.isPresent()) {
				maxOrderAmount = optionalDouble.getAsDouble();
			}
			BigDecimal sumOrderAmount   = list.stream().map(t -> t.getOrderAmount()).reduce(BigDecimal.ZERO, BigDecimal::add);//总计
			BigDecimal bdMaxOrderAmount = new BigDecimal(maxOrderAmount);

			//返回前9
			//第10为其他
			int        num              = 1;
			BigDecimal totalSale        = BigDecimal.ZERO;//前9总占比
			BigDecimal totalOrderAmount = BigDecimal.ZERO;//前9总金额
			for (UnifiedDashboardPurchaseCateCompareVo vo : list) {

				if (num < 10) {
					vo.setScale(vo.getOrderAmount().divide(bdMaxOrderAmount, 1, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)));//占比
					totalSale = totalSale.add(vo.getScale());
					totalOrderAmount = totalOrderAmount.add(vo.getOrderAmount());
					returnList.add(vo);
				} else if (num == 10) {
					vo.setScale(new BigDecimal(100).subtract(totalSale));
					vo.setOrderAmount(sumOrderAmount.subtract(totalOrderAmount));
					vo.setCateName("其他");
					returnList.add(vo);
					break;
				}

				++num;
			}


			Map<String, Object> headData = new HashMap<>();
			headData.put("sumOrderAmount", sumOrderAmount);//采购总金额

			result.setSuccess(true);
			result.setData(returnList);
			result.setHeadData(headData);
		} catch (Exception e) {

			result.setCode(String.valueOf(e.hashCode()));
			result.setSuccess(false);
			result.setMessage(e.getMessage());

			log.error(ExceptionUtils.getMessage(e));
			e.printStackTrace();
		}

		return result;
	}


	/***
	 * 商品采购情况排名
	 * @return
	 */
	@PostMapping("/getDashboardGoodsPurchaseRanking")
	@ResponseBody
	public R<Map> getDashboardGoodsPurchaseRanking() {

		R<Map> result    = new R<>();
		Map    returnMap = new HashMap();

		try {

			String queryYearMonth = getString("queryYearMonth");//月度

			Map<String, Object> params = new HashMap<>();
			params.put("queryYearMonth", queryYearMonth);
			params.put("virtIds", permissionDubboCustomerService.getPermOutVirtIds(getToken()));//用户权限企业
			String projectId = getString("projectId");
			String virtId    = getString("virtId");


			log.info("getDashboardPurchaseCateCompare 商品采购情况排名-参数params:{}", JSON.toJSONString(params));


			List<UnifiedDashboardGoodsPurchaseRankingVo> allList     = unifiedDashboardDubboConsumerService.getDashboardGoodsPurchaseRanking(params);
			List<UnifiedDashboardGoodsPurchaseRankingVo> projectList = allList;
			List<UnifiedDashboardGoodsPurchaseRankingVo> virtList    = allList;

			if (StringUtils.isNotEmpty(projectId)) {
				params.put("projectId", getString("projectId"));
				projectList = unifiedDashboardDubboConsumerService.getDashboardGoodsPurchaseRanking(params);
				virtList = projectList;
			}

			if (StringUtils.isNotEmpty(virtId)) {
				params.put("virtId", getString("virtId"));//查询权限
				virtList = unifiedDashboardDubboConsumerService.getDashboardGoodsPurchaseRanking(params);
			}

			returnMap.put("allList", allList);
			returnMap.put("projectList", projectList);
			returnMap.put("virtList", virtList);


			result.setSuccess(true);
			result.setData(returnMap);
		} catch (Exception e) {

			result.setCode(String.valueOf(e.hashCode()));
			result.setSuccess(false);
			result.setMessage(e.getMessage());

			log.error(ExceptionUtils.getMessage(e));
			e.printStackTrace();
		}

		return result;
	}


}
