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.mbg.model.EasArcArchivesExample;
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(String archiveNumber) {

        EasArcArchivesExample easArcArchivesExample = new EasArcArchivesExample();
        easArcArchivesExample.createCriteria().andArchiveNumberEqualTo(archiveNumber);
        EasArcArchives easArcArchives = archivesMapper.selectByExample(easArcArchivesExample)
                .stream().findFirst().orElse(null);

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

        return getArchiveDownloadToken( easArcArchives.getArchiveNumber(),  easArcArchives.getFilePath() );

    }

    @Override
    public String getArchiveDownloadToken(String archiveNumber, String filePath){

        long timestamp = System.currentTimeMillis();
        // 使用UUID生成一个唯一标识
        String uniqueId = UUID.randomUUID().toString();
        // 将用户传入的ID与时间戳和唯一标识拼接起来
        String token = archiveNumber + "_" + timestamp + "_" + uniqueId;

        // 将token存入redis
        archiveRedisService.saveArchiveToken(token, filePath);
        // 将token返回给用户
        String archiveToken = passwordManager.archiveEncryptPassword(token);

        return archiveToken;
    }

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



    @Override
    public boolean downloadFileByToken(String archiveToken, HttpServletResponse response) {

        //加入判断
        String filePath = getFilePathByToken(archiveToken);
        if (filePath == null) {
            throw new EasException("获取文件超时，请重新获取token", 4003);
        }
        String fileExtension = getFileExtension(filePath);
        String archiveFileType = ArchiveFileType.getContentType(fileExtension.toLowerCase());

        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 ignored) {}
        }
        return true;
    }

    @Override
    public boolean validateArchiveNumberByUser(String archiveNumber, String studentNumber) {
        EasArcArchivesExample easArcArchivesExample = new EasArcArchivesExample();
        EasArcArchivesExample.Criteria criteria = easArcArchivesExample.createCriteria();
        criteria.andArchiveNumberEqualTo(archiveNumber);
        criteria.andStudentNumberEqualTo(studentNumber);
        long l = archivesMapper.countByExample(easArcArchivesExample);
        return l >= 1;
    }

    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);

        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);

        return filename;
    }

}
