package com.zhpb.gdyd_zhpb_zgf.controller;

import com.zhpb.gdyd_zhpb_zgf.entity.mysql.File;
import com.zhpb.gdyd_zhpb_zgf.repository.mysql.FileRepository;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 简单文件浏览与下载接口
 */
@RestController
@RequestMapping("/view/api/v1/files")
@Tag(name = "文件浏览", description = "列出已存储文件并提供下载")
public class FileBrowseController {

    private static final Logger logger = LoggerFactory.getLogger(FileBrowseController.class);

    private final FileRepository fileRepository;

    public FileBrowseController(FileRepository fileRepository) {
        this.fileRepository = fileRepository;
    }

    /**
     * 列出文件，可按项目/供应商筛选
     */
    @GetMapping("/list")
    @Operation(summary = "列出已存储文件", description = "可按项目ID、供应商ID过滤")
    public List<Map<String, Object>> listFiles(
            @Parameter(description = "项目ID") @RequestParam(required = false) String projectId,
            @Parameter(description = "供应商ID") @RequestParam(required = false) String supplierId) {

        List<File> files;
        if (projectId != null && supplierId != null) {
            files = fileRepository.findByProjectIdAndSupplierId(projectId, supplierId);
        } else if (projectId != null) {
            files = fileRepository.findByProjectId(projectId);
        } else if (supplierId != null) {
            files = fileRepository.findBySupplierId(supplierId);
        } else {
            files = fileRepository.findAll();
        }

        if (CollectionUtils.isEmpty(files)) {
            return Collections.emptyList();
        }

        return files.stream().map(f -> Map.<String, Object>ofEntries(
                Map.entry("id", f.getId()),
                Map.entry("fileId", f.getFileId()),
                Map.entry("projectId", f.getProjectId()),
                Map.entry("supplierId", f.getSupplierId()),
                Map.entry("fileName", f.getFileName()),
                Map.entry("filePath", f.getFilePath()),
                Map.entry("fileSize", f.getFileSize()),
                Map.entry("fileExtension", f.getFileExtension()),
                Map.entry("fileTypeId", f.getFileTypeId()),
                Map.entry("status", f.getStatus()),
                Map.entry("downloadUrl", "/api/v1/files/download/" + f.getId())
        )).collect(Collectors.toList());
    }

    /**
     * 按ID下载文件
     */
    @GetMapping("/download/{id}")
    @Operation(summary = "下载文件", description = "根据文件记录ID下载实际文件")
    public ResponseEntity<Resource> download(@PathVariable Long id) {
        return fileRepository.findById(id)
                .map(file -> {
                    Path path = Paths.get(file.getFilePath());
                    if (!Files.exists(path)) {
                        return ResponseEntity.status(HttpStatus.NOT_FOUND).<Resource>build();
                    }
                    Resource resource = new FileSystemResource(path);
                    String encodedName = URLEncoder.encode(file.getFileName(), StandardCharsets.UTF_8);
                    return ResponseEntity.ok()
                            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encodedName)
                            .contentType(MediaType.APPLICATION_OCTET_STREAM)
                            .body(resource);
                })
                .orElse(ResponseEntity.status(HttpStatus.NOT_FOUND).<Resource>build());
    }
}

