<?php

namespace App\Support\Witness;

/**
 * Computed progress / readiness snapshot for a witness statement. Built by
 * WitnessStatementService::progress(). Pure data — no persistence.
 */
class WitnessProgress
{
    /**
     * @param  int  $totalQuestions  Total questions across the questionnaire.
     * @param  int  $answeredQuestions  Questions with a non-empty answer.
     * @param  int  $requiredTotal  Required questions.
     * @param  int  $requiredAnswered  Required questions answered.
     * @param  array<int, array{section:string,question:string,label:string}>  $requiredUnanswered
     * @param  array<string, array{answered:int,total:int,percent:int}>  $sections  keyed by section key
     * @param  array<string, array{answered:int,total:int,percent:int}>  $groups  keyed by group name
     * @param  int  $awaitingReview  Suggested answers not yet accepted/rejected.
     * @param  array<int, array{section:string,question:string,label:string}>  $conflicts
     * @param  array<int, string>  $missingEvidenceSections  Sections that accept evidence but have none.
     */
    public function __construct(
        public readonly int $totalQuestions,
        public readonly int $answeredQuestions,
        public readonly int $requiredTotal,
        public readonly int $requiredAnswered,
        public readonly array $requiredUnanswered,
        public readonly array $sections,
        public readonly array $groups,
        public readonly int $awaitingReview,
        public readonly int $acceptedSuggestions,
        public readonly array $conflicts,
        public readonly array $missingEvidenceSections,
        public readonly int $exhibitCount,
        public readonly int $suggestionsTotal = 0,
    ) {}

    public function suggestionsReviewed(): int
    {
        return max(0, $this->suggestionsTotal - $this->awaitingReview);
    }

    public function overallPercent(): int
    {
        if ($this->totalQuestions === 0) {
            return 0;
        }

        return (int) round(($this->answeredQuestions / $this->totalQuestions) * 100);
    }

    public function requiredPercent(): int
    {
        if ($this->requiredTotal === 0) {
            return 100;
        }

        return (int) round(($this->requiredAnswered / $this->requiredTotal) * 100);
    }

    /**
     * A statement is ready to generate when every required question is answered,
     * no suggested answer is still awaiting review, and there are no conflicts.
     */
    public function isReadyToGenerate(): bool
    {
        return $this->requiredUnanswered === []
            && $this->awaitingReview === 0
            && $this->conflicts === [];
    }

    /**
     * The blocking issues, most-actionable first, for the readiness panel. Each
     * carries a call-to-action and (where known) the section to jump to so the
     * "next best action" resolves the top blocker directly.
     *
     * @return array<int, array{type:string,message:string,cta:string,section:?string,count:int}>
     */
    public function blockers(): array
    {
        $blockers = [];

        if (($n = count($this->requiredUnanswered)) > 0) {
            $blockers[] = [
                'type' => 'required',
                'message' => $n.' required '.($n === 1 ? 'answer is' : 'answers are').' missing',
                'cta' => 'Complete '.$n.' required '.($n === 1 ? 'answer' : 'answers'),
                'section' => $this->requiredUnanswered[0]['section'] ?? null,
                'count' => $n,
            ];
        }

        if ($this->awaitingReview > 0) {
            $blockers[] = [
                'type' => 'review',
                'message' => $this->awaitingReview.' evidence '.($this->awaitingReview === 1 ? 'suggestion needs' : 'suggestions need').' review',
                'cta' => 'Review '.$this->awaitingReview.' evidence '.($this->awaitingReview === 1 ? 'suggestion' : 'suggestions'),
                'section' => null,
                'count' => $this->awaitingReview,
            ];
        }

        if (($n = count($this->conflicts)) > 0) {
            $blockers[] = [
                'type' => 'conflict',
                'message' => $n.' conflicting '.($n === 1 ? 'answer' : 'answers').' to resolve',
                'cta' => 'Resolve '.$n.' conflicting '.($n === 1 ? 'answer' : 'answers'),
                'section' => $this->conflicts[0]['section'] ?? null,
                'count' => $n,
            ];
        }

        return $blockers;
    }

    /**
     * The single highest-priority blocker, or null when ready to generate.
     *
     * @return array{type:string,message:string,cta:string,section:?string,count:int}|null
     */
    public function primaryBlocker(): ?array
    {
        return $this->blockers()[0] ?? null;
    }
}
