package com.dji.sample.media.controller;

import com.dji.sample.common.error.CommonErrorEnum;
import com.dji.sample.media.model.FolderTreeDTO;
import com.dji.sample.media.model.MediaFileDTO;
import com.dji.sample.media.service.IFileService;
import com.dji.sdk.common.HttpResultResponse;
import com.dji.sdk.common.PaginationData;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URL;
import java.util.List;

/**
 * Controller for OSS browser operations (files, folders, move, rename, delete).
 * @author dji
 * @version 1.0
 * @date 2026/01/27
 */
@Slf4j
@RestController
@RequestMapping("${url.media.prefix}${url.media.version}/oss")
public class OssBrowserController {

    @Autowired
    private IFileService fileService;

    /**
     * Get files with pagination and filters.
     * @param page page number
     * @param pageSize page size
     * @param jobId job id filter
     * @param drone drone filter
     * @param workspaceId workspace id
     * @return paginated file list
     */
    @GetMapping("/{workspace_id}/files")
    public HttpResultResponse getFiles(
            @RequestParam(defaultValue = "1") Long page,
            @RequestParam(name = "page_size", defaultValue = "20") Long pageSize,
            @RequestParam(name = "job_id", required = false) String jobId,
            @RequestParam(required = false) String drone,
            @PathVariable(name = "workspace_id") String workspaceId
    ) {
        PaginationData<MediaFileDTO> data = fileService.getMediaFilesPaginationByWorkspaceId(
                workspaceId, jobId, drone, page, pageSize
        );
        return HttpResultResponse.success(data);
    }

    /**
     * Get folder tree for the folder picker.
     * @param workspaceId workspace id
     * @param prefix path prefix
     * @return folder tree list
     */
    @GetMapping("/{workspace_id}/folders-tree")
    public HttpResultResponse getFolderTree(
            @PathVariable(name = "workspace_id") String workspaceId,
            @RequestParam(required = false, defaultValue = "") String prefix
    ) {
        List<FolderTreeDTO> folders = fileService.getFolderTree(workspaceId, prefix);
        return HttpResultResponse.success(folders);
    }

    /**
     * Download a file by redirecting to presigned URL.
     * @param workspaceId workspace id
     * @param fileId file id
     * @param response http response for redirect
     */
    @GetMapping("/{workspace_id}/file/{file_id}/download")
    public void downloadFile(
            @PathVariable(name = "workspace_id") String workspaceId,
            @PathVariable(name = "file_id") String fileId,
            HttpServletResponse response
    ) {
        try {
            URL url = fileService.getObjectUrl(workspaceId, fileId);
            response.sendRedirect(url.toString());
        } catch (IOException e) {
            log.error("Download redirect failed: {}", e.getMessage());
        }
    }

    /**
     * Delete a media file.
     * @param workspaceId workspace id
     * @param fileId file id
     * @return success status
     */
    @DeleteMapping("/{workspace_id}/file/{file_id}")
    public HttpResultResponse deleteFile(
            @PathVariable(name = "workspace_id") String workspaceId,
            @PathVariable(name = "file_id") String fileId
    ) {
        Boolean success = fileService.deleteMediaFile(workspaceId, fileId);
        if (success) {
            return HttpResultResponse.success(true);
        } else {
            return HttpResultResponse.error("删除失败");
        }
    }

    /**
     * Rename a media file.
     * @param workspaceId workspace id
     * @param fileId file id
     * @param request rename request with new name
     * @return success status
     */
    @PutMapping("/{workspace_id}/file/{file_id}/rename")
    public HttpResultResponse renameFile(
            @PathVariable(name = "workspace_id") String workspaceId,
            @PathVariable(name = "file_id") String fileId,
            @RequestBody RenameRequest request
    ) {
        Boolean success = fileService.renameMediaFile(workspaceId, fileId, request.getNewName());
        if (success) {
            return HttpResultResponse.success(true);
        } else {
            return HttpResultResponse.error("重命名失败，目标文件名可能已存在");
        }
    }

    /**
     * Move a media file to a new folder.
     * @param workspaceId workspace id
     * @param fileId file id
     * @param request move request with target path
     * @return success status
     */
    @PutMapping("/{workspace_id}/file/{file_id}/move")
    public HttpResultResponse moveFile(
            @PathVariable(name = "workspace_id") String workspaceId,
            @PathVariable(name = "file_id") String fileId,
            @RequestBody MoveRequest request
    ) {
        Boolean success = fileService.moveMediaFile(workspaceId, fileId, request.getTargetPath());
        if (success) {
            return HttpResultResponse.success(true);
        } else {
            return HttpResultResponse.error("移动失败，目标路径可能已存在同名文件");
        }
    }

    // ============= Request DTOs =============

    @Data
    public static class RenameRequest {
        private String newName;
    }

    @Data
    public static class MoveRequest {
        private String targetPath;
    }
}
