package incheon.sgp.drm.web;

import incheon.sgp.drm.service.sgpDrmService;
import incheon.sgp.drm.service.impl.sgpDrmServiceImpl;
import incheon.ags.drm.vo.DrmContentVO;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

@RestController
public class sgpDrmFileDownloadController {

    private final sgpDrmService sgpDrmService;

    public sgpDrmFileDownloadController(sgpDrmService sgpDrmService) {
        this.sgpDrmService = sgpDrmService;
    }

    @GetMapping("/sgp/drm/content/{contsId}/{type}")
    public ResponseEntity<Resource> downloadContentFile(
            @PathVariable Long contsId,
            @PathVariable String type
    ) {
        try {
            // 파일 정보 조회
            DrmContentVO contentVO = sgpDrmService.searchContentDetail(contsId);

            // 파일의 실제 절대 경로
            Path filePath = ((sgpDrmServiceImpl) sgpDrmService).getSgpFilePath(contentVO.getContsClsf(), contentVO.getContsFileNm());

            // 파일 경로 변환 (Spring Resource 객체)
            Resource resource = new UrlResource(filePath.toUri());
            if (!resource.exists() || !resource.isReadable()) {
                throw new FileNotFoundException("File not found or unreadable: " + contentVO.getContsFileNm());
            }

            // Content-Type (MIME Type) 결정 및 설정
            String contentType = getContentType(filePath, contentVO.getContsFileNm());

            // 파일명 인코딩
            String encodedFileName = URLEncoder.encode(contentVO.getContsFileNm(), StandardCharsets.UTF_8.toString())
                    .replaceAll("\\+", "%20");

            // 대민용 이므로 항상 브라우저표시
            String dispositionType = "inline";
            String contentDispositionHeader =
                    dispositionType + "; filename=\"" + encodedFileName + "\"; filename*=UTF-8''" + encodedFileName;

            return ResponseEntity.ok()
                    // 정확한 MIME Type 설정
                    .contentType(MediaType.parseMediaType(contentType))
                    // inline으로 설정하여 브라우저가 화면에 바로 표출하도록 지시 (3D 모델, 파노라마 필수)
                    .header(HttpHeaders.CONTENT_DISPOSITION, contentDispositionHeader)
                    // 파일 리소스를 응답 본문에 담아 전송
                    .body(resource);

        } catch (FileNotFoundException e) {
            // 파일이 없으면 404 Not Found
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            // 기타 오류 발생 시 서버 오류(500) 응답
            e.printStackTrace();
            return ResponseEntity.internalServerError().build();
        }
    }

    // 파일 경로와 파일명을 기반으로 Content-Type(MIME Type) 결정
    private String getContentType(Path filePath, String fileName) throws IOException {
        String contentType = Files.probeContentType(filePath);

        // probeContentType이 타입을 유추하지 못하는 경우 (FBX, HDR 등)
        if (contentType == null) {
            String lowerCaseFileName = fileName.toLowerCase();

            if (lowerCaseFileName.endsWith(".fbx")) { return "application/octet-stream"; }
            if (lowerCaseFileName.endsWith(".hdr") || lowerCaseFileName.endsWith(".exr")) { return "application/octet-stream"; }
            if (lowerCaseFileName.endsWith(".obj")) { return "model/obj"; }
            if (lowerCaseFileName.endsWith(".mtl")) { return "model/mtl"; }

            return "application/octet-stream";
        }

        return contentType;
    }
}
