package com.kym.service.admin.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.github.pagehelper.PageHelper;
import com.kym.common.cache.PlatformCache;
import com.kym.common.utils.CommUtil;
import com.kym.entity.admin.ConnectorInfo;
import com.kym.entity.admin.EquipmentInfo;
import com.kym.entity.admin.queryParams.EquipmentQueryParam;
import com.kym.entity.admin.vo.ConnectorInfoVo;
import com.kym.entity.common.PageBean;
import com.kym.entity.miniapp.ChargeOrder;
import com.kym.mapper.admin.ConnectorInfoMapper;
import com.kym.service.admin.ConnectorInfoService;
import com.kym.service.cache.KymCache;
import com.kym.service.miniapp.ChargeOrderService;
import com.kym.service.mybatisplus.MyBaseServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Map;
import java.util.stream.Collectors;

import static com.baomidou.mybatisplus.core.toolkit.ObjectUtils.isNotNull;

/**
 * <p>
 * 充电桩接口（枪）信息 服务实现类
 * </p>
 *
 * @author skyline
 * @since 2023-08-05
 */
@Service
@DS("db-admin")
public class ConnectorInfoServiceImpl extends MyBaseServiceImpl<ConnectorInfoMapper, ConnectorInfo> implements ConnectorInfoService {

    private final ChargeOrderService chargeOrderService;

    public ConnectorInfoServiceImpl(ChargeOrderService chargeOrderService) {
        this.chargeOrderService = chargeOrderService;
    }

    @Override
    public PageBean<ConnectorInfoVo> listConnectors(EquipmentQueryParam params) {
        // 判断数据权限
        var adminStationIds = KymCache.INSTANCE.getAdminUserStationIds(StpUtil.getLoginIdAsLong());
        if (params.getStationId() == null && KymCache.INSTANCE.getAdminUserStationIds(StpUtil.getLoginIdAsLong()) != null) {
            params.setStationId(adminStationIds.get(0));
        }
        PageHelper.startPage(params.getPageNum(), params.getPageSize());
        var connectorInfos = lambdaQuery()
                .eq(CommUtil.isNotEmptyAndNull(params.getEquipmentId()), ConnectorInfo::getConnectorId,
                        CommUtil.isNotEmptyAndNull(params.getEquipmentId()) ? KymCache.INSTANCE.getConnectorId(params.getEquipmentId()) : null)
                .eq(CommUtil.isNotEmptyAndNull(params.getStationId()), ConnectorInfo::getStationId, params.getStationId())
                .eq(CommUtil.isNotEmptyAndNull(params.getStatus()), ConnectorInfo::getStatus, params.getStatus())
                .list();
        var pageBean = new PageBean<>(connectorInfos);
        // 转换成vo
        var connectorInfoVos = new ArrayList<>(connectorInfos.parallelStream()
                .map(item -> {
                            var vo = new ConnectorInfoVo();
                            BeanUtils.copyProperties(item, vo);
                            vo.setPlatformName(PlatformCache.INSTANCE.getPlatformNameByConnectorId(vo.getConnectorId()));
                            return vo;
                        }
                ).toList());
        var page = new PageBean<>(connectorInfoVos);
        BeanUtils.copyProperties(pageBean, page);
        // parallelStream 这里可能有坑，注意检查
        var res = connectorInfoVos.parallelStream().map(item ->
                item.setShortId(KymCache.INSTANCE.getShortIdByEquipmentIdOrConnectorId(item.getConnectorId()))
                        .setStationName(KymCache.INSTANCE.getStationNameById(item.getStationId()))
                        .setParkingNo(KymCache.INSTANCE.getParkNoByEquipmentIdOrConnectorId(item.getConnectorId()))
        ).sorted(Comparator.comparing(ConnectorInfoVo::getShortId)).toList();
        page.setList(res);
        return page;
    }

    @Override
    public Map<Integer, Long> statConnectorStatus(String stationId) {
        if (CommUtil.null2Long(stationId) <= 0) {
            // 判断数据权限
            stationId = CommUtil.isEmptyOrNull(KymCache.INSTANCE.getAdminUserStationIds(StpUtil.getLoginIdAsLong())) ? null : KymCache.INSTANCE.getAdminUserStationIds(StpUtil.getLoginIdAsLong()).get(0);
        }
        // 获取指定站点下的充电桩
        var connectorInfos = lambdaQuery().eq(isNotNull(stationId), ConnectorInfo::getStationId, stationId).list();
        // 根据状态进行分组

        // 预约中的设备
        // 手动切换数据源
        DynamicDataSourceContextHolder.push("db-miniapp");
        // 查询预约中的订单，按照站点id分组并对connectorId去重计数
        var orderInfos = chargeOrderService.lambdaQuery()
                .select(ChargeOrder::getConnectorId)
                .eq(ChargeOrder::getStationId, stationId)
                .eq(ChargeOrder::getChargeStatus, ChargeOrder.CHARGE_STATUS_预约中)
                .list().stream().filter(CommUtil.distinctByKey(ChargeOrder::getConnectorId)).count();

        DynamicDataSourceContextHolder.poll();
        var res = connectorInfos.stream().collect(Collectors.groupingBy(ConnectorInfo::getStatus, Collectors.counting()));
        res.put(EquipmentInfo.SERVICE_STATUS_已连接, res.getOrDefault(EquipmentInfo.SERVICE_STATUS_已连接, 0L) - orderInfos);
        res.put(EquipmentInfo.SERVICE_STATUS_预约中, orderInfos);
        return res;
    }

}
