package com.zsElectric.boot.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zsElectric.boot.business.mapper.BannerInfoMapper;
import com.zsElectric.boot.business.mapper.ThirdPartyStationInfoMapper;
import com.zsElectric.boot.business.mapper.UserFirmMapper;
import com.zsElectric.boot.charging.entity.ThirdPartyConnectorInfo;
import com.zsElectric.boot.charging.entity.ThirdPartyEquipmentInfo;
import com.zsElectric.boot.charging.mapper.ThirdPartyConnectorInfoMapper;
import com.zsElectric.boot.charging.entity.ThirdPartyEquipmentPricePolicy;
import com.zsElectric.boot.charging.entity.ThirdPartyPolicyInfo;
import com.zsElectric.boot.charging.entity.ThirdPartyStationInfo;
import com.zsElectric.boot.business.mapper.ThirdPartyEquipmentInfoMapper;
import com.zsElectric.boot.charging.mapper.ThirdPartyEquipmentPricePolicyMapper;
import com.zsElectric.boot.charging.mapper.ThirdPartyPolicyInfoMapper;
import com.zsElectric.boot.business.model.entity.BannerInfo;
import com.zsElectric.boot.business.model.entity.UserFirm;
import com.zsElectric.boot.business.model.query.StationInfoQuery;
import com.zsElectric.boot.business.model.vo.AppletConnectorListVO;
import com.zsElectric.boot.business.model.vo.AppletStationDetailVO;
import com.zsElectric.boot.business.model.vo.AppletStationPriceListVO;
import com.zsElectric.boot.business.model.vo.BannerInfoVO;
import com.zsElectric.boot.business.model.vo.StationInfoMapVO;
import com.zsElectric.boot.business.model.vo.StationInfoVO;
import com.zsElectric.boot.business.service.AppletHomeService;
import com.zsElectric.boot.business.converter.BannerInfoConverter;
import com.zsElectric.boot.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class AppletHomeServiceImpl implements AppletHomeService {

    private final ThirdPartyStationInfoMapper thirdPartyStationInfoMapper;
    private final UserFirmMapper userFirmMapper;
    private final BannerInfoMapper bannerInfoMapper;
    private final BannerInfoConverter bannerInfoConverter;
    private final ThirdPartyConnectorInfoMapper thirdPartyConnectorInfoMapper;
    private final ThirdPartyEquipmentInfoMapper thirdPartyEquipmentInfoMapper;
    private final ThirdPartyEquipmentPricePolicyMapper thirdPartyEquipmentPricePolicyMapper;
    private final ThirdPartyPolicyInfoMapper thirdPartyPolicyInfoMapper;

    /**
     * 时间格式化器 HHmmss
     */
    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HHmmss");

    @Override
    public IPage<StationInfoVO> getStationInfoPage(StationInfoQuery queryParams) {
        
        // 查询用户是否为企业用户，获取企业ID
        Long firmId = null;
        boolean isFirmUser = false;
        if (queryParams.getUserId() != null) {
            UserFirm userFirm = userFirmMapper.selectOne(
                    new LambdaQueryWrapper<UserFirm>()
                            .eq(UserFirm::getUserId, queryParams.getUserId())
                            .last("LIMIT 1")
            );
            if (userFirm != null) {
                firmId = userFirm.getFirmId();
                isFirmUser = true;
            }
        }
        
        // 获取当前时间(HHmmss格式)
        String currentTime = LocalTime.now().format(TIME_FORMATTER);
        
        // 构建分页对象
        Page<StationInfoVO> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize());
        
        // 执行查询
        IPage<StationInfoVO> resultPage = thirdPartyStationInfoMapper.selectAppletStationInfoPage(
                page, queryParams, currentTime, firmId
        );
        
        // 设置是否企业用户标识
        final boolean finalIsFirmUser = isFirmUser;
        resultPage.getRecords().forEach(vo -> vo.setFirmUser(finalIsFirmUser));
        
        return resultPage;
    }

    @Override
    public List<StationInfoMapVO> getStationInfoMapList(BigDecimal longitude, BigDecimal latitude) {
        // 获取当前时间(HHmmss格式)
        String currentTime = LocalTime.now().format(TIME_FORMATTER);
        
        // 查询站点列表（按距离排序）
        return thirdPartyStationInfoMapper.selectStationMapList(
                longitude, latitude, currentTime
        );
    }

    @Override
    public List<BannerInfoVO> getBannerList() {
        // 查询启用状态的Banner，按排序字段降序
        List<BannerInfo> bannerList = bannerInfoMapper.selectList(
                new LambdaQueryWrapper<BannerInfo>()
                        .eq(BannerInfo::getStatus, 1)
                        .orderByDesc(BannerInfo::getSort)
        );
        return bannerInfoConverter.toVO(bannerList);
    }

    @Override
    public AppletStationDetailVO getStationDetail(Long stationId, BigDecimal longitude, BigDecimal latitude) {
        // 获取当前登录用户ID
        Long userId = SecurityUtils.getUserId();
        
        // 查询用户是否为企业用户，获取企业ID
        Long firmId = null;
        boolean isFirmUser = false;
        if (userId != null) {
            UserFirm userFirm = userFirmMapper.selectOne(
                    new LambdaQueryWrapper<UserFirm>()
                            .eq(UserFirm::getUserId, userId)
                            .last("LIMIT 1")
            );
            if (userFirm != null) {
                firmId = userFirm.getFirmId();
                isFirmUser = true;
            }
        }
        
        // 获取当前时间(HHmmss格式)
        String currentTime = LocalTime.now().format(TIME_FORMATTER);
        
        // 查询站点详情基本信息
        AppletStationDetailVO result = thirdPartyStationInfoMapper.selectStationDetail(
                stationId, longitude, latitude, currentTime, firmId
        );
        
        if (result == null) {
            return null;
        }
        
        // 设置是否企业用户
        result.setFirmUser(isFirmUser);
        
        // 计算预计省多少(当前价 - 原价，如果为负则取绝对值)
        if (result.getCurrentPrice() != null && result.getOriginalPrice() != null) {
            BigDecimal saving = result.getOriginalPrice().subtract(result.getCurrentPrice());
            result.setEstimatedSaving(saving.compareTo(BigDecimal.ZERO) > 0 ? saving : BigDecimal.ZERO);
            result.setShowSpecialPriceTag(saving.compareTo(BigDecimal.ZERO) > 0);
        }
        
        // 查询站点对应的stationId
        ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectById(stationId);
        if (stationInfo == null) {
            return result;
        }
        
        // 根据站点stationId查询设备列表（third_party_equipment_info）
        List<ThirdPartyEquipmentInfo> equipmentList = thirdPartyEquipmentInfoMapper.selectList(
                new LambdaQueryWrapper<ThirdPartyEquipmentInfo>()
                        .eq(ThirdPartyEquipmentInfo::getStationId, stationInfo.getStationId())
        );
        
        // 构建设备ID到设备类型的映射
        Map<String, Integer> equipmentTypeMap = equipmentList.stream()
                .collect(Collectors.toMap(
                        ThirdPartyEquipmentInfo::getEquipmentId,
                        e -> e.getEquipmentType() != null ? e.getEquipmentType() : 0,
                        (v1, v2) -> v1
                ));
        
        // 根据设备列表的equipmentId查询充电接口信息（third_party_connector_info）
        List<ThirdPartyConnectorInfo> connectorList = new ArrayList<>();
        if (!equipmentList.isEmpty()) {
            List<String> equipmentIds = equipmentList.stream()
                    .map(ThirdPartyEquipmentInfo::getEquipmentId)
                    .collect(Collectors.toList());
            connectorList = thirdPartyConnectorInfoMapper.selectList(
                    new LambdaQueryWrapper<ThirdPartyConnectorInfo>()
                            .in(ThirdPartyConnectorInfo::getEquipmentId, equipmentIds)
            );
        }
        
        // 统计终端状态
        int idleCount = 0;
        int occupiedCount = 0;
        int offlineCount = 0;
        
        List<AppletStationDetailVO.ConnectorInfoVO> connectorVOList = new ArrayList<>();
        for (ThirdPartyConnectorInfo connector : connectorList) {
            AppletStationDetailVO.ConnectorInfoVO vo = new AppletStationDetailVO.ConnectorInfoVO();
            vo.setConnectorId(connector.getId());
            vo.setConnectorName(connector.getConnectorName());
            vo.setConnectorCode(connector.getConnectorId());
            
            // 设备分类：从设备表获取设备类型（1-直流设备,2-交流设备,3-交直流一体设备,4-无线设备,5-其他）
            Integer equipmentType = equipmentTypeMap.get(connector.getEquipmentId());
            if (equipmentType != null) {
                switch (equipmentType) {
                    case 1:
                        vo.setEquipmentType("直流设备");
                        break;
                    case 2:
                        vo.setEquipmentType("交流设备");
                        break;
                    case 3:
                        vo.setEquipmentType("交直流一体设备");
                        break;
                    case 4:
                        vo.setEquipmentType("无线设备");
                        break;
                    case 5:
                        vo.setEquipmentType("其他");
                        break;
                    default:
                        vo.setEquipmentType("未知");
                }
            }
            
            // 从充电接口表获取实际状态
            // 0-离网,1-空闲,2-占用(未充电),3-占用(充电中),4-占用(预约锁定),255-故障
            Integer connectorStatus = connector.getStatus();
            if (connectorStatus == null) {
                // 默认为离网
                connectorStatus = 0;
            }
            vo.setStatus(connectorStatus);
            
            // 设置状态名称并统计
            switch (connectorStatus) {
                case 0:
                    vo.setStatusName("离网");
                    offlineCount++;
                    break;
                case 1:
                    vo.setStatusName("空闲");
                    idleCount++;
                    break;
                case 2:
                    vo.setStatusName("占用(未充电)");
                    occupiedCount++;
                    break;
                case 3:
                    vo.setStatusName("占用(充电中)");
                    occupiedCount++;
                    break;
                case 4:
                    vo.setStatusName("占用(预约锁定)");
                    occupiedCount++;
                    break;
                case 255:
                    vo.setStatusName("故障");
                    offlineCount++;
                    break;
                default:
                    vo.setStatusName("未知");
                    offlineCount++;
            }
            
            connectorVOList.add(vo);
        }
        
        result.setConnectorList(connectorVOList);
        result.setIdleCount(idleCount);
        result.setOccupiedCount(occupiedCount);
        result.setOfflineCount(offlineCount);
        
        return result;
    }

    @Override
    public AppletConnectorListVO getConnectorList(Long stationId) {
        // 查询站点信息
        ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectById(stationId);
        if (stationInfo == null) {
            return null;
        }
        
        AppletConnectorListVO result = new AppletConnectorListVO();
        result.setStationId(stationId);
        result.setStationName(stationInfo.getStationName());
        
        // 根据站点stationId查询设备列表
        List<ThirdPartyEquipmentInfo> equipmentList = thirdPartyEquipmentInfoMapper.selectList(
                new LambdaQueryWrapper<ThirdPartyEquipmentInfo>()
                        .eq(ThirdPartyEquipmentInfo::getStationId, stationInfo.getStationId())
        );
        
        // 构建设备ID到设备类型的映射
        Map<String, Integer> equipmentTypeMap = equipmentList.stream()
                .collect(Collectors.toMap(
                        ThirdPartyEquipmentInfo::getEquipmentId,
                        e -> e.getEquipmentType() != null ? e.getEquipmentType() : 0,
                        (v1, v2) -> v1
                ));
        
        // 查询充电接口信息
        List<ThirdPartyConnectorInfo> connectorList = new ArrayList<>();
        if (!equipmentList.isEmpty()) {
            List<String> equipmentIds = equipmentList.stream()
                    .map(ThirdPartyEquipmentInfo::getEquipmentId)
                    .collect(Collectors.toList());
            connectorList = thirdPartyConnectorInfoMapper.selectList(
                    new LambdaQueryWrapper<ThirdPartyConnectorInfo>()
                            .in(ThirdPartyConnectorInfo::getEquipmentId, equipmentIds)
            );
        }
        
        // 统计终端状态
        int idleCount = 0;
        int occupiedCount = 0;
        int offlineCount = 0;
        
        List<AppletConnectorListVO.ConnectorItemVO> connectorVOList = new ArrayList<>();
        for (ThirdPartyConnectorInfo connector : connectorList) {
            AppletConnectorListVO.ConnectorItemVO vo = new AppletConnectorListVO.ConnectorItemVO();
            vo.setConnectorId(connector.getId());
            vo.setConnectorName(connector.getConnectorName());
            vo.setConnectorCode(connector.getConnectorId());
            
            // 设备分类
            Integer equipmentType = equipmentTypeMap.get(connector.getEquipmentId());
            vo.setEquipmentType(getEquipmentTypeName(equipmentType));
            
            // 状态处理
            Integer connectorStatus = connector.getStatus();
            if (connectorStatus == null) {
                connectorStatus = 0;
            }
            vo.setStatus(connectorStatus);
            vo.setStatusName(getStatusName(connectorStatus));
            
            // 统计
            switch (connectorStatus) {
                case 1:
                    idleCount++;
                    break;
                case 2:
                case 3:
                case 4:
                    occupiedCount++;
                    break;
                default:
                    offlineCount++;
            }
            
            connectorVOList.add(vo);
        }
        
        result.setConnectorList(connectorVOList);
        result.setIdleCount(idleCount);
        result.setOccupiedCount(occupiedCount);
        result.setOfflineCount(offlineCount);
        
        return result;
    }

    @Override
    public AppletStationPriceListVO getStationPriceList(Long stationId) {
        // 查询站点信息
        ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectById(stationId);
        if (stationInfo == null) {
            return null;
        }
        
        AppletStationPriceListVO result = new AppletStationPriceListVO();
        result.setStationId(stationId);
        result.setStationName(stationInfo.getStationName());
        
        // 获取当前时间(HHmmss格式)
        String currentTime = LocalTime.now().format(TIME_FORMATTER);
        
        // 查询站点对应的价格策略
        // 1. 先查询充电接口
        ThirdPartyConnectorInfo connector = thirdPartyConnectorInfoMapper.selectOne(
                new LambdaQueryWrapper<ThirdPartyConnectorInfo>()
                        .eq(ThirdPartyConnectorInfo::getStationId, stationInfo.getStationId())
                        .last("LIMIT 1")
        );
        
        if (connector == null) {
            result.setPriceList(new ArrayList<>());
            return result;
        }
        
        // 2. 查询价格策略
        ThirdPartyEquipmentPricePolicy pricePolicy = thirdPartyEquipmentPricePolicyMapper.selectOne(
                new LambdaQueryWrapper<ThirdPartyEquipmentPricePolicy>()
                        .eq(ThirdPartyEquipmentPricePolicy::getConnectorId, connector.getConnectorId())
                        .eq(ThirdPartyEquipmentPricePolicy::getIsDeleted, 0)
                        .last("LIMIT 1")
        );
        
        if (pricePolicy == null) {
            result.setPriceList(new ArrayList<>());
            return result;
        }
        
        // 3. 查询价格明细列表
        List<ThirdPartyPolicyInfo> policyInfoList = thirdPartyPolicyInfoMapper.selectList(
                new LambdaQueryWrapper<ThirdPartyPolicyInfo>()
                        .eq(ThirdPartyPolicyInfo::getPricePolicyId, pricePolicy.getId())
                        .eq(ThirdPartyPolicyInfo::getIsDeleted, 0)
                        .orderByAsc(ThirdPartyPolicyInfo::getStartTime)
        );
        
        // 4. 构建价格列表
        List<AppletStationPriceListVO.PriceItemVO> priceList = new ArrayList<>();
        for (int i = 0; i < policyInfoList.size(); i++) {
            ThirdPartyPolicyInfo policyInfo = policyInfoList.get(i);
            AppletStationPriceListVO.PriceItemVO priceItem = new AppletStationPriceListVO.PriceItemVO();
            
            // 时段格式化：HHmmss -> HH:mm
            String startTime = formatTime(policyInfo.getStartTime());
            // 下一个时段的开始时间作为当前时段的结束时间
            String endTime = (i + 1 < policyInfoList.size()) 
                    ? formatTime(policyInfoList.get(i + 1).getStartTime()) 
                    : "24:00";
            priceItem.setTimePeriod(startTime + "-" + endTime);
            
            priceItem.setPeriodFlag(policyInfo.getPeriodFlag());
            priceItem.setPeriodFlagName(getPeriodFlagName(policyInfo.getPeriodFlag()));
            priceItem.setElecPrice(policyInfo.getElecPrice());
            priceItem.setServicePrice(policyInfo.getServicePrice());
            
            // 合计充电价 = 电费 + 服务费
            BigDecimal elecPrice = policyInfo.getElecPrice() != null ? policyInfo.getElecPrice() : BigDecimal.ZERO;
            BigDecimal servicePrice = policyInfo.getServicePrice() != null ? policyInfo.getServicePrice() : BigDecimal.ZERO;
            priceItem.setTotalPrice(elecPrice.add(servicePrice));
            
            // 判断是否为当前时段
            priceItem.setCurrentPeriod(isCurrentPeriod(policyInfo.getStartTime(), 
                    (i + 1 < policyInfoList.size()) ? policyInfoList.get(i + 1).getStartTime() : null, 
                    currentTime));
            
            priceList.add(priceItem);
        }
        
        result.setPriceList(priceList);
        return result;
    }
    
    /**
     * 获取设备类型名称
     */
    private String getEquipmentTypeName(Integer equipmentType) {
        if (equipmentType == null) {
            return "未知";
        }
        switch (equipmentType) {
            case 1:
                return "直流设备";
            case 2:
                return "交流设备";
            case 3:
                return "交直流一体设备";
            case 4:
                return "无线设备";
            case 5:
                return "其他";
            default:
                return "未知";
        }
    }
    
    /**
     * 获取状态名称
     */
    private String getStatusName(Integer status) {
        if (status == null) {
            return "未知";
        }
        switch (status) {
            case 0:
                return "离网";
            case 1:
                return "空闲";
            case 2:
                return "占用(未充电)";
            case 3:
                return "占用(充电中)";
            case 4:
                return "占用(预约锁定)";
            case 255:
                return "故障";
            default:
                return "未知";
        }
    }
    
    /**
     * 获取时段标志名称
     */
    private String getPeriodFlagName(Integer periodFlag) {
        if (periodFlag == null) {
            return "";
        }
        switch (periodFlag) {
            case 1:
                return "尖";
            case 2:
                return "峰";
            case 3:
                return "平";
            case 4:
                return "谷";
            default:
                return "";
        }
    }
    
    /**
     * 格式化时间 HHmmss -> HH:mm
     */
    private String formatTime(String time) {
        if (time == null || time.length() < 4) {
            return "00:00";
        }
        return time.substring(0, 2) + ":" + time.substring(2, 4);
    }
    
    /**
     * 判断是否为当前时段
     */
    private boolean isCurrentPeriod(String startTime, String nextStartTime, String currentTime) {
        if (startTime == null || currentTime == null) {
            return false;
        }
        // 当前时间 >= 开始时间 且 当前时间 < 下一个时段开始时间
        if (currentTime.compareTo(startTime) >= 0) {
            if (nextStartTime == null || currentTime.compareTo(nextStartTime) < 0) {
                return true;
            }
        }
        return false;
    }
}
