package com.aegis.resource.dashboard.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.aegis.common.core.redis.RedisCache;
import com.aegis.resource.dashboard.mapper.ResourceDashboardMapper;
import com.aegis.resource.dashboard.service.IResourceDashboardService;
import com.aegis.resource.dashboard.vo.EquipmentStatsVO;
import com.aegis.resource.dashboard.vo.ExpertStatsVO;
import com.aegis.resource.dashboard.vo.InventoryAlertVO;
import com.aegis.resource.dashboard.vo.MaterialStatsVO;
import com.aegis.resource.dashboard.vo.ProcurementStatsVO;
import com.aegis.resource.dashboard.vo.RequisitionStatsVO;
import com.aegis.resource.dashboard.vo.ResourceStatsVO;
import com.aegis.resource.dashboard.vo.TeamStatsVO;
import com.aegis.resource.dashboard.vo.UsageTrendVO;
import com.aegis.resource.dashboard.vo.VehicleStatsVO;

/**
 * 资源看板Service业务层处理
 * 
 * @author aegis
 */
@Service
public class ResourceDashboardServiceImpl implements IResourceDashboardService {
    
    @Autowired
    private ResourceDashboardMapper dashboardMapper;
    
    @Autowired
    private RedisCache redisCache;
    
    /** 缓存时间：5分钟 */
    private static final int CACHE_TIME = 5;
    
    /** 缓存Key前缀 */
    private static final String CACHE_KEY_PREFIX = "resource:dashboard:";
    
    /** 资源总览统计缓存Key */
    private static final String CACHE_KEY_STATS = CACHE_KEY_PREFIX + "stats";
    
    /** 库存预警缓存Key */
    private static final String CACHE_KEY_INVENTORY_ALERTS = CACHE_KEY_PREFIX + "inventory-alerts";
    
    /** 采购状态统计缓存Key */
    private static final String CACHE_KEY_PROCUREMENT_STATUS = CACHE_KEY_PREFIX + "procurement-status";
    
    /** 征用状态统计缓存Key */
    private static final String CACHE_KEY_REQUISITION_STATUS = CACHE_KEY_PREFIX + "requisition-status";
    
    /** 资源状态分布缓存Key */
    private static final String CACHE_KEY_RESOURCE_DISTRIBUTION = CACHE_KEY_PREFIX + "resource-distribution";
    
    /** 使用趋势缓存Key前缀 */
    private static final String CACHE_KEY_USAGE_TRENDS = CACHE_KEY_PREFIX + "usage-trends";
    
    /**
     * 安全地从Map中获取Integer值（兼容大小写和Long类型）
     */
    private Integer getIntegerFromMap(Map<String, Object> map, String key) {
        if (map == null || key == null) {
            return 0;
        }
        Object value = map.get(key);
        if (value == null) {
            // 尝试大写key
            value = map.get(key.toUpperCase());
        }
        if (value == null) {
            return 0;
        }
        if (value instanceof Integer) {
            return (Integer) value;
        } else if (value instanceof Long) {
            return ((Long) value).intValue();
        } else if (value instanceof Number) {
            return ((Number) value).intValue();
        }
        return 0;
    }
    
    /**
     * 获取资源总览统计
     */
    @Override
    public ResourceStatsVO getResourceStats() {
        // 先查缓存
        Object cachedObj = redisCache.getCacheObject(CACHE_KEY_STATS);
        if (cachedObj != null) {
            // 如果已经是 ResourceStatsVO 类型，直接返回
            if (cachedObj instanceof ResourceStatsVO) {
                return (ResourceStatsVO) cachedObj;
            }
            // 如果是 JSONObject，转换为 ResourceStatsVO
            if (cachedObj instanceof JSONObject) {
                try {
                    ResourceStatsVO stats = JSON.parseObject(JSON.toJSONString(cachedObj), ResourceStatsVO.class);
                    return stats;
                } catch (Exception e) {
                    // 转换失败，清除缓存，重新查询
                    redisCache.deleteObject(CACHE_KEY_STATS);
                }
            } else {
                // 其他类型，清除缓存，重新查询
                redisCache.deleteObject(CACHE_KEY_STATS);
            }
        }
        
        // 缓存未命中，查询数据库
        ResourceStatsVO stats = new ResourceStatsVO();
        
        // 队伍统计
        Map<String, Object> teamStats = dashboardMapper.countTeamByStatus();
        if (teamStats != null) {
            TeamStatsVO teams = new TeamStatsVO();
            teams.setTotal(getIntegerFromMap(teamStats, "total"));
            teams.setAvailable(getIntegerFromMap(teamStats, "available"));
            teams.setBusy(getIntegerFromMap(teamStats, "busy"));
            teams.setOffline(getIntegerFromMap(teamStats, "offline"));
            stats.setTeams(teams);
        }
        
        // 车辆统计
        Map<String, Object> vehicleStats = dashboardMapper.countVehicleByStatus();
        if (vehicleStats != null) {
            VehicleStatsVO vehicles = new VehicleStatsVO();
            vehicles.setTotal(getIntegerFromMap(vehicleStats, "total"));
            vehicles.setAvailable(getIntegerFromMap(vehicleStats, "available"));
            vehicles.setBusy(getIntegerFromMap(vehicleStats, "busy"));
            vehicles.setRepair(getIntegerFromMap(vehicleStats, "repair"));
            stats.setVehicles(vehicles);
        }
        
        // 专家统计
        Map<String, Object> expertStats = dashboardMapper.countExpertByStatus();
        if (expertStats != null) {
            ExpertStatsVO experts = new ExpertStatsVO();
            experts.setTotal(getIntegerFromMap(expertStats, "total"));
            experts.setActive(getIntegerFromMap(expertStats, "active"));
            experts.setInactive(getIntegerFromMap(expertStats, "inactive"));
            experts.setBlacklisted(getIntegerFromMap(expertStats, "blacklisted"));
            stats.setExperts(experts);
        }
        
        // 装备统计
        Map<String, Object> equipmentStats = dashboardMapper.countEquipmentByStatus();
        if (equipmentStats != null) {
            EquipmentStatsVO equipment = new EquipmentStatsVO();
            equipment.setTotal(getIntegerFromMap(equipmentStats, "total"));
            equipment.setAvailable(getIntegerFromMap(equipmentStats, "available"));
            equipment.setBusy(getIntegerFromMap(equipmentStats, "busy"));
            equipment.setRepair(getIntegerFromMap(equipmentStats, "repair"));
            equipment.setScrap(getIntegerFromMap(equipmentStats, "scrap"));
            stats.setEquipment(equipment);
        }
        
        // 物资统计
        MaterialStatsVO materials = new MaterialStatsVO();
        Integer totalCategories = dashboardMapper.countMaterialCategory();
        materials.setTotalCategories(totalCategories != null ? totalCategories : 0);
        Integer totalMaterials = dashboardMapper.countMaterial();
        materials.setTotalMaterials(totalMaterials != null ? totalMaterials : 0);
        // 库存预警数量（直接查询，避免缓存循环）
        List<InventoryAlertVO> alerts = dashboardMapper.selectInventoryAlerts();
        materials.setAlertCount(alerts != null ? alerts.size() : 0);
        stats.setMaterials(materials);
        
        // 采购统计
        Map<String, Object> procurementStats = dashboardMapper.countProcurementByStatus();
        if (procurementStats != null) {
            ProcurementStatsVO procurement = new ProcurementStatsVO();
            procurement.setTotal(getIntegerFromMap(procurementStats, "total"));
            procurement.setDraft(getIntegerFromMap(procurementStats, "draft"));
            procurement.setSubmitted(getIntegerFromMap(procurementStats, "submitted"));
            procurement.setApproved(getIntegerFromMap(procurementStats, "approved"));
            procurement.setInProgress(getIntegerFromMap(procurementStats, "inProgress"));
            procurement.setReceived(getIntegerFromMap(procurementStats, "received"));
            stats.setProcurement(procurement);
        }
        
        // 征用统计
        Map<String, Object> requisitionStats = dashboardMapper.countRequisitionByStatus();
        if (requisitionStats != null) {
            RequisitionStatsVO requisition = new RequisitionStatsVO();
            requisition.setTotal(getIntegerFromMap(requisitionStats, "total"));
            requisition.setDraft(getIntegerFromMap(requisitionStats, "draft"));
            requisition.setApproved(getIntegerFromMap(requisitionStats, "approved"));
            requisition.setActive(getIntegerFromMap(requisitionStats, "active"));
            requisition.setEnded(getIntegerFromMap(requisitionStats, "ended"));
            stats.setRequisition(requisition);
        }
        
        // 写入缓存
        redisCache.setCacheObject(CACHE_KEY_STATS, stats, CACHE_TIME, TimeUnit.MINUTES);
        return stats;
    }
    
    /**
     * 获取库存预警列表
     */
    @Override
    public List<InventoryAlertVO> getInventoryAlerts() {
        // 先查缓存
        List<InventoryAlertVO> cached = redisCache.getCacheObject(CACHE_KEY_INVENTORY_ALERTS);
        if (cached != null) {
            return cached;
        }
        
        // 缓存未命中，查询数据库
        List<InventoryAlertVO> alerts = dashboardMapper.selectInventoryAlerts();
        if (alerts == null) {
            alerts = new ArrayList<>();
        }
        
        // 写入缓存
        redisCache.setCacheObject(CACHE_KEY_INVENTORY_ALERTS, alerts, CACHE_TIME, TimeUnit.MINUTES);
        return alerts;
    }
    
    /**
     * 获取采购状态统计
     */
    @Override
    public Map<String, Integer> getProcurementStatus() {
        // 先查缓存
        Map<String, Integer> cached = redisCache.getCacheObject(CACHE_KEY_PROCUREMENT_STATUS);
        if (cached != null) {
            return cached;
        }
        
        // 缓存未命中，查询数据库
        Map<String, Object> statusObj = dashboardMapper.countProcurementByStatus();
        Map<String, Integer> status = new HashMap<>();
        if (statusObj != null) {
            status.put("total", getIntegerFromMap(statusObj, "total"));
            status.put("draft", getIntegerFromMap(statusObj, "draft"));
            status.put("submitted", getIntegerFromMap(statusObj, "submitted"));
            status.put("approved", getIntegerFromMap(statusObj, "approved"));
            status.put("rejected", getIntegerFromMap(statusObj, "rejected"));
            status.put("inProgress", getIntegerFromMap(statusObj, "inProgress"));
            status.put("received", getIntegerFromMap(statusObj, "received"));
        }
        
        // 写入缓存
        redisCache.setCacheObject(CACHE_KEY_PROCUREMENT_STATUS, status, CACHE_TIME, TimeUnit.MINUTES);
        return status;
    }
    
    /**
     * 获取征用状态统计
     */
    @Override
    public Map<String, Integer> getRequisitionStatus() {
        // 先查缓存
        Map<String, Integer> cached = redisCache.getCacheObject(CACHE_KEY_REQUISITION_STATUS);
        if (cached != null) {
            return cached;
        }
        
        // 缓存未命中，查询数据库
        Map<String, Object> statusObj = dashboardMapper.countRequisitionByStatus();
        Map<String, Integer> status = new HashMap<>();
        if (statusObj != null) {
            status.put("total", getIntegerFromMap(statusObj, "total"));
            status.put("draft", getIntegerFromMap(statusObj, "draft"));
            status.put("approved", getIntegerFromMap(statusObj, "approved"));
            status.put("rejected", getIntegerFromMap(statusObj, "rejected"));
            status.put("active", getIntegerFromMap(statusObj, "active"));
            status.put("ended", getIntegerFromMap(statusObj, "ended"));
        }
        
        // 写入缓存
        redisCache.setCacheObject(CACHE_KEY_REQUISITION_STATUS, status, CACHE_TIME, TimeUnit.MINUTES);
        return status;
    }
    
    /**
     * 获取资源状态分布
     */
    @Override
    public Map<String, Map<String, Double>> getResourceDistribution() {
        // 先查缓存
        Map<String, Map<String, Double>> cached = redisCache.getCacheObject(CACHE_KEY_RESOURCE_DISTRIBUTION);
        if (cached != null) {
            return cached;
        }
        
        // 缓存未命中，从资源总览统计的缓存中获取数据（避免重复查询数据库）
        // 使用 getResourceStats() 方法，它会处理类型转换
        ResourceStatsVO stats = getResourceStats();
        
        // 从统计数据计算分布
        Map<String, Map<String, Double>> distribution = new HashMap<>();
        
        // 队伍分布
        if (stats.getTeams() != null) {
            int total = stats.getTeams().getTotal();
            if (total > 0) {
                Map<String, Double> teams = new HashMap<>();
                teams.put("available", stats.getTeams().getAvailable() * 100.0 / total);
                teams.put("busy", stats.getTeams().getBusy() * 100.0 / total);
                teams.put("offline", stats.getTeams().getOffline() * 100.0 / total);
                distribution.put("teams", teams);
            }
        }
        
        // 车辆分布
        if (stats.getVehicles() != null) {
            int total = stats.getVehicles().getTotal();
            if (total > 0) {
                Map<String, Double> vehicles = new HashMap<>();
                vehicles.put("available", stats.getVehicles().getAvailable() * 100.0 / total);
                vehicles.put("busy", stats.getVehicles().getBusy() * 100.0 / total);
                vehicles.put("repair", stats.getVehicles().getRepair() * 100.0 / total);
                distribution.put("vehicles", vehicles);
            }
        }
        
        // 装备分布
        if (stats.getEquipment() != null) {
            int total = stats.getEquipment().getTotal();
            if (total > 0) {
                Map<String, Double> equipment = new HashMap<>();
                equipment.put("available", stats.getEquipment().getAvailable() * 100.0 / total);
                equipment.put("busy", stats.getEquipment().getBusy() * 100.0 / total);
                equipment.put("repair", stats.getEquipment().getRepair() * 100.0 / total);
                equipment.put("scrap", stats.getEquipment().getScrap() * 100.0 / total);
                distribution.put("equipment", equipment);
            }
        }
        
        // 写入缓存
        redisCache.setCacheObject(CACHE_KEY_RESOURCE_DISTRIBUTION, distribution, CACHE_TIME, TimeUnit.MINUTES);
        return distribution;
    }
    
    /**
     * 获取资源使用趋势
     */
    @Override
    public UsageTrendVO getUsageTrends(Integer days) {
        if (days == null || days <= 0) {
            days = 7; // 默认7天
        }
        
        String cacheKey = CACHE_KEY_USAGE_TRENDS + ":" + days;
        
        // 先查缓存
        Object cachedObj = redisCache.getCacheObject(cacheKey);
        if (cachedObj != null) {
            // 如果已经是 UsageTrendVO 类型，直接返回
            if (cachedObj instanceof UsageTrendVO) {
                return (UsageTrendVO) cachedObj;
            }
            // 如果是 JSONObject，转换为 UsageTrendVO
            if (cachedObj instanceof JSONObject) {
                try {
                    UsageTrendVO trends = JSON.parseObject(JSON.toJSONString(cachedObj), UsageTrendVO.class);
                    return trends;
                } catch (Exception e) {
                    // 转换失败，清除缓存，重新查询
                    redisCache.deleteObject(cacheKey);
                }
            } else {
                // 其他类型，清除缓存，重新查询
                redisCache.deleteObject(cacheKey);
            }
        }
        
        // 缓存未命中，查询数据库
        UsageTrendVO trends = new UsageTrendVO();
        
        // 生成日期范围（从days天前到今天）
        List<String> dateRange = new ArrayList<>();
        List<Integer> materialConsume = new ArrayList<>();
        List<Integer> materialReturn = new ArrayList<>();
        List<Integer> equipmentAssign = new ArrayList<>();
        List<Integer> equipmentRelease = new ArrayList<>();
        
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Map<String, Integer> consumeMap = new HashMap<>();
        Map<String, Integer> returnMap = new HashMap<>();
        Map<String, Integer> assignMap = new HashMap<>();
        Map<String, Integer> releaseMap = new HashMap<>();
        
        // 查询趋势数据
        List<Map<String, Object>> consumeTrend = dashboardMapper.selectMaterialConsumeTrend(days);
        List<Map<String, Object>> returnTrend = dashboardMapper.selectMaterialReturnTrend(days);
        List<Map<String, Object>> assignTrend = dashboardMapper.selectEquipmentAssignTrend(days);
        List<Map<String, Object>> releaseTrend = dashboardMapper.selectEquipmentReleaseTrend(days);
        
        // 将查询结果转换为Map，方便按日期查找
        if (consumeTrend != null) {
            for (Map<String, Object> item : consumeTrend) {
                String date = item.get("date") != null ? item.get("date").toString() : null;
                Integer count = item.get("count") != null ? ((Number) item.get("count")).intValue() : 0;
                if (date != null) {
                    consumeMap.put(date, count);
                }
            }
        }
        if (returnTrend != null) {
            for (Map<String, Object> item : returnTrend) {
                String date = item.get("date") != null ? item.get("date").toString() : null;
                Integer count = item.get("count") != null ? ((Number) item.get("count")).intValue() : 0;
                if (date != null) {
                    returnMap.put(date, count);
                }
            }
        }
        if (assignTrend != null) {
            for (Map<String, Object> item : assignTrend) {
                String date = item.get("date") != null ? item.get("date").toString() : null;
                Integer count = item.get("count") != null ? ((Number) item.get("count")).intValue() : 0;
                if (date != null) {
                    assignMap.put(date, count);
                }
            }
        }
        if (releaseTrend != null) {
            for (Map<String, Object> item : releaseTrend) {
                String date = item.get("date") != null ? item.get("date").toString() : null;
                Integer count = item.get("count") != null ? ((Number) item.get("count")).intValue() : 0;
                if (date != null) {
                    releaseMap.put(date, count);
                }
            }
        }
        
        // 生成日期范围并填充数据（从days天前到今天）
        for (int i = days - 1; i >= 0; i--) {
            cal.setTime(new java.util.Date());
            cal.add(Calendar.DAY_OF_MONTH, -i);
            String dateStr = sdf.format(cal.getTime());
            dateRange.add(dateStr);
            
            // 填充对应日期的数据
            materialConsume.add(consumeMap.getOrDefault(dateStr, 0));
            materialReturn.add(returnMap.getOrDefault(dateStr, 0));
            equipmentAssign.add(assignMap.getOrDefault(dateStr, 0));
            equipmentRelease.add(releaseMap.getOrDefault(dateStr, 0));
        }
        
        trends.setDateRange(dateRange);
        trends.setMaterialConsume(materialConsume);
        trends.setMaterialReturn(materialReturn);
        trends.setEquipmentAssign(equipmentAssign);
        trends.setEquipmentRelease(equipmentRelease);
        
        // 写入缓存
        redisCache.setCacheObject(cacheKey, trends, CACHE_TIME, TimeUnit.MINUTES);
        return trends;
    }
    
    /**
     * 刷新看板缓存
     */
    @Override
    public void refreshDashboardCache() {
        // 直接删除已知的缓存key，避免使用keys()命令（性能问题）
        redisCache.deleteObject(CACHE_KEY_STATS);
        redisCache.deleteObject(CACHE_KEY_INVENTORY_ALERTS);
        redisCache.deleteObject(CACHE_KEY_PROCUREMENT_STATUS);
        redisCache.deleteObject(CACHE_KEY_REQUISITION_STATUS);
        redisCache.deleteObject(CACHE_KEY_RESOURCE_DISTRIBUTION);
        // 使用趋势的key包含动态参数（days），无法全部清除
        // 但影响不大，因为下次查询时会自动刷新
        // 如果需要清除所有趋势缓存，可以手动调用或使用SCAN命令（不推荐）
    }
}