package com.arms.api.report.rolling3m.model.vo;

import com.fasterxml.jackson.annotation.JsonValue;
import lombok.Getter;
import lombok.experimental.SuperBuilder;

import java.util.List;

@Getter
@SuperBuilder(toBuilder = true)
public class Rolling3mBaseVO {

    /** 모든 이슈에 대한 상태별 카운트와 완료율 */
    private Long total;
    private Long completed;
    private Long inProgress;
    private Long open;
    private Double completionRate;

    /** 모든 요구사항 이슈(isReq=true)에 대한 상태별 카운트와 완료율 */
    private Long reqTotal;
    private Long reqCompleted;
    private Long reqInProgress;
    private Long reqOpen;
    private Double reqCompletionRate;

    /** 모든 alm 이슈(isReq=false, almIssue)에 대한 상태별 카운트와 완료 */
    private Long issueTotal;
    private Long issueCompleted;
    private Long issueInProgress;
    private Long issueOpen;
    private Double issueCompletionRate;

    // 매우 높음의 기준: 매우 높음, 또는 높음 + status가 open인 건수
    private Long highPriorityOpen;
    private Long reqHighPriorityOpen;
    private Long issueHighPriorityOpen;

    /** 요구사항 이슈들에 한해서 mysql의 c_req_priority_value를 기준으로 5그룹 분포 */
    private ReqIssuePriorityDistributionVO priorityDistribution;
    /** 요구사항 이슈들에 한해서 난이도별로 카운트 통계 */
    private ReqIssueDifficultyDistributionVO difficultyDistribution;

    /** 상태 */
    private Status scopeStatus;
    private Status timeStatus;
    private Status resourceStatus;
    private Status overallStatus;

    public enum Status {
        GOOD, CAUTION, CRITICAL;

        @JsonValue
        public String toValue() {
            return name().toLowerCase();
        }
    }

    public static Status determineScopeStatus(double completionRate) {
        if (completionRate < 50.0) return Status.CRITICAL;
        if (completionRate >= 75.0) return Status.GOOD;
        return Status.CAUTION;
    }

    public static Status determineTimeStatus(long issueOverdue) {
        if (issueOverdue < 1) return Status.GOOD;
        if (issueOverdue >= 3) return Status.CRITICAL;
        return Status.CAUTION;
    }

    public static Status determineResourceStatus(double loadRatio) {
        if (loadRatio < 1.2) return Status.GOOD;
        if (loadRatio > 1.5) return Status.CRITICAL;
        return Status.CAUTION;
    }

    public static Status determineOverallStatus(Status scopeStatus, Status timeStatus, Status resourceStatus) {
        List<Status> statuses = List.of(scopeStatus, timeStatus, resourceStatus);
        if (statuses.contains(Status.CRITICAL)) return Status.CRITICAL;
        if (statuses.stream().allMatch(Status.GOOD::equals)) return Status.GOOD;
        return Status.CAUTION;
    }

    public static double calculateRatio(long value, double average) {
        if (average == 0) return 0.0;
        return roundToOneDecimal(value / average);
    }

    private static double roundToOneDecimal(double value) {
        return Math.round(value * 10.0) / 10.0;
    }
}
