package com.leromro.core.controller;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.leromro.common.core.domain.entity.SysDept;
import com.leromro.core.domain.Address;
import com.leromro.core.domain.SecondOrder;
import com.leromro.core.domain.VolunteerInfo;
import com.leromro.core.domain.dto.HomePageDTO;
import com.leromro.core.domain.vo.OrderSummaryVO;
import com.leromro.core.domain.vo.OrgRankVO;
import com.leromro.core.domain.vo.UserSummaryVO;
import com.leromro.core.service.IAddressService;
import com.leromro.core.service.ISecondOrderService;
import com.leromro.core.service.IVolunteerInfoService;
import com.leromro.system.service.ISysDeptService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.leromro.common.core.domain.R;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.leromro.common.annotation.Log;
import com.leromro.common.core.controller.BaseController;
import com.leromro.common.core.domain.AjaxResult;
import com.leromro.common.enums.BusinessType;
import com.leromro.core.domain.OrgStatData;
import com.leromro.core.service.IOrgStatDataService;
import com.leromro.common.utils.poi.ExcelUtil;
import com.leromro.common.core.page.TableDataInfo;

/**
 * 平台机构数据统计Controller
 * 
 * @author ruoyi
 * @date 2025-04-30
 */
@RestController
@Api(tags = "(首页)平台机构数据统计")
@RequiredArgsConstructor
@RequestMapping("/core/org/stat")
public class OrgStatDataController extends BaseController
{
    private final IOrgStatDataService orgStatDataService;

    private final ISecondOrderService secondOrderService;

    private final IAddressService addressService;

    private final IVolunteerInfoService volunteerInfoService;

    private final ISysDeptService deptService;

    /**
     * 订单总览
     */
    @ApiOperation(value = "订单总览", notes = "前端计算今日，昨天，本周到startDate字段，全部则传null")
    @PostMapping("/orderSummary")
    public R<OrderSummaryVO> orderSummary(@RequestBody HomePageDTO dto)
    {
        OrderSummaryVO orderSummaryVO = new OrderSummaryVO();
        //获取指定时间范围的订单
        List<SecondOrder> list = secondOrderService.getCurrentOrgSecondOrderList(dto);
        //订单总量
        orderSummaryVO.setOrderTotal(list.size());
        //取消单量
        orderSummaryVO.setOrderCancelTotal((int) list.stream().filter(item ->  "4".equals(item.getOrderStatus())).count());
        //订单金额
        orderSummaryVO.setOrderTotalAmount(BigDecimal.valueOf(list.stream().mapToDouble(item -> item.getServiceOnePrice().doubleValue()).sum()));
        //完成单量
        orderSummaryVO.setOrderFinishTotal((int) list.stream().filter(item ->  "2".equals(item.getOrderStatus())).count());
        return R.ok(orderSummaryVO);
    }

    /**
     * 人员总览
     */
    @ApiOperation(value = "人员总览", notes = "前端计算今日，昨天，本周到startDate字段，全部则传null")
    @PostMapping("/userSummary")
    public R<UserSummaryVO> userSummary(@RequestBody HomePageDTO dto)
    {
        UserSummaryVO userSummaryVO = new UserSummaryVO();
        //判断人员类型是否有值
        if (ObjectUtil.isNull(dto.getUserType())) {
            return R.fail("人员类型不能为空");
        }
        //获取当前机构本月记录，并按照日期映射
        List<OrgStatData> statDataList = orgStatDataService.getCurrentOrgMonthStatDataList(dto);
        Map<LocalDate, OrgStatData> statDataMap = statDataList.stream().collect(Collectors.toMap(OrgStatData::getStatDate, l -> l));
        if (dto.getUserType() == 1){
            //如果为用户则查看用户地址
            List<Address> addressList = addressService.getCurrentOrgClientList(dto);
            userSummaryVO.setUserTotal(addressList.size());
            userSummaryVO.setTodayAdd(ObjectUtil.isNull(statDataMap.get(LocalDate.now()))? addressList.size():(addressList.size() - statDataMap.get(LocalDate.now()).getAllClientTotal()));
            userSummaryVO.setYesterdayAdd(ObjectUtil.isNull(statDataMap.get(LocalDate.now().minusDays(1)))? addressList.size():(addressList.size() - statDataMap.get(LocalDate.now().minusDays(1)).getAllClientTotal()));
            userSummaryVO.setMonthAdd(ObjectUtil.isNull(statDataMap.get(LocalDate.now().withDayOfMonth(1)))? addressList.size():(addressList.size() - statDataMap.get(LocalDate.now().withDayOfMonth(1)).getAllClientTotal()));
        }else {
            //如果为志愿者则查看志愿者审批通过时间
            List<VolunteerInfo> volunteerInfoList = volunteerInfoService.getCurrentOrgVolunteerList(dto);
            userSummaryVO.setUserTotal(volunteerInfoList.size());
            userSummaryVO.setTodayAdd(ObjectUtil.isNull(statDataMap.get(LocalDate.now()))? volunteerInfoList.size():(volunteerInfoList.size() - statDataMap.get(LocalDate.now()).getAllVolunteerTotal()));
            userSummaryVO.setYesterdayAdd(ObjectUtil.isNull(statDataMap.get(LocalDate.now().minusDays(1)))? volunteerInfoList.size():(volunteerInfoList.size() - statDataMap.get(LocalDate.now().minusDays(1)).getAllVolunteerTotal()));
            userSummaryVO.setMonthAdd(ObjectUtil.isNull(statDataMap.get(LocalDate.now().withDayOfMonth(1)))? volunteerInfoList.size():(volunteerInfoList.size() - statDataMap.get(LocalDate.now().withDayOfMonth(1)).getAllVolunteerTotal()));
        }
        return R.ok(userSummaryVO);
    }

    /**
     * 机构排名
     */
    @ApiOperation(value = "机构排名", notes = "默认查询所有区县")
    @PostMapping("/orgRank")
    public R<OrgRankVO> orgRank(@RequestBody HomePageDTO dto)
    {
        OrgRankVO orgRankVO = new OrgRankVO();
        //获取今天所有订单
        List<SecondOrder> list = secondOrderService.getTodayAllOrderList(dto);
        if (ObjectUtil.isEmpty(list)){
            return R.ok(orgRankVO);
        }
        //获取所有区县机构(不含服务中心)
        List<SysDept> deptList = deptService.getAllOrgList();
        if (ObjectUtil.isEmpty(deptList)){
            return R.ok(orgRankVO);
        }
        Map<String, String> codeMapName = deptList.stream().collect(Collectors.toMap(SysDept::getDistrictCode, SysDept::getDeptName));
        /** 数量排序*/
        //按照区级区划编号分组并统计数量 结果为Map<String,integer>
        Map<String, Long> districtCodeMap = list.stream().filter(item -> StrUtil.isNotEmpty(item.getDistrictCode())).collect(Collectors.groupingBy(SecondOrder::getDistrictCode, Collectors.counting()));
        //districtCodeMap按照value大小排序
        List<Map.Entry<String, Long>> districtCodeMapList = districtCodeMap.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList());
        List<OrgRankVO.OrgOrderVo> orgOrderVoList = new ArrayList<>();
        for (Map.Entry<String, Long> entry : districtCodeMapList) {
            OrgRankVO.OrgOrderVo orgOrderVo = new OrgRankVO.OrgOrderVo();
            orgOrderVo.setOrgName(codeMapName.get(entry.getKey()));
            orgOrderVo.setOrderTotal(entry.getValue());
            orgOrderVoList.add(orgOrderVo);
        }
        orgRankVO.setOrgOrderVos(orgOrderVoList);

        /**金额排序*/
        Map<String, BigDecimal> districtCodeMapAmount = list.stream().filter(item -> StrUtil.isNotEmpty(item.getDistrictCode())).collect(Collectors.groupingBy(SecondOrder::getDistrictCode, Collectors.mapping(SecondOrder::getServiceOnePrice, Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
        List<Map.Entry<String, BigDecimal>> districtCodeMapAmountList = districtCodeMapAmount.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).collect(Collectors.toList());
        List<OrgRankVO.OrgAmountVo> orgAmountVos = new ArrayList<>();
        for (Map.Entry<String, BigDecimal> entry : districtCodeMapAmountList) {
            OrgRankVO.OrgAmountVo orgAmountVo = new OrgRankVO.OrgAmountVo();
            orgAmountVo.setOrgName(codeMapName.get(entry.getKey()));
            orgAmountVo.setOrderAmount(entry.getValue());
            orgAmountVos.add(orgAmountVo);
        }
        orgRankVO.setOrgAmountVos(orgAmountVos);
        return R.ok(orgRankVO);
    }

}
