package com.kamco.cd.training.filemanager.dto;

import com.kamco.cd.training.common.utils.interfaces.JsonFormatDttm;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

public class FileManagerDto {

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(description = "파일 정보")
  public static class FileInfo {
    @Schema(description = "파일명", example = "dataset.zip")
    private String fileName;

    @Schema(description = "파일 전체 경로", example = "/data/request/dataset.zip")
    private String filePath;

    @Schema(description = "파일 크기 (bytes)", example = "1024000")
    private Long fileSize;

    @Schema(description = "파일인지 디렉토리인지 여부", example = "true")
    private Boolean isFile;

    @Schema(description = "디렉토리인지 여부", example = "false")
    private Boolean isDirectory;

    @Schema(description = "마지막 수정 시간", example = "2026-04-06T15:30:00")
    private LocalDateTime lastModified;

    @Schema(description = "읽기 권한", example = "true")
    private Boolean readable;

    @Schema(description = "쓰기 권한", example = "true")
    private Boolean writable;
  }

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(description = "디렉토리 목록 조회 요청")
  public static class ListFilesReq {
    @Schema(description = "조회할 디렉토리 경로 (기본값: /data)", example = "/data/request")
    private String directoryPath;

    @Schema(description = "하위 디렉토리 포함 여부", example = "false")
    private Boolean recursive;
  }

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(description = "디렉토리 목록 조회 응답")
  public static class ListFilesRes {
    @Schema(description = "조회된 디렉토리 경로", example = "/data/request")
    private String directoryPath;

    @Schema(description = "파일 목록")
    private List<FileInfo> files;

    @Schema(description = "총 파일 개수", example = "10")
    private Integer totalCount;

    @Schema(description = "총 파일 크기 (bytes)", example = "10240000")
    private Long totalSize;
  }

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(description = "파일 삭제 요청")
  public static class DeleteFileReq {
    @Schema(
        description = "삭제할 파일 또는 디렉토리 경로 목록",
        example = "[\"/data/request/old_file.zip\", \"/data/tmp/test_folder\"]")
    private List<String> filePaths;

    @Schema(description = "디렉토리일 경우 하위 파일 포함 삭제 여부", example = "true")
    private Boolean recursive;
  }

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(description = "파일 삭제 응답")
  public static class DeleteFileRes {
    @Schema(description = "삭제 성공한 파일 경로 목록")
    private List<String> deletedFiles;

    @Schema(description = "삭제 실패한 파일 경로 목록")
    private List<String> failedFiles;

    @Schema(description = "삭제 성공 개수", example = "5")
    private Integer successCount;

    @Schema(description = "삭제 실패 개수", example = "0")
    private Integer failureCount;

    @Schema(description = "전체 메시지", example = "5개 파일 삭제 성공")
    private String message;
  }

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(description = "디스크 사용량 조회 응답")
  public static class DiskUsageRes {
    @Schema(description = "디렉토리 경로", example = "/data")
    private String directoryPath;

    @Schema(description = "총 용량 (bytes)", example = "1000000000000")
    private Long totalSpace;

    @Schema(description = "사용 가능 용량 (bytes)", example = "500000000000")
    private Long usableSpace;

    @Schema(description = "사용 중인 용량 (bytes)", example = "500000000000")
    private Long usedSpace;

    @Schema(description = "사용률 (%)", example = "50.0")
    private Double usagePercentage;
  }

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(description = "모델 파일 경로 정보 응답")
  public static class ModelFilePathRes {
    @Schema(description = "모델 UUID", example = "df284755-c0b7-4070-bfee-ef554e8d0fe4")
    private String modelUuid;

    @Schema(
        description = "요청 경로 (심볼릭 링크 디렉토리)",
        example = "/home/kcomu/data/tmp/AE366F3076504FACBF12106986202AB5")
    private String requestPath;

    @Schema(
        description = "응답 경로 (모델 결과 저장)",
        example = "/home/kcomu/data/response/df284755-c0b7-4070-bfee-ef554e8d0fe4")
    private String responsePath;

    @Schema(description = "요청 경로 파일 목록")
    private List<FileInfo> requestFiles;

    @Schema(description = "응답 경로 파일 목록")
    private List<FileInfo> responseFiles;
  }

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(description = "데이터셋 파일 경로 정보 응답")
  public static class DatasetFilePathRes {
    @Schema(description = "데이터셋 UUID", example = "037b09a0-b315-4e2e-b88d-b9011f9eaa15")
    private String datasetUuid;

    @Schema(
        description = "데이터셋 경로",
        example = "/home/kcomu/data/request/037b09a0-b315-4e2e-b88d-b9011f9eaa15")
    private String datasetPath;

    @Schema(description = "데이터셋 파일 목록")
    private List<FileInfo> files;
  }

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(description = "디렉토리 용량 체크 응답")
  public static class DirectoryCapacityRes {
    @Schema(description = "디렉토리 경로", example = "/home/kcomu/data/request/dataset-uuid")
    private String directoryPath;

    @Schema(description = "파일 개수", example = "1234")
    private Integer fileCount;

    @Schema(description = "디렉토리 개수", example = "56")
    private Integer directoryCount;

    @Schema(description = "총 용량 (bytes)", example = "10485760000")
    private Long totalSize;

    @Schema(description = "총 용량 (읽기 쉬운 형식)", example = "9.77 GB")
    private String totalSizeFormatted;
  }

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(description = "모델별 학습 실행 상태 응답")
  public static class ModelExecutionStatusRes {
    @Schema(description = "모델 번호", example = "G1")
    private String modelNo;

    @Schema(description = "실행 상태 메시지", example = "G1 모델에 테스트를 진행중입니다.")
    private String statusMessage;

    @Schema(description = "1단계 상태", example = "COMPLETED")
    private String step1State;

    @Schema(description = "2단계 상태", example = "IN_PROGRESS")
    private String step2State;

    @Schema(description = "현재 실행 중인 단계", example = "2")
    private Integer currentStep;
  }

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(description = "전체 모델 학습 실행 상태 목록 응답")
  public static class AllModelsExecutionStatusRes {
    @Schema(description = "모델별 실행 상태 목록")
    private List<ModelExecutionStatusRes> modelStatuses;

    @Schema(description = "현재 실행 중인 모델 개수", example = "2")
    private Integer runningCount;
  }

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(description = "저장공간 정보 응답 (남은 공간 포함)")
  public static class StorageSpaceRes {
    @Schema(description = "디렉토리 경로", example = "/home/kcomu/data")
    private String directoryPath;

    @Schema(description = "파일 개수", example = "1234")
    private Integer fileCount;

    @Schema(description = "디렉토리 개수", example = "56")
    private Integer directoryCount;

    @Schema(description = "사용 중인 용량 (bytes)", example = "10485760000")
    private Long usedSize;

    @Schema(description = "사용 중인 용량 (읽기 쉬운 형식)", example = "9.77 GB")
    private String usedSizeFormatted;

    @Schema(description = "전체 디스크 용량 (bytes)", example = "1000000000000")
    private Long totalDiskSpace;

    @Schema(description = "전체 디스크 용량 (읽기 쉬운 형식)", example = "931.32 GB")
    private String totalDiskSpaceFormatted;

    @Schema(description = "남은 저장공간 (bytes)", example = "500000000000")
    private Long freeSpace;

    @Schema(description = "남은 저장공간 (읽기 쉬운 형식)", example = "465.66 GB")
    private String freeSpaceFormatted;

    @Schema(description = "사용 가능한 공간 (bytes)", example = "480000000000")
    private Long usableSpace;

    @Schema(description = "사용 가능한 공간 (읽기 쉬운 형식)", example = "447.03 GB")
    private String usableSpaceFormatted;

    @Schema(description = "디스크 사용률 (%)", example = "50.5")
    private Double usagePercentage;

    @JsonFormatDttm private ZonedDateTime lastModifiedDate;

    public ZonedDateTime getLastModifiedDate() {
      return ZonedDateTime.now();
    }
  }
}
