package com.yida.data.device.camera.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yida.data.common.core.entity.camera.*;
import com.yida.data.common.core.entity.camera.enums.ThemeTypeEnum;
import com.yida.data.common.core.exception.FebsException;
import com.yida.data.device.camera.mapper.EduCameraMapper;
import com.yida.data.device.camera.mapper.EduCameraStrategyThemeMapper;
import com.yida.data.device.camera.service.EduCameraStrategyOpenCameraService;
import com.yida.data.device.camera.service.EduCameraStrategyOpenClassService;
import com.yida.data.device.camera.service.EduCameraStrategyOpenTimeService;
import com.yida.data.device.camera.service.EduCameraStrategyThemeService;
import com.yida.data.device.dto.camera.ThemeCameraDTO;
import com.yida.data.device.dto.camera.ThemeDeptDTO;
import com.yida.data.device.dto.camera.ThemeOpenTimeDTO;
import com.yida.data.device.dto.camera.ThemeSaveDTO;
import com.yida.data.device.vo.camera.ThemeListVO;
import com.yida.data.device.vo.camera.ThemeTagVO;
import com.yida.data.device.vo.camera.ThemeVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author ccl
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class EduCameraStrategyThemeServiceImpl extends ServiceImpl
        <EduCameraStrategyThemeMapper, EduCameraStrategyTheme> implements EduCameraStrategyThemeService {

    private final EduCameraStrategyOpenCameraService openCameraService;
    private final EduCameraStrategyOpenClassService openClassService;
    private final EduCameraStrategyOpenTimeService openTimeService;
    private final EduCameraMapper eduCameraMapper;

    @Override
    public List<ThemeTagVO> listThemeTag(Long deptId) {
        List<EduCameraStrategyTheme> themeList = list(new LambdaQueryWrapper<>(new EduCameraStrategyTheme())
                .eq(EduCameraStrategyTheme::getSchoolId, deptId));
        if (CollUtil.isEmpty(themeList)) {
            return new ArrayList<>();
        }
        return themeList.stream().map(eduCameraStrategyTheme -> {
            ThemeTagVO themeTagVO = new ThemeTagVO();
            BeanUtils.copyProperties(eduCameraStrategyTheme, themeTagVO);
            return themeTagVO;
        }).collect(Collectors.toList());
    }

    @Override
    public ThemeVO getThemeInfo(Integer themeId) {
        EduCameraStrategyTheme theme = getById(themeId);
        ThemeVO themeVO = new ThemeVO();
        BeanUtils.copyProperties(theme, themeVO);
        // 不固定查询关联区域里面的摄像头
        List<ThemeCameraDTO> cameraList = new ArrayList<>();
        // 不固定的主题有对应的摄像头信息
        if (ThemeTypeEnum.UN_FIXED_TYPE.getType().equals(theme.getThemeType())) {
            List<EduCameraStrategyOpenCamera> openCameraList = openCameraService.list(Wrappers
                    .query(new EduCameraStrategyOpenCamera()).lambda()
                    .eq(EduCameraStrategyOpenCamera::getOpenId, theme.getId()));
            cameraList = openCameraList.stream().map(camera -> {
                ThemeCameraDTO themeCameraDTO = new ThemeCameraDTO();
                themeCameraDTO.setCameraId(camera.getCameraId());
                themeCameraDTO.setCameraName(eduCameraMapper.selectById(camera.getCameraId()).getCameraName());
                return themeCameraDTO;
            }).collect(Collectors.toList());
        }
        themeVO.setCameraList(cameraList);
        // 关联可见班级
        List<EduCameraStrategyOpenClass> openClassList = openClassService.list(Wrappers.query(new EduCameraStrategyOpenClass())
                .lambda().eq(EduCameraStrategyOpenClass::getOpenId, theme.getId()));
        themeVO.setDeptList(openClassList.stream().map(openClass -> {
            ThemeDeptDTO themeDeptDTO = new ThemeDeptDTO();
            BeanUtils.copyProperties(openClass, themeDeptDTO);
            return themeDeptDTO;
        }).collect(Collectors.toList()));
        // 关联开放时间
        List<EduCameraStrategyOpenTime> openTimeList = openTimeService.list(Wrappers.query(new EduCameraStrategyOpenTime())
                .lambda().eq(EduCameraStrategyOpenTime::getOpenId, theme.getId()));
        themeVO.setOpenTimeList(openTimeList.stream().map(openTime -> {
            ThemeOpenTimeDTO themeOpenTimeDTO = new ThemeOpenTimeDTO();
            BeanUtils.copyProperties(openTime, themeOpenTimeDTO);
            return themeOpenTimeDTO;
        }).collect(Collectors.toList()));
        return themeVO;
    }

    @Override
    public List<ThemeListVO> listTheme(Long schoolId) {
        List<EduCameraStrategyTheme> themeList = list(Wrappers.query(new EduCameraStrategyTheme()).lambda().eq(EduCameraStrategyTheme::getSchoolId, schoolId));

        List<ThemeListVO> list = new ArrayList<>();
        for (EduCameraStrategyTheme theme : themeList) {
            ThemeListVO themeListVO = new ThemeListVO();
            BeanUtils.copyProperties(theme, themeListVO);

            // 不固定查询关联区域里面的摄像头
            List<ThemeCameraDTO> cameraList = new ArrayList<>();
            // 不固定的主题有对应的摄像头信息
            if (ThemeTypeEnum.UN_FIXED_TYPE.getType().equals(theme.getThemeType())) {
                List<EduCameraStrategyOpenCamera> openCameraList = openCameraService.list(Wrappers
                        .query(new EduCameraStrategyOpenCamera()).lambda()
                        .eq(EduCameraStrategyOpenCamera::getOpenId, theme.getId()));
                cameraList = openCameraList.stream().map(camera -> {
                    ThemeCameraDTO themeCameraDTO = new ThemeCameraDTO();
                    themeCameraDTO.setCameraId(camera.getCameraId());
                    themeCameraDTO.setCameraName(eduCameraMapper.selectById(camera.getCameraId()).getCameraName());
                    return themeCameraDTO;
                }).collect(Collectors.toList());
            }
            themeListVO.setCameraList(cameraList);
            // 关联可见班级
            List<EduCameraStrategyOpenClass> openClassList = openClassService.list(Wrappers.query(new EduCameraStrategyOpenClass())
                    .lambda().eq(EduCameraStrategyOpenClass::getOpenId, theme.getId()));
            themeListVO.setDeptList(openClassList.stream().map(openClass -> {
                ThemeDeptDTO themeDeptDTO = new ThemeDeptDTO();
                BeanUtils.copyProperties(openClass, themeDeptDTO);
                return themeDeptDTO;
            }).collect(Collectors.toList()));
            // 关联开放时间
            List<EduCameraStrategyOpenTime> openTimeList = openTimeService.list(Wrappers.query(new EduCameraStrategyOpenTime())
                    .lambda().eq(EduCameraStrategyOpenTime::getOpenId, theme.getId()));
            themeListVO.setOpenTimeList(openTimeList.stream().map(openTime -> {
                ThemeOpenTimeDTO themeOpenTimeDTO = new ThemeOpenTimeDTO();
                BeanUtils.copyProperties(openTime, themeOpenTimeDTO);
                return themeOpenTimeDTO;
            }).collect(Collectors.toList()));
            list.add(themeListVO);
        }
        return list;
    }


    @Override
    public Long saveOrUpdateTheme(Long schoolId, ThemeSaveDTO themeSaveDTO) {
        EduCameraStrategyTheme theme = new EduCameraStrategyTheme();
        BeanUtils.copyProperties(themeSaveDTO, theme);
        theme.setSchoolId(schoolId);
        saveOrUpdate(theme);

        // 编辑时删除附表数据
        if (Objects.nonNull(themeSaveDTO.getId())) {
            openTimeService.remove(Wrappers.query(new EduCameraStrategyOpenTime()).lambda().eq(EduCameraStrategyOpenTime::getOpenId, themeSaveDTO.getId()));
            openClassService.remove(Wrappers.query(new EduCameraStrategyOpenClass()).lambda().eq(EduCameraStrategyOpenClass::getOpenId, themeSaveDTO.getId()));
            openCameraService.remove(Wrappers.query(new EduCameraStrategyOpenCamera()).lambda().eq(EduCameraStrategyOpenCamera::getOpenId, themeSaveDTO.getId()));
        }

        // 设置设备信息
        if (CollUtil.isNotEmpty(themeSaveDTO.getCameraList())) {
            List<EduCameraStrategyOpenCamera> cameraList = new ArrayList<>();
            themeSaveDTO.getCameraList().forEach(camera -> {
                EduCameraStrategyOpenCamera openCamera = new EduCameraStrategyOpenCamera();
                openCamera.setCameraId(camera.getCameraId());
                openCamera.setOpenId(theme.getId());
                cameraList.add(openCamera);
            });
            openCameraService.saveBatch(cameraList);
        }
        // 设置开放时间信息
        if (CollUtil.isNotEmpty(themeSaveDTO.getOpenTimeList())) {
            List<EduCameraStrategyOpenTime> openTimeList = new ArrayList<>();
            themeSaveDTO.getOpenTimeList().forEach(themeOpenTimeDTO -> {
                EduCameraStrategyOpenTime openTime = new EduCameraStrategyOpenTime();
                BeanUtils.copyProperties(themeOpenTimeDTO, openTime);
                openTime.setOpenId(theme.getId());
                openTimeList.add(openTime);
            });
            openTimeService.saveBatch(openTimeList);
        }
        // 设置可见范围信息
        if (CollUtil.isNotEmpty(themeSaveDTO.getDeptList())) {
            List<EduCameraStrategyOpenClass> openClassList = new ArrayList<>();
            themeSaveDTO.getDeptList().forEach(themeDeptDTO -> {
                EduCameraStrategyOpenClass openClass = new EduCameraStrategyOpenClass();
                BeanUtils.copyProperties(themeDeptDTO, openClass);
                openClass.setOpenId(theme.getId());
                openClassList.add(openClass);
            });
            openClassService.saveBatch(openClassList);
        }
        return theme.getId();
    }

    @Override
    public void deleteTheme(Integer themeId) {
        EduCameraStrategyTheme theme = getById(themeId);
        if (Objects.isNull(theme)) {
            return;
        }
        // 判断主题类型, 固定类型不能删除
        if (ThemeTypeEnum.FIXED_TYPE.getType().equals(theme.getThemeType())) {
            throw new FebsException("当前主题无法删除");
        }
        removeById(themeId);
    }
}

