package org.dromara.service.impl;


import org.apache.commons.lang3.ObjectUtils;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.AjaxResult;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.domain.checkPoint.bo.CheckPointRecordBo;
import org.dromara.domain.checkPoint.vo.CheckPointRecordVo;
import org.dromara.domain.complaintSuggestion.bo.ComplaintSuggestionBo;
import org.dromara.domain.complaintSuggestion.vo.ComplaintSuggestionVo;
import org.dromara.domain.illegalParking.bo.IllegalParkingBo;
import org.dromara.domain.illegalParking.vo.IllegalParkingVo;
import org.dromara.domain.propertyRepair.PropertyRepair;
import org.dromara.domain.residentInfo.ResidentInfo;
import org.dromara.domain.staffManage.StaffManage;
import org.dromara.mapper.*;
import org.dromara.service.ICheckPointRecordService;
import org.dromara.service.IComplaintSuggestionService;
import org.dromara.service.IIllegalParkingService;
import org.dromara.service.IStatisticsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.dromara.common.core.constant.Constants.*;


/**
 * 首页统计Service业务层处理
 *
 * @author boman
 * @date 2025-03-06
 */
@Service
public class StatisticsServiceImpl implements IStatisticsService {

    @Autowired
    private IllegalParkingMapper illegalParkingMapper;
    @Autowired
    private IIllegalParkingService illegalParkingService;
    @Autowired
    private ICheckPointRecordService checkPointRecordService;
    @Autowired
    private PropertyRepairMapper propertyRepairMapper;
    @Autowired
    private IComplaintSuggestionService complaintSuggestionService;
    @Autowired
    private VisitorManageMapper visitorManageMapper;
    @Autowired
    private HouseInfoMapper houseInfoMapper;
    @Autowired
    private ProprietorCarMapper proprietorCarMapper;


    @Override
    public R<Map<String, Object>> numApp() {
        String day = DateUtils.getDate();
        String dayTime = DateUtils.getTime();
        Map<String, Object> map = new HashMap<>();
        //空闲车位
        int kxcw = 0;
        //空闲充电桩
        int kxcdz = 0;
        //进入车辆
        int jrcl = 0;
        //离开车辆
        int lkcl = 0;
        //外来车辆
        int wlcl = 0;
        //违停登记
        int wtdj = 0;
        //外来人员
        int wlry = 0;
        //进入人员
        int jrry = 0;
        //已巡更
        int yxg = 0;
        //未巡更
        int wxg = 0;
        //家政订单
        int jzdd = 0;
        //完成订单
        int wcdd = 0;
        //今日报修
        int jrbx = 0;
        //已派报修
        int ypbx = 0;
        //投诉建议
        int tsjy = 0;
        //已回投诉
        int yhjy = 0;
        // todo 空闲车位，空闲充电桩，进入车辆，离开车辆，外来车辆，外来人员，进入人员，家政订单，完成订单


        //查询违停登记
        Map<String, Object> params = new HashMap<>();
        params.put("createTime", day);
        IllegalParkingBo illegalParking = new IllegalParkingBo();
        illegalParking.setParams(params);
        List<IllegalParkingVo> illegalParkings = illegalParkingService.queryList(illegalParking);
        if (illegalParkings != null && !illegalParkings.isEmpty()) {
            wtdj = illegalParkings.size();
        }
        //查询巡更
        CheckPointRecordBo checkPointRecord = new CheckPointRecordBo();
        checkPointRecord.setCheckTime(DateUtils.getNowDate());
        List<CheckPointRecordVo> checkPointRecords = checkPointRecordService.queryList(checkPointRecord);
        if (checkPointRecords != null && !checkPointRecords.isEmpty()) {
            Map<String, List<CheckPointRecordVo>> collects = checkPointRecords.stream().collect(Collectors.groupingBy(CheckPointRecordVo::getCheckStatus));
            if (collects.containsKey("1")) {
                wxg = collects.get("1").size();
            }
            if (collects.containsKey("2")) {
                yxg = collects.get("2").size();
            }
        }

        //查询报修
        List<PropertyRepair> propertyRepairs = propertyRepairMapper.selectPropertyRepairListByTime(day, day);
        if (propertyRepairs != null && !propertyRepairs.isEmpty()) {
            jrbx = propertyRepairs.size();
            for (PropertyRepair propertyRepair : propertyRepairs) {
                if (StringUtils.isNotEmpty(propertyRepair.getPhoneNumber())) {
                    ypbx++;
                }
            }
        }
        //查询投诉建议
        ComplaintSuggestionBo complaintSuggestion = new ComplaintSuggestionBo();
        complaintSuggestion.setParams(params);
        List<ComplaintSuggestionVo> complaintSuggestions = complaintSuggestionService.queryList(complaintSuggestion);
        if (complaintSuggestions != null && !complaintSuggestions.isEmpty()) {
            tsjy = complaintSuggestions.size();
            Map<String, List<ComplaintSuggestionVo>> suggestionCollect = complaintSuggestions.stream().collect(Collectors.groupingBy(ComplaintSuggestionVo::getStatus));
            if (suggestionCollect.containsKey("2")) {
                yhjy = suggestionCollect.get("2").size();
            }
        }
        map.put("wtdj", wtdj);
        map.put("yxg", yxg);
        map.put("wxg", wxg);
        map.put("jrbx", jrbx);
        map.put("ypbx", ypbx);
        map.put("tsjy", tsjy);
        map.put("yhjy", yhjy);
        // todo 空闲车位，空闲充电桩，进入车辆，离开车辆，外来车辆，外来人员，进入人员，家政订单，完成订单
        map.put("kxcw", kxcw);
        map.put("kxcdz", kxcdz);
        map.put("jrcl", jrcl);
        map.put("lkcl", lkcl);
        map.put("wlcl", wlcl);
        map.put("wlry", wlry);
        map.put("jrry", jrry);
        map.put("jzdd", jzdd);
        map.put("wcdd", wcdd);
        return R.ok(map);
    }

    /**
     * APP首页红点统计物业
     */
    @Override
    public R<Map<String, Object>> wuYeTips(StaffManage staffManage) {
        Map<String, Object> map = new HashMap<>(3);
        Long userId = staffManage.getUserId();
        //物业报修未完成的数量 投诉建议未回复的数量 社区资讯未读数量
        Object repairNum = RedisUtils.getCacheObject(PROPERTY_REPAIR_NO_ALL);
        map.put("propertyRepair", 0);
        if (ObjectUtils.isNotEmpty(repairNum)) {
            map.put("propertyRepair", repairNum);
        }
        //投诉建议未回复的数量
        Object complaintSuggestionNum = RedisUtils.getCacheObject(COMPLAINT_SUGGESTION_NO_ALL);
        map.put("complaintSuggestion", 0);
        if (ObjectUtils.isNotEmpty(repairNum)) {
            map.put("complaintSuggestion", complaintSuggestionNum);
        }
        //查询社区资讯未读互动数量
        map.put("commentInteractionUserCount", 0);
        String commentInteractionUserCountKey = COMMENT_INTERACTION_USER_COUNT + userId;
        Object commentInteractionUserCount = RedisUtils.getCacheObject(commentInteractionUserCountKey);
        if (ObjectUtils.isNotEmpty(commentInteractionUserCount)) {
            map.put("commentInteractionUserCount", commentInteractionUserCount);
        }
        return R.ok(map);
    }

    /**
     * APP首页红点业主统计
     */
    @Override
    public R<Map<String, Object>> yeZhuTips(ResidentInfo residentInfo) {
        Map<String, Object> map = new HashMap<>(7);
        Long userId = residentInfo.getUserId();
        //物业报修未完成的数量 投诉建议未回复的数量 社区资讯未读数量
        String userRepairKey = PROPERTY_REPAIR_NO + userId;
        Object repairNum = RedisUtils.getCacheObject(userRepairKey);
        map.put("propertyRepair", 0);
        if (ObjectUtils.isNotEmpty(repairNum)) {
            map.put("propertyRepair", repairNum);
        }
        //个人投诉建议未回复的数量
        String userSuggestionKey = COMPLAINT_SUGGESTION_NO + userId;
        Object complaintSuggestionNum = RedisUtils.getCacheObject(userSuggestionKey);
        map.put("complaintSuggestion", 0);
        if (ObjectUtils.isNotEmpty(repairNum)) {
            map.put("complaintSuggestion", complaintSuggestionNum);
        }
        //未读互动的数量
        //查询社区资讯未读互动数量
        map.put("commentInteractionUserCount", 0);
        String commentInteractionUserCountKey = COMMENT_INTERACTION_USER_COUNT + userId;
        Object commentInteractionUserCount = RedisUtils.getCacheObject(commentInteractionUserCountKey);
        if (ObjectUtils.isNotEmpty(commentInteractionUserCount)) {
            map.put("commentInteractionUserCount", commentInteractionUserCount);
        }
        //点赞的数量
        //获取记录社区资讯某个用户一共有多少个未读的互动(点赞，收藏，回复)的具体信息
        String commentInteractionUserKey = COMMENT_INTERACTION_USER + userId;
        Map<String, Object> commentInteractionUserMap = RedisUtils.getCacheMap(commentInteractionUserKey);
        //点赞数量
        int likeCount = 0;
        //评论数量
        int contentCount = 0;
        if (commentInteractionUserMap != null && !commentInteractionUserMap.isEmpty()) {
            // hkey = {targetType:targetId} targetType = 目标类型（1：资讯评论 2：资讯点赞 3：资讯收藏 4：评论回复 5:回复点赞）
            for (String hKey : commentInteractionUserMap.keySet()) {
                //找到所有点赞的数量targetType = 2|5
                String type = hKey.split(":")[0];
                if (type.equals(TWO) || type.equals(FIV)) {
                    likeCount = likeCount + 1;
                }
                if (likeCount == 99) {
                    break;
                }
            }
            for (String hKey : commentInteractionUserMap.keySet()) {
                //找到所有评论的数量targetType = 2|5
                String type = hKey.split(":")[0];
                if (type.equals(ONE) || type.equals(FOR)) {
                    contentCount = contentCount + 1;
                }
                if (contentCount == 99) {
                    break;
                }
            }

        }
        map.put("likeCount", likeCount);
        map.put("contentCount", contentCount);

        //我的房屋
        int houseCount = 0;
        List<ResidentInfo> residentInfos = houseInfoMapper.selectHouseInfoListAndResidentInfo(residentInfo);
        if (residentInfos != null && residentInfos.size() > 0) {
            houseCount = residentInfos.size();
        }
        map.put("houseCount", houseCount);
        //我的车辆
        map.put("carCount", proprietorCarMapper.selectProprietorCarCount(residentInfo.getResidentPhone()));
        return R.ok(map);
    }

    /**
     * web车辆管控统计
     */
    @Override
    public AjaxResult vehicleControl() {
        Map<String, Object> map = new HashMap<>();
        // todo 空闲车位，空闲充电桩，进入车辆，离开车辆
        //空闲车位数量
        map.put("idlePlace", 0);
        //空闲车位占比
        map.put("idlePercentage", "25%");
        //空闲充电桩数量
        map.put("chargePlace", 0);
        //空闲充电桩占比
        map.put("chargePercentage", "25%");
        //进入车辆
        map.put("interCarNum", 0);
        map.put("interCarStatus", UP);
        map.put("interCarPercentage", "25.83%");
        //离开车辆
        map.put("outCarNum", 0);
        map.put("outCarStatus", UP);
        map.put("outCarPercentage", "25.83%");

        //---------外来车辆------------
        getVisitorCar(map);
        //---------外来车辆结束------------
        //---------违停登记------------
        getIllegalCar(map);

        //---------违停登记结束------------
        return AjaxResult.success(map);
    }

    /**
     * visitor_manage来访管理表表中的车辆
     *
     * @param map
     * @return
     */
    public Map<String, Object> getVisitorCar(Map<String, Object> map) {
        //查询当月来访车辆总数
        int currentMonth = 0;
        Object nowMonthRedis = RedisUtils.getCacheObject(NOW_MONTH_VISITOR_CAR + DateUtils.getMonth());
        if (ObjectUtils.isNotEmpty(nowMonthRedis)) {
            currentMonth = (int) nowMonthRedis;
        }
        //上月数据
        int previousMonth = 0;
        map.put("visitorNum", currentMonth);
        map.put("visitorStatus", UP);
        //查询上月月来访车辆总数
        Object cacheObject = RedisUtils.getCacheObject(LAST_MONTH_VISITOR_CAR);
        if (ObjectUtils.isNotEmpty(cacheObject)) {
            previousMonth = Integer.parseInt(cacheObject.toString());
        } else {
            //查询数据库写入redis
            previousMonth = visitorManageMapper.selectVisitorManageVehicleCount(DateUtils.getLastMonth());
            RedisUtils.setCacheObject(LAST_MONTH_VISITOR_CAR, previousMonth);
        }
        //判断谁大
        if (currentMonth < previousMonth) {
            map.put("visitorStatus", DOWN);
        } else if (currentMonth == previousMonth) {
            map.put("visitorStatus", FLAT);
        }
        //计算百分比
        map.put("visitorPercentage", getPercentageChange(currentMonth, previousMonth));
        return map;
    }


    /**
     * illegal_parking 违章停车登记表
     *
     * @param map
     * @return
     */
    public Map<String, Object> getIllegalCar(Map<String, Object> map) {
        //查询当月违停车辆总数
        int currentMonth = 0;
        Object nowMonthRedis = RedisUtils.getCacheObject(NOW_MONTH_ILLEGAL_CAR + DateUtils.getMonth());
        if (ObjectUtils.isNotEmpty(nowMonthRedis)) {
            currentMonth = (int) nowMonthRedis;
        }
        //上月数据
        int previousMonth = 0;
        map.put("illegalNum", currentMonth);
        map.put("illegalStatus", UP);
        //查询上月月违停车辆总数
        Object cacheObject = RedisUtils.getCacheObject(LAST_MONTH_ILLEGAL_CAR);
        if (ObjectUtils.isNotEmpty(cacheObject)) {
            previousMonth = Integer.parseInt(cacheObject.toString());
        } else {
            //查询数据库写入redis
            previousMonth = illegalParkingMapper.selectIllegalCount(DateUtils.getLastMonth());
            RedisUtils.setCacheObject(LAST_MONTH_ILLEGAL_CAR, previousMonth);
        }
        //判断谁大
        if (currentMonth < previousMonth) {
            map.put("illegalStatus", DOWN);
        } else if (currentMonth == previousMonth) {
            map.put("illegalStatus", FLAT);
        }
        //计算百分比
        map.put("illegalPercentage", getPercentageChange(currentMonth, previousMonth));

        return map;
    }


    /**
     * 两个数计算绝对值百分比
     * 格式化为两位小数+百分号
     *
     * @param previousMonth 上月
     * @param currentMonth  当月
     * @return
     */
    public String getPercentageChange(int currentMonth, int previousMonth) {
        double percentageChange;

        if (previousMonth == 0) {
            // 处理上月为0的特殊情况
            percentageChange = (currentMonth == 0)
                    ? 0.0          // 两月都为0 → 0%变化
                    : 100.0;       // 上月为0且本月非0 → 视为100%增长
        } else {
            // 常规计算并取绝对值确保正数
            double change = currentMonth - previousMonth;
            percentageChange = Math.abs((change / previousMonth) * 100);
        }
        return String.format("%.2f%%", percentageChange);
    }

    @Override
    public AjaxResult numCar() {
        Map<String,Object> map = new HashMap<>();
        //总数
        int zs = 1237;
        //外来
        int wl = 396;
        //内部
        int nb = 841;
        map.put("zs",zs);
        map.put("wl",wl);
        map.put("nb",nb);
        return AjaxResult.success(map);
    }
}
