package com.malk.huagao.controller;

import org.springframework.core.io.UrlResource;
import org.springframework.core.io.Resource;
import com.alibaba.fastjson.JSON;
import com.malk.huagao.service.EqbService;
import com.malk.server.common.McR;
import com.malk.utils.UtilMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("/eqb")
public class HgEqbController {
    @Autowired
    private EqbService eqbService;

    @Value(value = "${eqb.downloadFilePath}")
    private String fileStoragePath;


    @PostMapping("/sign")
    public McR sign(@RequestBody Map map){
        eqbService.sign(map);
        return McR.success();
    }

    // 使用ConcurrentHashMap保证线程安全
    private final ConcurrentMap<String, Long> eventList = new ConcurrentHashMap<>();
    // 记录最后一次清理时间
    private volatile long lastCleanTime = System.currentTimeMillis();
    // 清理间隔时间(毫秒)
    private static final long CLEAN_INTERVAL = 60_000;


    @PostMapping("/callback")
    public McR callback(@RequestBody Map map){
        System.out.println(map);

        log.info("e签宝回调： {}", JSON.toJSONString(map));

        //签署回调通知：SIGN_MISSON_COMPLETE   事件订阅-签署流程完成：SIGN_FLOW_FINISH
        String action = UtilMap.getString(map, "action");
        String signFlowId = UtilMap.getString(map, "signFlowId");//e签宝签署流程id

        String info = action + "-" + signFlowId;

        // 定期清理过期记录
        cleanExpiredEvents();

        if (isCallbackProcessed(info)){
            log.info("info:{},重复回调,不做处理",info);
        }else {
            eventList.put(info, System.currentTimeMillis());
            //签署回调结束
            if ("SIGN_MISSON_COMPLETE".equals(action)) {
                int signResult = UtilMap.getInt(map, "signResult");//2 - 签署完成，4 - 拒签
                if (2 == signResult) {
                    String processInstanceId = UtilMap.getString(map, "customBizNum");//宜搭审批实例id
                    //自动同意审批节点
                    eqbService.autoAgree(signFlowId,processInstanceId);
                }
            }
        }

        return McR.success();
    }

    @GetMapping("/files/{fileId}")
    public ResponseEntity<Resource> getFileResource(
            @PathVariable String fileId,
            @RequestParam(defaultValue = "download") String option) throws IOException {

        // 根据fileId获取实际文件路径，这里简化处理，实际可能需要从数据库查询
        Path filePath = Paths.get(fileStoragePath).resolve(fileId).normalize();

        // 检查文件是否存在
        if (!Files.exists(filePath)) {
            return ResponseEntity.notFound().build();
        }

        // 创建Resource对象
        Resource resource =  new UrlResource(filePath.toUri());

        // 根据选项设置响应头
        HttpHeaders headers = new HttpHeaders();
        if ("preview".equalsIgnoreCase(option)) {
            // 预览模式 - 尝试确定内容类型
            String contentType = Files.probeContentType(filePath);
            // 强制修正 PDF 的 Content-Type
            if (filePath.toString().toLowerCase().endsWith(".pdf")) {
                contentType = "application/pdf";
            } else if (contentType == null) {
                contentType = "application/octet-stream";
            }
            headers.setContentType(MediaType.parseMediaType(contentType));
            headers.add("Content-Disposition", "inline; filename=\"" + resource.getFilename() + "\"");
            headers.add("X-Content-Type-Options", "nosniff"); // 防止浏览器忽略 Content-Type
        } else {
            // 下载模式 - 默认处理
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\"");
        }

        return ResponseEntity.ok()
                .headers(headers)
                .contentLength(resource.contentLength())
                .body(resource);
    }

    /**
     * 检查并清理过期事件
     */
    private void cleanExpiredEvents() {
        long currentTime = System.currentTimeMillis();
        // 只在达到清理间隔时执行清理
        if (currentTime - lastCleanTime > CLEAN_INTERVAL) {
            synchronized (this) {
                // 双重检查，避免重复清理
                if (currentTime - lastCleanTime > CLEAN_INTERVAL) {
                    long expirationTime = currentTime - TimeUnit.MINUTES.toMillis(1);
                    eventList.entrySet().removeIf(entry -> entry.getValue() < expirationTime);
                    lastCleanTime = currentTime;
                }
            }
        }
    }

    /**
     * 检查该回调事件在一分钟内是否处理过
     */
    private boolean isCallbackProcessed(String detail) {
        return eventList.containsKey(detail);
    }

}
