package com.koobietech.eas.service.impl;

import cn.hutool.core.lang.UUID;
import com.koobietech.eas.common.constant.ArchiveFileType;
import com.koobietech.eas.common.exception.EasException;
import com.koobietech.eas.common.utils.PasswordManager;
import com.koobietech.eas.mbg.mapper.EasArcArchivesMapper;
import com.koobietech.eas.mbg.model.EasArcArchives;
import com.koobietech.eas.service.EasArcArchiveRedisService;
import com.koobietech.eas.service.EasArchiveFileDownloadService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Objects;

@Service
public class EasArchiveFileDownloadServiceImpl implements EasArchiveFileDownloadService {
    @Resource
    private PasswordManager passwordManager;

    @Resource
    private EasArcArchiveRedisService archiveRedisService;

    @Resource
    private EasArcArchivesMapper archivesMapper;


    @Override
    public String getArchiveToken(Integer archiveId) {
        //在getArchiveToken中，使用UUID随机生成字符串作为k键，
        // 为了保证每次生成的字符串不同，在生成的时候加上时间戳
        // 使用根据id查询到的所需文件在本机上的地址file_path作为v值
        // 存入redis，时间设置成三分钟
        // 获取当前时间戳
        long timestamp = System.currentTimeMillis();
        // 使用UUID生成一个唯一标识
        String uniqueId = UUID.randomUUID().toString();
        // 将用户传入的ID与时间戳和唯一标识拼接起来
        String token = archiveId + "_" + timestamp + "_" + uniqueId;
        System.out.println("生成的file token 拼接版："+token);
        EasArcArchives easArcArchives = archivesMapper.selectByPrimaryKey(archiveId);

        if (Objects.isNull(easArcArchives)) {
            throw new EasException("文件不存在");
        }

        // 获取文件路径
        String filePath = easArcArchives.getFilePath();

        archiveRedisService.saveArchiveToken(token,filePath);
        // 将token返回给用户
        String archiveToken = passwordManager.archiveEncryptPassword(token);
        System.out.println("加密生成的file token 加密版："+archiveToken);
        return archiveToken;

    }

    @Override
    public String getFilePathByToken(String archiveToken) {
        //在getFilePathByToken中，使用token作为k键，从redis中取出v值
        // 如果取出的值为空，说明token已经过期，返回null
        // 如果取出的值不为空，说明token没有过期，返回v值
        String token = passwordManager.archiveDecryptPassword(archiveToken);
        System.out.println("解密后的file token："+token);
        return archiveRedisService.getFilePathByToken(token);
    }



    @Override
    public boolean downloadFileByToken(String archiveToken, HttpServletResponse response) {
        //加入判断

        String filePath = getFilePathByToken(archiveToken);

        //加一个判断，如果filePath为空，说明token已经过期，抛出异常
        if (filePath == null) {
            throw new EasException("获取文件超时，请重新获取token", 4003);
        }
        String fileExtension = getFileExtension(filePath);
        String archiveFileType = ArchiveFileType.getContentType(fileExtension);


        if (archiveFileType != null) {
            response.addHeader("Content-Type", archiveFileType);
            response.addHeader("Content-Disposition", "attachment; filename=" + getFileSaveName(filePath) );
        } else {
            throw new EasException("文件类型未知", 4000);
        }
        OutputStream outputStream = null;
        FileInputStream fileInputStream = null;
        try {
            outputStream = response.getOutputStream();
            fileInputStream = new FileInputStream(filePath);
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
        } catch (IOException e) {
            throw new EasException("文件传输失败", 4001);
        } finally {
            try {
                if (Objects.nonNull(outputStream)) {
                    outputStream.close();
                }
                if (Objects.nonNull(fileInputStream)) {
                    fileInputStream.close();
                }
            } catch (IOException e) {}
        }
        return true;
    }

    private String getFileExtension(String filePath) {
        // 获取文件后缀名逻辑，请根据实际情况实现
        if (filePath == null || filePath.isEmpty()) {
            return "";
        }

        int dotIndex = filePath.lastIndexOf(".");
        if (dotIndex == -1 || dotIndex == filePath.length() - 1) {
            return "";
        }

        String extension = filePath.substring(dotIndex);
        System.out.println("文件后缀名：" + extension);

        return extension;
    }

    private String getFileSaveName(String filePath) {
        // 获取文件后缀名逻辑，请根据实际情况实现
        if (filePath == null || filePath.isEmpty()) {
            return "";
        }

        int dotIndex = filePath.lastIndexOf(File.separator );
        if (dotIndex == -1 || dotIndex == filePath.length() - 1) {
            return "";
        }

        String filename = filePath.substring(dotIndex + 1);
        System.out.println("文件名：" + filename);

        return filename;
    }

}
