package com.sz.admin.monitor.service.impl;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.sz.admin.monitor.mapper.EdgeBoxMapper;
import com.sz.admin.monitor.mapper.FaceImageMapper;
import com.sz.admin.monitor.mapper.FaceInfoMapper;
import com.sz.admin.monitor.mapper.FaceLibraryMapper;
import com.sz.admin.monitor.pojo.dto.faceinfo.FaceInfoListDTO;
import com.sz.admin.monitor.pojo.dto.facelibrary.FaceLibraryCreateDTO;
import com.sz.admin.monitor.pojo.dto.facelibrary.FaceLibraryImportDTO;
import com.sz.admin.monitor.pojo.dto.facelibrary.FaceLibraryListDTO;
import com.sz.admin.monitor.pojo.dto.facelibrary.FaceLibraryUpdateDTO;
import com.sz.admin.monitor.pojo.po.EdgeBox;
import com.sz.admin.monitor.pojo.po.FaceInfo;
import com.sz.admin.monitor.pojo.po.FaceLibrary;
import com.sz.admin.monitor.pojo.vo.faceinfo.FaceInfoVO;
import com.sz.admin.monitor.pojo.vo.facelibrary.FaceLibraryVO;
import com.sz.admin.monitor.service.FaceInfoService;
import com.sz.admin.monitor.service.FaceLibraryService;
import com.sz.admin.monitor.utils.AiBoxRequestUtil;
import com.sz.admin.monitor.utils.AlgMediaConfigResponse;
import com.sz.core.common.entity.ImportExcelDTO;
import com.sz.core.common.entity.PageResult;
import com.sz.core.common.entity.SelectIdsDTO;
import com.sz.core.common.enums.CommonResponseEnum;
import com.sz.core.common.exception.common.BusinessException;
import com.sz.core.datascope.SimpleDataScopeHelper;
import com.sz.core.util.BeanCopyUtils;
import com.sz.core.util.FileUtils;
import com.sz.core.util.PageUtils;
import com.sz.core.util.Utils;
import com.sz.excel.core.ExcelResult;
import com.sz.excel.utils.ExcelUtils;
import com.sz.platform.enums.AdminResponseEnum;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.OutputStream;
import java.io.Serializable;
import java.util.List;

/**
 * ClassName: FaceLibraryServiceImpl
 * Package: com.sz.admin.monitor.service.impl
 * Description:
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class FaceLibraryServiceImpl extends ServiceImpl<FaceLibraryMapper, FaceLibrary> implements FaceLibraryService {
    private final FaceInfoService faceInfoService;
    private final AiBoxRequestUtil aiBoxRequestUtil;
    private final EdgeBoxMapper edgeBoxMapper;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(FaceLibraryCreateDTO dto){
        EdgeBox edgeBox = edgeBoxMapper.selectOneById(dto.getBoxId());
        if (edgeBox == null) {
            throw new BusinessException(AdminResponseEnum.OPERATION_FAIL, null, "盒子不存在");
        }
        AlgMediaConfigResponse response = aiBoxRequestUtil.createFaceLibrary(edgeBox.getIp(),
            edgeBox.getPort(),
            dto.getName());
        Integer albumId = response.getAlbumId();
        // 创建人脸库
        FaceLibrary ryFaceLibrary = BeanCopyUtils.copy(dto, FaceLibrary.class);
        ryFaceLibrary.setAlbumId(albumId);
        try {
            // 保存数据到数据库
            save(ryFaceLibrary);
        }catch (Exception e)
        {
            // 如果保存失败，则删除盒子新建的人脸库
            aiBoxRequestUtil.deleteFaceLibrary(edgeBox.getIp(),
                edgeBox.getPort(), dto.getName());
            throw e;
        }
    }

    @Override
    public void update(FaceLibraryUpdateDTO dto){
        FaceLibrary ryFaceLibrary = BeanCopyUtils.copy(dto, FaceLibrary.class);
        QueryWrapper wrapper;
        // id有效性校验
        wrapper = QueryWrapper.create()
            .eq(FaceLibrary::getId, dto.getId());
        CommonResponseEnum.INVALID_ID.assertTrue(count(wrapper) <= 0);

        saveOrUpdate(ryFaceLibrary);
    }

    @Override
    public PageResult<FaceLibraryVO> page(FaceLibraryListDTO dto){
        try {
            SimpleDataScopeHelper.start(FaceLibrary.class);
            Page<FaceLibraryVO> page = pageAs(PageUtils.getPage(dto), buildQueryWrapper(dto),  FaceLibraryVO.class);
            return PageUtils.getPageResult(page);
        } finally {
            SimpleDataScopeHelper.clearDataScope();
        }
    }

    @Override
    public List<FaceLibraryVO> list(FaceLibraryListDTO dto){
        try {
            SimpleDataScopeHelper.start(FaceLibrary.class);
            return listAs(buildQueryWrapper(dto), FaceLibraryVO.class);
        } finally {
            SimpleDataScopeHelper.clearDataScope();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void remove(SelectIdsDTO dto){
        CommonResponseEnum.INVALID_ID.assertTrue(dto.getIds().isEmpty());
        List<FaceLibrary> faceLibraryList = listByIds(dto.getIds());
        if (faceLibraryList.isEmpty())
        {
            return;
        }
        for (FaceLibrary library : faceLibraryList) {
            try {
                Long boxId = library.getBoxId();
                EdgeBox edgeBox = edgeBoxMapper.selectOneById(boxId);
                aiBoxRequestUtil.deleteFaceLibrary(edgeBox.getIp(), edgeBox.getPort(), library.getName());
            }catch (Exception e)
            {
                log.error("AI盒子删除人脸库失败, libraryName: {}", library.getName(), e);
                throw new BusinessException(AdminResponseEnum.OPERATION_FAIL,null, "同步删除AI盒子数据失败，请重试");
            }
        }
        // 删除人脸信息表关联数据
        faceInfoService.removeByLibraryIds(dto.getIds());
        removeByIds(dto.getIds());
    }
    @Override
    public FaceLibraryVO detail(Object id){
        FaceLibrary ryFaceLibrary = getById((Serializable) id);
        CommonResponseEnum.INVALID_ID.assertNull(ryFaceLibrary);
        return BeanCopyUtils.copy(ryFaceLibrary, FaceLibraryVO.class);
    }

    @SneakyThrows
    @Override
    public void importExcel(ImportExcelDTO dto) {
        ExcelResult<FaceLibraryImportDTO> excelResult = ExcelUtils.importExcel(dto.getFile().getInputStream(), FaceLibraryImportDTO.class, true);
        List<FaceLibraryImportDTO> list = excelResult.getList();
        // 入库
        List<FaceLibrary> importList = BeanCopyUtils.copyList(list, FaceLibrary.class);
        saveBatch(importList);
        List<String> errorList = excelResult.getErrorList();
        String analysis = excelResult.getAnalysis();
        System.out.println(" analysis : " + analysis);
        System.out.println(" isCover : " + dto.getIsCover());
    }

    @SneakyThrows
    @Override
    public void exportExcel(FaceLibraryListDTO dto, HttpServletResponse response) {
        List<FaceLibraryVO> list = list(dto);
        String fileName = "人脸库表模板";
        OutputStream os = FileUtils.getOutputStream(response, fileName + ".xlsx");
        ExcelUtils.exportExcel(list, "人脸库表", FaceLibraryVO.class, os);
    }

    private static QueryWrapper buildQueryWrapper(FaceLibraryListDTO dto) {
        QueryWrapper wrapper = QueryWrapper.create().from(FaceLibrary.class);
        if (Utils.isNotNull(dto.getName())) {
            wrapper.like(FaceLibrary::getName, dto.getName());
        }
        if (Utils.isNotNull(dto.getBoxId())) {
            wrapper.eq(FaceLibrary::getBoxId, dto.getBoxId());
        }
        return wrapper;
    }
}
