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

import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

public class TrainingMetricsDto {

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(name = "TrainingMetricsResponse", description = "학습 메트릭 조회 응답")
  public static class Response {

    @Schema(description = "학습 작업 ID (모델 UUID)", example = "b34a2d18-11e6-4b1b-a156-cd314bec45bb")
    private String jobId;

    @Schema(
        description = "기본 경로",
        example = "/data/training/response/b34a2d18-11e6-4b1b-a156-cd314bec45bb-out")
    private String basePath;

    @Schema(description = "데이터 소스 (csv 또는 log)", example = "csv")
    private String source;

    @Schema(description = "응답 상태 (SUCCESS, EMPTY, ERROR)", example = "SUCCESS")
    private String status;

    @Schema(description = "에러 메시지 (오류 발생 시만 포함)")
    private String errorMessage;

    @Schema(description = "Epoch별 학습 메트릭 데이터")
    private List<EpochMetrics> epochs;
  }

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(name = "EpochMetrics", description = "Epoch 단위 메트릭 데이터")
  public static class EpochMetrics {

    @Schema(description = "Epoch 번호", example = "1")
    private Integer epoch;

    @Schema(description = "학습 데이터 (train.csv에서 추출)")
    private TrainMetrics train;

    @Schema(description = "검증 데이터 요약 (val.csv에서 추출)")
    private SummaryMetrics summary;

    @Schema(description = "클래스별 메트릭 (changed, unchanged)")
    private List<ClassMetrics> classes;
  }

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(name = "TrainMetrics", description = "학습 메트릭 (train.csv)")
  public static class TrainMetrics {

    @Schema(description = "Iteration", example = "37")
    @JsonProperty("iteration")
    private Integer iteration;

    @Schema(description = "Loss", example = "0.61584342")
    @JsonProperty("loss")
    private Double loss;

    @Schema(description = "Learning Rate", example = "8.4e-07")
    @JsonProperty("lr")
    private String lr;

    @Schema(description = "처리 시간 (초)", example = "1.5034")
    @JsonProperty("time")
    private Double time;
  }

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(name = "SummaryMetrics", description = "검증 메트릭 요약 (val.csv)")
  public static class SummaryMetrics {

    @Schema(description = "Accuracy (All Accuracy)", example = "29.92")
    @JsonProperty("aAcc")
    private Double aAcc;

    @Schema(description = "Mean F-Score", example = "24.49")
    @JsonProperty("mFscore")
    private Double mFscore;

    @Schema(description = "Mean Precision", example = "51.07")
    @JsonProperty("mPrecision")
    private Double mPrecision;

    @Schema(description = "Mean Recall", example = "64.22")
    @JsonProperty("mRecall")
    private Double mRecall;

    @Schema(description = "Mean IoU (Intersection over Union)", example = "15.49")
    @JsonProperty("mIoU")
    private Double mIoU;

    @Schema(description = "Mean Accuracy", example = "64.22")
    @JsonProperty("mAcc")
    private Double mAcc;
  }

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(name = "ClassMetrics", description = "클래스별 메트릭 (changed/unchanged)")
  public static class ClassMetrics {

    @Schema(description = "클래스명 (changed 또는 unchanged)", example = "unchanged")
    private String className;

    @Schema(description = "F-Score", example = "44.735149")
    private Double fscore;

    @Schema(description = "Precision", example = "99.779264")
    private Double precision;

    @Schema(description = "Recall", example = "28.813878")
    private Double recall;
  }

  @Data
  @Builder
  @NoArgsConstructor
  @AllArgsConstructor
  @Schema(name = "ProcessingLogMetrics", description = "processing.log 파싱 결과 (내부용)")
  public static class ProcessingLogMetrics {

    private Integer epoch;
    private SummaryMetrics summary;
    private List<ClassMetrics> classes;
  }
}
