package com.usky.sas.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.usky.sas.domain.*;
import com.usky.sas.enums.SystemTypeCodeEnum;
import com.usky.sas.mapper.*;
import com.usky.sas.service.SasEventCodeService;
import com.usky.sas.service.vo.EventCodeInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 根据系统类型编码返回对应事件编码/子类型列表
 */
@Slf4j
@Service
public class SasEventCodeServiceImpl implements SasEventCodeService {

    @Autowired
    private SasAcquisitionEventCodeMapper acquisitionEventCodeMapper;
    @Autowired
    private SasAlarsasEventCodeMapper alarsasEventCodeMapper;
    @Autowired
    private SasCollectionEventCodeMapper collectionEventCodeMapper;
    @Autowired
    private SasEntranceEventCodeMapper entranceEventCodeMapper;
    @Autowired
    private SasParkingEventCodeMapper parkingEventCodeMapper;
    @Autowired
    private SasPatrolEventCodeMapper patrolEventCodeMapper;
    @Autowired
    private SasPerceptionEventCodeMapper perceptionEventCodeMapper;
    @Autowired
    private SasRoadblockEventCodeMapper roadblockEventCodeMapper;
    @Autowired
    private SasSnapTypeCodeMapper snapTypeCodeMapper;
    @Autowired
    private SasUsbEventCodeMapper usbEventCodeMapper;
    @Autowired
    private SasVideoEventCodeMapper videoEventCodeMapper;
    @Autowired
    private SasGauthCertificationMapper gauthCertificationMapper;

    @Override
    public List<EventCodeInfo> getEventCodes(Integer code) {
        log.debug("请求参数：code={}", code);
        if (code == null) {
            return null;
        }
        SystemTypeCodeEnum type = SystemTypeCodeEnum.getByCode(code);
        if (type == null) {
            return null;
        }
        List<?> list = listByType(type, null);
        if (list == null) {
            return null;
        }
        if (type == SystemTypeCodeEnum.gauth) {
            return gauthToEventCodeInfo(list);
        }
        return toEventCodeInfoList(list);
    }

    @Override
    public List<EventCodeInfo> getEventCodesByIds(Integer systemTypeCode, List<Integer> ids) {
        if (systemTypeCode == null || ids == null || ids.isEmpty()) {
            return Collections.emptyList();
        }
        SystemTypeCodeEnum type = SystemTypeCodeEnum.getByCode(systemTypeCode);
        if (type == null) {
            return Collections.emptyList();
        }
        List<?> list = listByType(type, ids);
        if (list == null || list.isEmpty()) {
            return Collections.emptyList();
        }
        if (type == SystemTypeCodeEnum.gauth) {
            return gauthToEventCodeInfo(list);
        }
        return toEventCodeInfoList(list);
    }

    /**
     * 按系统类型查询事件编码：ids 为 null 时查全部，否则按 id 列表查
     */
    private List<?> listByType(SystemTypeCodeEnum type, List<Integer> ids) {
        if (ids == null || ids.isEmpty()) {
            switch (type) {
                case acquisition:
                    return acquisitionEventCodeMapper.selectList(Wrappers.emptyWrapper());
                case alarm:
                    return alarsasEventCodeMapper.selectList(Wrappers.emptyWrapper());
                case roadblock:
                    return roadblockEventCodeMapper.selectList(Wrappers.emptyWrapper());
                case perception:
                    return perceptionEventCodeMapper.selectList(Wrappers.emptyWrapper());
                case patrol:
                    return patrolEventCodeMapper.selectList(Wrappers.emptyWrapper());
                case usbalarm:
                    return usbEventCodeMapper.selectList(Wrappers.emptyWrapper());
                case collection:
                    return collectionEventCodeMapper.selectList(Wrappers.emptyWrapper());
                case entrance:
                    return entranceEventCodeMapper.selectList(Wrappers.emptyWrapper());
                case video:
                    return videoEventCodeMapper.selectList(Wrappers.emptyWrapper());
                case snap:
                    return snapTypeCodeMapper.selectList(Wrappers.emptyWrapper());
                case parking:
                    return parkingEventCodeMapper.selectList(Wrappers.emptyWrapper());
                case gauth:
                    return gauthCertificationMapper.selectList(Wrappers.emptyWrapper());
                default:
                    return null;
            }
        }
        switch (type) {
            case acquisition:
                return acquisitionEventCodeMapper.selectBatchIds(ids);
            case alarm:
                return alarsasEventCodeMapper.selectBatchIds(ids);
            case roadblock:
                return roadblockEventCodeMapper.selectBatchIds(ids);
            case perception:
                return perceptionEventCodeMapper.selectBatchIds(ids);
            case patrol:
                return patrolEventCodeMapper.selectBatchIds(ids);
            case usbalarm:
                return usbEventCodeMapper.selectBatchIds(ids);
            case collection:
                return collectionEventCodeMapper.selectBatchIds(ids);
            case entrance:
                return entranceEventCodeMapper.selectBatchIds(ids);
            case video:
                return videoEventCodeMapper.selectBatchIds(ids);
            case snap:
                return snapTypeCodeMapper.selectBatchIds(ids);
            case parking:
                return parkingEventCodeMapper.selectBatchIds(ids);
            case gauth:
                return gauthCertificationMapper.selectBatchIds(ids);
            default:
                return Collections.emptyList();
        }
    }

    private List<EventCodeInfo> gauthToEventCodeInfo(List<?> list) {
        if (list == null) {
            return Collections.emptyList();
        }
        return list.stream().map(g -> {
            SasGauthCertification cert = (SasGauthCertification) g;
            EventCodeInfo info = new EventCodeInfo();
            info.setCode(cert.getFunctions());
            info.setName(cert.getName() != null ? cert.getName() : cert.getActionName());
            return info;
        }).collect(Collectors.toList());
    }

    private List<EventCodeInfo> toEventCodeInfoList(List<?> list) {
        if (list == null) {
            return Collections.emptyList();
        }
        return list.stream()
                .map(entity -> BeanUtil.toBean(entity, EventCodeInfo.class))
                .collect(Collectors.toList());
    }
}
