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

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.IdUtil;
import com.mybatisflex.core.BaseMapper;
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.po.EdgeBox;
import com.sz.admin.monitor.pojo.po.FaceImage;
import com.sz.admin.monitor.pojo.po.FaceInfo;
import com.sz.admin.monitor.pojo.po.FaceLibrary;
import com.sz.admin.monitor.pojo.po.table.FaceImageTableDef;
import com.sz.admin.monitor.pojo.vo.faceimage.FaceImageVO;
import com.sz.admin.monitor.service.FaceImageService;
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.ImageNameUtils;
import com.sz.admin.monitor.utils.UrlConvert;
import com.sz.core.util.BeanCopyUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.Base64;
import java.util.List;

/**
 * ClassName: FaceImageServiceImpl
 * Package: com.sz.admin.monitor.service.impl
 * Description:
 */
@Service
@Slf4j
public class FaceImageServiceImpl extends ServiceImpl<FaceImageMapper, FaceImage> implements FaceImageService {
    @Resource
    private AiBoxRequestUtil aiBoxRequestUtil;
    @Resource
    private FaceInfoMapper faceInfoMapper;
    @Resource
    private FaceLibraryMapper faceLibraryMapper;
    @Resource
    private EdgeBoxMapper edgeBoxMapper;
    // 图片上传接口
    @Override
    public String fileUpload(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        String fileName = ImageNameUtils.generateFileName("face",suffix);
        // 保存到本地文件夹
        String filePath = "D:\\work\\images\\" + fileName;
        try {
            file.transferTo(new File(filePath));
            return UrlConvert.convertToUrl(filePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    @Override
    public List<FaceImageVO> getByFaceId(Long id) {
        QueryWrapper wrapper = QueryWrapper.create()
            .select()
            .from(FaceImageTableDef.FACE_IMAGE)
            .where(FaceImageTableDef.FACE_IMAGE.FACE_INFO_ID.eq(id));
        List<FaceImage> faceImages = this.list(wrapper);
        return BeanCopyUtils.copyList(faceImages, FaceImageVO.class);
    }

    @Override
    @Transactional
    public void fileUploadBind(MultipartFile file, Long id) {
        String path = fileUpload(file);
        FaceInfo faceInfo = faceInfoMapper.selectOneById(id);
        if (faceInfo == null) {
            throw new RuntimeException("未找到对应的人脸信息，绑定失败");
        }
        FaceLibrary faceLibrary = faceLibraryMapper.selectOneById(faceInfo.getLibraryId());
        if (faceLibrary == null) {
            throw new RuntimeException("未找到关联的人脸库，绑定失败");
        }
        EdgeBox edgeBox = edgeBoxMapper.selectOneById(faceLibrary.getBoxId());
        String base64Image = null;
        try {
            String realFilePath = getRealFilePath(path);
           File f = new File(realFilePath);
            if (!f.exists()) {
                throw new RuntimeException("读取人脸图片失败，文件不存在: " + path);
            }
            byte[] fileBytes = Files.readAllBytes(Paths.get(realFilePath));
            base64Image = Base64.getEncoder().encodeToString(fileBytes);
        } catch (IOException e) {
            log.error("图片转Base64编码异常, 图片路径: {}", path, e);
            throw new RuntimeException("处理人脸图片文件时发生异常");
        }
        aiBoxRequestUtil.registerFaceLibrary(edgeBox.getIp(), edgeBox.getPort(), faceLibrary.getName(),
            faceInfo.getFaceSign(),
            faceInfo.getName(),
            base64Image,
            UUID.randomUUID().toString().replaceAll("-", ""));
        try {
            FaceImage faceImage = new FaceImage();
            faceImage.setFaceInfoId(id);
            faceImage.setImageUrl(path);
            faceImage.setUploadTime(LocalDateTime.now());
            this.save(faceImage);
        } catch (Exception e) {
            log.error("本地保存图片记录失败，准备执行 AI 盒子反向清理。图片路径: {}", path, e);
            try {
                aiBoxRequestUtil.deleteFaceInfo(edgeBox.getIp(), edgeBox.getPort(), faceInfo.getFaceSign(), faceLibrary.getName());
            } catch (Exception rollbackEx) {
                log.error("【严重告警】本地落库失败，且 AI 盒子清理也失败！需人工排查。", rollbackEx);
            }
            throw new RuntimeException("图片绑定失败，请重试");
        }
    }
    private String getRealFilePath(String imageUrl) {
        String basePath="D:/work/images";
        return basePath + imageUrl.replace("/save", "");
    }

    @Override
    public void removeByFaceIds(List<? extends Serializable> ids) {
        QueryWrapper queryWrapper = QueryWrapper.create()
            .select()
            .from(FaceImageTableDef.FACE_IMAGE)
            .where(FaceImageTableDef.FACE_IMAGE.FACE_INFO_ID.in(ids));
        this.remove(queryWrapper);
    }
}
