package com.arms.api.report.rolling3m.service;

import com.arms.api.report.rolling3m.assignee.model.vo.AssigneeVO;
import com.arms.api.report.rolling3m.assignee.service.AssigneeService;
import com.arms.api.report.rolling3m.model.vo.*;
import com.arms.api.report.rolling3m.assignee.model.dto.Rolling3mDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Service
@RequiredArgsConstructor
public class Rolling3mReportServiceImpl implements Rolling3mReportService {

    private final AssigneeService assigneeService;

    private final IssueStateService issueStateService;

    private final TeamAverageStatByStateService teamAverageStatService;

    private final RequirementDistributionService requirementDistributionService;

    private final PdServiceAndVersionService pdServiceAndVersionService;

    private static final Long UNDEFINED_VALUE = 1L;

    /**
     * 최신3개월_담당자_실적_집계
     */
    @Override
    public Rolling3mAssigneeReportVO rolling3mReportByAssignee(Rolling3mDTO rolling3mDTO) {
        Rolling3mAssigneeReportVO.Rolling3mAssigneeReportVOBuilder<?, ?> builder =
                Rolling3mAssigneeReportVO.builder();

        AssigneeVO assigneeVO = assigneeService.selectAssigneeDisplayName(rolling3mDTO);
        builder.assigneeId(assigneeVO.getAccountId());
        builder.assigneeName(assigneeVO.getDisplayName());

        IssueArmsStateCountVO stateCountVO = issueStateService.selectStateCountVOByAssignee(rolling3mDTO, null);
        builder.total(stateCountVO.getTotal());
        builder.completed(stateCountVO.getCompleted());
        builder.inProgress(stateCountVO.getInProgress());
        builder.open(stateCountVO.getOpen());
        builder.completionRate(stateCountVO.getCompletionRate());

        IssueArmsStateCountVO reqStateCountVO = issueStateService.selectStateCountVOByAssignee(rolling3mDTO, Boolean.TRUE);
        builder.reqTotal(reqStateCountVO.getTotal());
        builder.reqCompleted(reqStateCountVO.getCompleted());
        builder.reqInProgress(reqStateCountVO.getInProgress());
        builder.reqOpen(reqStateCountVO.getOpen());
        builder.reqCompletionRate(reqStateCountVO.getCompletionRate());

        IssueArmsStateCountVO almIssueStateCountVO = issueStateService.selectStateCountVOByAssignee(rolling3mDTO, Boolean.FALSE);
        builder.issueTotal(almIssueStateCountVO.getTotal());
        builder.issueCompleted(almIssueStateCountVO.getCompleted());
        builder.issueInProgress(almIssueStateCountVO.getInProgress());
        builder.issueOpen(almIssueStateCountVO.getOpen());
        builder.issueCompletionRate(almIssueStateCountVO.getCompletionRate());

        builder.priorityDistribution(requirementDistributionService.selectReqIssuePriorityDistributionByAssignee(rolling3mDTO));
        builder.difficultyDistribution(requirementDistributionService.selectReqIssueDifficultyDistributionByAssignee(rolling3mDTO));

        IssueAverageByTeamVO teamStats = teamAverageStatService.selectTeamAverageStatsByAssignee(rolling3mDTO);
        builder.teamAverage(teamStats.getTeamAverage());
        builder.reqTeamAverage(teamStats.getReqTeamAverage());
        builder.issueTeamAverage(teamStats.getIssueTeamAverage());
        builder.loadRatio(Rolling3mBaseVO.calculateRatio(stateCountVO.getTotal(), teamStats.getTeamAverage()));
        builder.reqLoadRatio(Rolling3mBaseVO.calculateRatio(reqStateCountVO.getTotal(), teamStats.getReqTeamAverage()));
        builder.issueLoadRatio(Rolling3mBaseVO.calculateRatio(almIssueStateCountVO.getTotal(), teamStats.getIssueTeamAverage()));

        Rolling3mBaseVO.Status scopeStatus    = Rolling3mBaseVO.determineScopeStatus(stateCountVO.getCompletionRate());
        Rolling3mBaseVO.Status timeStatus     = Rolling3mBaseVO.determineTimeStatus(UNDEFINED_VALUE);
        Rolling3mBaseVO.Status resourceStatus = Rolling3mBaseVO.determineResourceStatus(
                Rolling3mBaseVO.calculateRatio(stateCountVO.getTotal(), teamStats.getTeamAverage()));
        builder.scopeStatus(scopeStatus);
        builder.timeStatus(timeStatus);
        builder.resourceStatus(resourceStatus);
        builder.overallStatus(Rolling3mBaseVO.determineOverallStatus(scopeStatus, timeStatus, resourceStatus));

        return builder.build();
    }

    @Override
    public Rolling3mReportVO rolling3mReport(Rolling3mDTO rolling3mDTO) {
        Rolling3mReportVO.Rolling3mReportVOBuilder<?, ?> builder = Rolling3mReportVO.builder();

        PdServiceVO pdServiceVO = pdServiceAndVersionService.selectPdServiceAndVersion(rolling3mDTO);
        builder.pdServiceName(pdServiceVO.getPdServiceName());
        builder.pdServiceVersionNameList(pdServiceVO.getPdServiceVersionNameList());

        IssueArmsStateCountVO stateCountVO = issueStateService.selectStateCountVO(rolling3mDTO, null);
        builder.total(stateCountVO.getTotal());
        builder.completed(stateCountVO.getCompleted());
        builder.inProgress(stateCountVO.getInProgress());
        builder.open(stateCountVO.getOpen());
        builder.completionRate(stateCountVO.getCompletionRate());

        IssueArmsStateCountVO reqStateCountVO = issueStateService.selectStateCountVO(rolling3mDTO, Boolean.TRUE);
        builder.reqTotal(reqStateCountVO.getTotal());
        builder.reqCompleted(reqStateCountVO.getCompleted());
        builder.reqInProgress(reqStateCountVO.getInProgress());
        builder.reqOpen(reqStateCountVO.getOpen());
        builder.reqCompletionRate(reqStateCountVO.getCompletionRate());

        IssueArmsStateCountVO almIssueStateCountVO = issueStateService.selectStateCountVO(rolling3mDTO, Boolean.FALSE);
        builder.issueTotal(almIssueStateCountVO.getTotal());
        builder.issueCompleted(almIssueStateCountVO.getCompleted());
        builder.issueInProgress(almIssueStateCountVO.getInProgress());
        builder.issueOpen(almIssueStateCountVO.getOpen());
        builder.issueCompletionRate(almIssueStateCountVO.getCompletionRate());

        builder.priorityDistribution(requirementDistributionService.selectReqIssuePriorityDistribution(rolling3mDTO));
        builder.difficultyDistribution(requirementDistributionService.selectReqIssueDifficultyDistribution(rolling3mDTO));

        Rolling3mBaseVO.Status scopeStatus    = Rolling3mBaseVO.determineScopeStatus(stateCountVO.getCompletionRate());
        Rolling3mBaseVO.Status timeStatus     = Rolling3mBaseVO.determineTimeStatus(UNDEFINED_VALUE);
        Rolling3mBaseVO.Status resourceStatus = Rolling3mBaseVO.determineResourceStatus(UNDEFINED_VALUE);

        builder.scopeStatus(scopeStatus);
        builder.timeStatus(timeStatus);
        builder.resourceStatus(resourceStatus);
        builder.overallStatus(Rolling3mBaseVO.determineOverallStatus(scopeStatus, timeStatus, resourceStatus));

        return builder.build();
    }
}
