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


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.sz.admin.monitor.pojo.dto.camera.CameraListDTO;
import com.sz.admin.monitor.pojo.dto.file.FileEntityDTO;
import com.sz.admin.monitor.pojo.dto.file.FileStorageDTO;
import com.sz.admin.monitor.pojo.po.Camera;
import com.sz.admin.monitor.pojo.po.FileStorageDO;
import com.sz.admin.monitor.pojo.po.Nvr;
import com.sz.admin.monitor.pojo.que.file.FileStorageQue;
import com.sz.admin.monitor.pojo.vo.camera.CameraVO;
import com.sz.admin.monitor.service.FileStorageService;
import com.sz.core.common.entity.ApiResult;
import com.sz.core.common.entity.PageResult;
import com.sz.core.datascope.SimpleDataScopeHelper;
import com.sz.core.util.PageUtils;
import com.sz.core.util.Utils;
import com.sz.platform.enums.AdminResponseEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;

/**
 * @author xq
 * @description:文件存储业务
 * @date 2026/3/13 15:28
 */
@Service
public class FileServiceImpl {
    @Autowired
    private FileStorageService fileStorageService;

    @Value("${file.object.storage.targetDir:/defaultFile}")
    private String targetDir;

    // 获取当前操作系统的文件分隔符
    private static String separator = "/";

    //获取文件流路径（请求路径）
    private static String path = "/fileStorage/getPreviewFile/";

    /**
     * 删除文件
     *
     * @param id
     * @return
     */
    public ApiResult<String> deleteFileById(String id) {
        if (ObjectUtil.isEmpty(id))
            return ApiResult.error(AdminResponseEnum.OPERATION_FAIL);
        FileStorageDO fileStorageDO = fileStorageService.getById(id);
        if (ObjectUtil.isEmpty(fileStorageDO))
            return ApiResult.error(AdminResponseEnum.OPERATION_FAIL);
        fileStorageService.removeById(id);
        return ApiResult.success("删除成功");
    }

    /**
     * 修改文件名称
     *
     * @param dto
     * @return
     */
    public ApiResult<String> editFileNameById(FileEntityDTO dto) {
        if (ObjectUtil.isEmpty(dto.getId()))
            return ApiResult.error(AdminResponseEnum.OPERATION_FAIL);
        FileStorageDO fileStorageDO = fileStorageService.getById(dto.getId());
        if (ObjectUtil.isEmpty(fileStorageDO))
            return ApiResult.error(AdminResponseEnum.OPERATION_FAIL);
        fileStorageDO.setFileName(dto.getFileName());
        fileStorageService.saveOrUpdate(fileStorageDO);
        return ApiResult.success("修改成功");
    }

    /**
     * 分页查询
     *
     * @param que
     * @return
     */
    public ApiResult<PageResult<FileEntityDTO>> getFileObjectList(FileStorageQue que) {
        SimpleDataScopeHelper.start(FileStorageDO.class); // 指定要追加条件的表PO实体

        QueryWrapper queryWrapper = QueryWrapper.create()
            .from(FileStorageDO.class)
            .eq(FileStorageDO.ID, que.getId(), ObjectUtil.isNotEmpty(que.getId()))
            .like(FileStorageDO.FILE_NAME, que.getFileName(), ObjectUtil.isNotEmpty(que.getFileName()));
        if (ObjectUtil.isNotEmpty(que.getStartTime()) && ObjectUtil.isNotEmpty(que.getEndTime())) {
            queryWrapper.between(
                FileStorageDO.ADD_TIME,
                new Date(que.getStartTime()),
                new Date(que.getEndTime())
            );
        }
        queryWrapper.orderBy(FileStorageDO.ADD_TIME, false);


        Page<FileStorageDO> page = fileStorageService.pageAs(PageUtils.getPage(que), queryWrapper, FileStorageDO.class);// 调试sql
        if (ObjectUtil.isEmpty(page) || page.getRecords().isEmpty())
            return ApiResult.success(new PageResult<>(que.getPage().longValue(), que.getLimit().longValue(), 0, 0, new ArrayList<>()));

        List<FileEntityDTO> fileEntityDTOS = new ArrayList<>();
        for (FileStorageDO record : page.getRecords()) {
            FileEntityDTO fileEntityDTO = BeanUtil.copyProperties(record, FileEntityDTO.class);
            fileEntityDTO.setFilePath(path + record.getId());
            fileEntityDTOS.add(fileEntityDTO);
        }

        return ApiResult.success(new PageResult<>(
            page.getPageNumber(),
            page.getPageSize(),
            page.getTotalPage(),
            page.getTotalRow(),
            fileEntityDTOS));
    }

//    public ApiResult<PageResult<FileEntityDTO>> getFileObjectList(FileStorageQue que) {
//        Page<FileStorageDO> doPage = BaseQue.init(que, FileStorageDO.class);
//        Page<FileStorageDO> page = fileStorageService.page(doPage, new QueryWrapper<FileStorageDO>()
//            .eq(ObjectUtil.isNotEmpty(que.getId()), FileStorageDO.ID, que.getId())
//            .like(ObjectUtil.isNotEmpty(que.getFileName()), FileStorageDO.FILE_NAME, que.getFileName())
//            .between(
//                ObjectUtil.isNotEmpty(que.getStartTime()) && ObjectUtil.isNotEmpty(que.getEndTime())
//                , FileStorageDO.ADD_TIME
//                , que.getStartTime(), que.getEndTime())
//            .orderByDesc(FileStorageDO.ADD_TIME)
//        );
//        if(ObjectUtil.isEmpty(page) || page.getRecords().isEmpty())
//            return ResponseBody.ok();
//
//        BasePage<FileEntityDTO> basePage = new BasePage();
//        basePage.setTotal(page.getTotal());
//        basePage.setSize(page.getSize());
//        basePage.setCurrent(page.getCurrent());
//        basePage.setPages(page.getPages());
//
//        List<FileEntityDTO> fileEntityDTOS = new ArrayList<>();
//        for (FileStorageDO record : page.getRecords()) {
//            FileEntityDTO fileEntityDTO = BeanUtil.copyProperties(record, FileEntityDTO.class);
//            fileEntityDTO.setFilePath(path+record.getId());
//            fileEntityDTOS.add(fileEntityDTO);
//        }
//        basePage.setList(fileEntityDTOS);
//        return ApiResult.success(basePage);
//    }


    /**
     * 返回文件流
     *
     * @param id
     * @return
     */
    public ResponseEntity<byte[]> getPreviewFile(String id) {
        FileStorageDO fileStorageDO = fileStorageService.getById(id);
        String filePath = fileStorageDO.getFileUrl();
        // 使用Hutool读取文件并转换为Base64编码
        byte[] imageBytes = FileUtil.readBytes(filePath);
        String mimeType = getMimeType(filePath);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.parseMediaType(mimeType));
        headers.setContentLength(imageBytes.length);

        return new ResponseEntity<>(imageBytes, headers, HttpStatus.OK);
    }

    /**
     * 获取文件
     *
     * @param id
     * @return
     */
    public ApiResult<FileStorageDTO> getFile(String id) {
        FileStorageDO fileStorageDO = fileStorageService.getById(id);
        if (ObjectUtil.isEmpty(fileStorageDO))
            return ApiResult.error(AdminResponseEnum.OPERATION_FAIL);

        String filePath = fileStorageDO.getFileUrl();
        // 使用Hutool读取文件并转换为Base64编码
        byte[] fileBytes = FileUtil.readBytes(filePath);
        String base64Data = Base64.encode(fileBytes);
        String mimeType = getMimeType(filePath);
        String dataUrl = "data:" + mimeType + ";base64," + base64Data;
        FileStorageDTO fileStorageDTO = BeanUtil.copyProperties(fileStorageDO, FileStorageDTO.class);
        fileStorageDTO.setBase64Data(dataUrl);
        return ApiResult.success(fileStorageDTO);
    }

    /**
     * 图片存储
     *
     * @param file
     * @return
     */
    public ApiResult<FileStorageDTO> saveFile(MultipartFile file) {
        Map<String, Object> result = new HashMap<>();

        if (file.isEmpty())
            return ApiResult.error(AdminResponseEnum.OPERATION_FAIL);

        String path = targetDir;
        try {
            FileUtil.mkdir(path);

            // 生成唯一文件名
            String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
            String filePath = path + separator + fileName;

            // 使用Hutool保存文件
            FileUtil.writeBytes(file.getBytes(), filePath);

            String mimeType = getMimeType(filePath);
            FileStorageDTO fileDTO = FileStorageDTO.builder()
                .fileUrl(filePath)
                .fileSize(ObjectUtil.isNotEmpty(file.getSize()) ? String.valueOf(file.getSize()) : "0")
                .fileName(file.getOriginalFilename())
                .fileSuffix(mimeType)
                .addTime(new Date())
                .build();

            FileStorageDO fileStorageDO = FileStorageDTO.dtoConvertDO(fileDTO);
            fileStorageService.saveOrUpdate(fileStorageDO);
            fileDTO.setId(fileStorageDO.getId());

            String base64Data = Base64.encode(file.getBytes());
            String dataUrl = "data:" + mimeType + ";base64," + base64Data;
            fileDTO.setBase64Data(dataUrl);

            return ApiResult.success(fileDTO);
        } catch (IOException e) {
            result.put("success", false);
            result.put("message", "文件上传失败: " + e.getMessage());
            return ApiResult.error(null);
        }
    }

    public void test01() {
        fileStorageService.list().forEach(System.out::println);
    }

    /**
     * 根据文件扩展名获取MIME类型
     */
    private String getMimeType(String filePath) {
        String lowerPath = filePath.toLowerCase();
        if (lowerPath.endsWith(".jpg") || lowerPath.endsWith(".jpeg")) {
            return "image/jpeg";
        } else if (lowerPath.endsWith(".png")) {
            return "image/png";
        } else if (lowerPath.endsWith(".gif")) {
            return "image/gif";
        } else if (lowerPath.endsWith(".bmp")) {
            return "image/bmp";
        } else {
            return "image/jpeg"; // 默认JPEG类型
        }
    }
}
