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

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yida.data.common.core.entity.CurrentUser;
import com.yida.data.common.core.entity.camera.*;
import com.yida.data.common.core.entity.telephone.EduTelephoneCard;
import com.yida.data.common.core.exception.FebsException;
import com.yida.data.common.core.utils.ExcelUtil;
import com.yida.data.common.core.utils.FebsUtil;
import com.yida.data.common.core.utils.FileUtil;
import com.yida.data.device.camera.mapper.EduCameraMapper;
import com.yida.data.device.camera.service.*;
import com.yida.data.device.dto.camera.CameraDTO;
import com.yida.data.device.dto.camera.ListCameraDTO;
import com.yida.data.device.dto.camera.ListCameraSetDTO;
import com.yida.data.device.dto.camera.ListGroupDTO;
import com.yida.data.device.vo.camera.ListCameraVO;
import com.yida.data.system.feign.RemoteDeptService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.yida.data.common.core.utils.ExcelUtil.getCellValue;

/**
 * @author ccl
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class EduCameraServiceImpl extends ServiceImpl
        <EduCameraMapper, EduCamera> implements EduCameraService {

    private final RemoteDeptService deptService;
    private final EduCameraAreaGroupCameraService cameraAreaGroupCameraService;
    private final EduCameraAuthorityTeacherService authorityTeacherService;
    private final EduCameraStrategyTransService transService;
    private final EduCameraAreaGroupService groupService;

    @Override
    public Page<ListCameraVO> listCamera(ListCameraDTO dto) {
        dto.setSchoolId(FebsUtil.getDeptId());
        return baseMapper.listCamera(dto.toPage(), dto);
    }

    @Override
    public void saveOrUpCamera(CameraDTO dto) {
        CurrentUser user = FebsUtil.getCurrentUser();
        // 判断当前学校设备名称是否重复
        LambdaQueryWrapper<EduCamera> nameWrapper = Wrappers.lambdaQuery(new EduCamera())
                .eq(EduCamera::getCameraName, dto.getCameraName())
                .eq(EduCamera::getSchoolId, user.getDeptId());
        if (Objects.nonNull(dto.getId())) {
            nameWrapper.ne(EduCamera::getId, dto.getId());
        }
        long nameCount = count(nameWrapper);
        if (nameCount >= 1) {
            throw new FebsException("当前设备名称已存在！请勿重复填写");
        }
        // 判断当前学校设备编号是否重复
        LambdaQueryWrapper<EduCamera> codeWrapper = Wrappers.lambdaQuery(new EduCamera())
                .eq(EduCamera::getCameraCode, dto.getCode())
                .eq(EduCamera::getSchoolId, user.getDeptId());
        if (Objects.nonNull(dto.getId())) {
            codeWrapper.ne(EduCamera::getId, dto.getId());
        }
        long codeCount = count(codeWrapper);
        if (codeCount >= 1) {
            throw new FebsException("当前设备编号已存在！请勿重复填写");
        }
        // 保存设备基础信息
        EduCamera camera = new EduCamera();
        BeanUtils.copyProperties(dto, camera);
        camera.setCameraCode(dto.getCode());
        camera.setSchoolId(user.getDeptId());
        saveOrUpdate(camera);

        if (ObjectUtil.isNotEmpty(dto.getId())) {
            cameraAreaGroupCameraService.remove(Wrappers.query(new EduCameraAreaGroupCamera()).lambda().eq(EduCameraAreaGroupCamera::getCameraId, dto.getId()));

        }
        EduCameraAreaGroupCamera eduCameraAreaGroupCamera = new EduCameraAreaGroupCamera();
        eduCameraAreaGroupCamera.setCameraId(camera.getId());
        eduCameraAreaGroupCamera.setClassId(dto.getDeptId());
        eduCameraAreaGroupCamera.setGroupId(dto.getAreaGroupId());
        cameraAreaGroupCameraService.save(eduCameraAreaGroupCamera);
    }

    @Override
    public void listGroup(ListGroupDTO dto) {
        List<EduCameraAreaGroupCamera> list = new ArrayList<>();
        for (Long cameraId : dto.getCameraId()) {
            EduCameraAreaGroupCamera eduCameraAreaGroupCamera = new EduCameraAreaGroupCamera();
            eduCameraAreaGroupCamera.setCameraId(cameraId);
            eduCameraAreaGroupCamera.setClassId(dto.getClassId());
            eduCameraAreaGroupCamera.setGroupId(dto.getGroupId());
            list.add(eduCameraAreaGroupCamera);
        }
        cameraAreaGroupCameraService.saveBatch(list);
    }

    /**
     * @param id 设备id
     */
    @Override
    public void removeCamera(Long id) {
        removeById(id);
        cameraAreaGroupCameraService.remove(Wrappers.query(new EduCameraAreaGroupCamera()).lambda().eq(EduCameraAreaGroupCamera::getCameraId, id));
        authorityTeacherService.remove(Wrappers.query(new EduCameraAuthorityTeacher()).lambda().eq(EduCameraAuthorityTeacher::getCameraId, id));
        transService.remove(Wrappers.query(new EduCameraStrategyTrans()).lambda().eq(EduCameraStrategyTrans::getCameraId, id));
    }

    @Override
    public void listCameraSet(ListCameraSetDTO dto) {
        List<EduCameraStrategyTrans> transList = new ArrayList<>();
        for (Long id : dto.getIds()) {
            for (EduCameraStrategyTrans tran : dto.getTrans()) {
                tran.setCameraId(id);
                transList.add(tran);
            }
        }
        transService.saveBatch(transList);
    }

    @Override
    public ListCameraVO findCamera(Long id) {
        return baseMapper.findCamera(id);
    }

    @Override
    public void downloadTemplate(HttpServletResponse response) {
        String fileName = "cameraModel.xls";
        // 获取导入文件模板
        ClassPathResource classPathResource = new ClassPathResource("template/camera/" + fileName);
        InputStream inputStream = null;
        try {
            inputStream = classPathResource.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            FileUtil.download(FileUtil.inputStreamToFile(inputStream), fileName, false, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void batchUpIcCard(String path, CurrentUser currentUser) {
        List<String> errMsg = new ArrayList<>();
        try {

            Workbook workbook = ExcelUtil.readExcel(new FileInputStream(path), "xls");
            List<EduTelephoneCard> list = new ArrayList<>();
            List<Map<Integer, Cell>> mapList = ExcelUtil.readData(workbook.getSheetAt(0), 1);
            int rowNum = 0;

            Sheet sheet = workbook.getSheet("Sheet1");

            for (Map<Integer, Cell> cellMap : mapList) {
                rowNum++;

                //读取cell
                EduCamera camera = new EduCamera();
                camera.setSchoolId(currentUser.getDeptId());
                camera.setCameraCode(getCellValue(cellMap.get(0)));

                EduCamera one = getOne(Wrappers.query(new EduCamera()).lambda().eq(EduCamera::getCameraCode, getCellValue(cellMap.get(0))));
                if (ObjectUtil.isNotEmpty(one)){
                    continue;
                }
                //波流地址
                camera.setTransUrl(getCellValue(cellMap.get(1)));
                camera.setOpenStatus(Integer.parseInt(getCellValue(cellMap.get(3))));
                camera.setRunStatus(Integer.parseInt(getCellValue(cellMap.get(4))));
                camera.setRemarks(getCellValue(cellMap.get(5)));
                save(camera);

                String groupName = getCellValue(cellMap.get(2));
                EduCameraAreaGroup group = groupService.getOne(Wrappers.query(new EduCameraAreaGroup()).lambda().eq(EduCameraAreaGroup::getName, groupName));

                if (ObjectUtil.isEmpty(group)){
                    errMsg.add(String.format("第%d行:[%s]学生不存在", rowNum, groupName));
                    continue;
                }
                EduCameraAreaGroupCamera groupCamera = new EduCameraAreaGroupCamera();
                groupCamera.setGroupId(group.getId());
                groupCamera.setCameraId(camera.getId());
                cameraAreaGroupCameraService.save(groupCamera);

                //空说明最后一行，跳出循环
                if (StringUtils.isEmpty(getCellValue(cellMap.get(6)))) {
                    break;
                }
            }
        } catch (Exception e) {
            log.error("错误", e);
        }
    }
}
