<?php

namespace App\Components\Report;

use App\Models\Solicitor\Solicitor;
use App\Services\Dashboard\DashboardMetrics as M;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Carbon;
use Livewire\Attributes\Url;
use Livewire\Component;

/**
 * Cohort (by created-date range) report. The user picks a from/to window; the
 * report takes the set of clients CREATED in that window and shows how far that
 * same set has progressed through the pipeline TO DATE — a conversion/cohort
 * view for judging how an intake (e.g. a campaign week) is performing.
 *
 * Contrast with App\Components\Report\KpiReport, which buckets each metric by
 * WHEN the event happened across the last 12 periods. Here the created-date range
 * is the only bound: milestone rows are cumulative (ever reached) and the
 * "currently in status" rows are live counts (not the 5pm snapshots), because a
 * snapshot cannot be attributed to a creation cohort.
 *
 * Figures come from the same App\Services\Dashboard\DashboardMetrics service, so
 * they reconcile with the rest of the reporting suite.
 */
class CohortReport extends Component
{
    use AuthorizesRequests;

    #[Url]
    public ?string $from = null;

    #[Url]
    public ?string $to = null;

    public function mount(): void
    {
        $this->authorize('reports.trends');

        $this->from ??= Carbon::now()->subDays(29)->toDateString();
        $this->to ??= Carbon::now()->toDateString();
    }

    public function render()
    {
        [$from, $to] = $this->window();

        $metrics = new M(app(Solicitor::class)?->id, null);

        return view('components.report.cohort-report', [
            'rows'      => $this->build($metrics, $from, $to),
            'fromLabel' => $from->format('j M Y'),
            'toLabel'   => $to->format('j M Y'),
            'days'      => $from->diffInDays($to) + 1,
        ]);
    }

    /**
     * Parsed, sane [from, to] Carbon range. Falls back to a 30-day window on bad
     * input and swaps the bounds if they were entered the wrong way round.
     */
    private function window(): array
    {
        try {
            $from = Carbon::parse($this->from)->startOfDay();
        } catch (\Throwable) {
            $from = Carbon::now()->subDays(29)->startOfDay();
        }

        try {
            $to = Carbon::parse($this->to)->endOfDay();
        } catch (\Throwable) {
            $to = Carbon::now()->endOfDay();
        }

        return $from->greaterThan($to) ? [$to->copy()->startOfDay(), $from->copy()->endOfDay()] : [$from, $to];
    }

    /**
     * The metric rows for the cohort. Mirrors the KpiReport metric list, but every
     * value is a single cumulative/live figure for the cohort rather than a
     * per-period series. Row types: int, pct, ratio, days, and 'current' (live
     * count of the cohort now in a status — the cohort analogue of KpiReport's
     * snapshot 'stock' rows).
     */
    private function build(M $m, Carbon $from, Carbon $to): array
    {
        $leads       = $m->leadsCreated($from, $to);
        $contacted   = $m->cohortContacted($from, $to);
        $cSent       = $m->cohortContractsSent($from, $to);
        $cSigned     = $m->cohortContractsSigned($from, $to);
        $redress     = $m->cohortReachedStatus(M::STATUS_SENT_TO_REDRESS, $from, $to);
        $appRecv     = $m->cohortReachedStatus(M::STATUS_APP_NUMBER, $from, $to);
        $readyDsar   = $m->cohortReachedStatus(M::STATUS_INVESTIGATION, $from, $to);
        $dsarClients = $m->cohortClientsWithDsarSent($from, $to);
        $dsarSent    = $m->cohortDsarsSent($from, $to);
        $partDsar    = $m->cohortReachedStatus(M::STATUS_PART_DSAR, $from, $to);
        $closed      = $m->cohortReachedStatus(M::STATUS_CLOSED, $from, $to);
        $tAnother    = $m->cohortClosedWithTag(M::TAG_CLOSED_ANOTHER_FIRM, $from, $to);
        $tNoContact  = $m->cohortClosedWithTag(M::TAG_CLOSED_NO_CONTACT, $from, $to);
        $tNoCriteria = $m->cohortClosedWithTag(M::TAG_CLOSED_NO_CRITERIA, $from, $to);
        $tDuplicate  = $m->cohortClosedWithTag(M::TAG_CLOSED_DUPLICATE, $from, $to);

        // Live "where is the cohort now" counts (replace KpiReport's snapshot rows).
        $cWelcome  = $m->cohortCurrentlyInStatus(M::STATUS_WELCOME_CALL, $from, $to);
        $cWaiting  = $m->cohortCurrentlyInStatus(M::STATUS_SENT_TO_REDRESS, $from, $to);
        $cMissing  = $m->cohortCurrentlyInStatus(M::STATUS_MISSING_ID, $from, $to);
        $cInvest   = $m->cohortCurrentlyInStatus(M::STATUS_INVESTIGATION, $from, $to);
        $cActively = $m->cohortActivelyClaiming($from, $to);

        $avg = $m->cohortAvgAppLeadTime($from, $to);

        // Cumulative conversion of the cohort (num ÷ den), null when den is zero.
        $rate   = fn (int $num, int $den) => $den === 0 ? null : round($num / $den * 100, 1);
        $avgPer = fn (int $num, int $den) => $den === 0 ? null : round($num / $den, 1);

        return [
            ['label' => 'Leads In', 'sub' => '(created)', 'type' => 'int', 'note' => 'Cohort size — clients created in the range', 'value' => $leads],
            ['label' => 'Client Contacted', 'sub' => '', 'type' => 'int', 'note' => 'Cohort clients ever marked Contact Made', 'value' => $contacted],
            ['label' => 'Lead In to Contacted rate', 'sub' => '', 'type' => 'pct', 'note' => 'Client Contacted ÷ Leads In', 'value' => $rate($contacted, $leads)],
            ['label' => 'Now at Welcome Call', 'sub' => '', 'type' => 'current', 'note' => 'Cohort claims currently in Welcome Call (live)', 'value' => $cWelcome],
            ['label' => 'Contracts Sent', 'sub' => '', 'type' => 'int', 'note' => 'Cohort clients ever sent a contract via eSign', 'value' => $cSent],
            ['label' => 'Client Contacted to Contracts Sent rate', 'sub' => '', 'type' => 'pct', 'note' => 'Contracts Sent ÷ Client Contacted', 'value' => $rate($cSent, $contacted)],
            ['label' => 'Contracts Signed', 'sub' => '', 'type' => 'int', 'note' => 'Cohort clients ever signing a contract', 'value' => $cSigned],
            ['label' => 'Sign up rate', 'sub' => '', 'type' => 'pct', 'note' => 'Contracts Signed ÷ Contracts Sent', 'value' => $rate($cSigned, $cSent)],
            ['label' => 'Sent To Redress', 'sub' => '(Parts 1/3)', 'type' => 'int', 'note' => 'Cohort claims ever reaching Part 1/3 Sent To Redress', 'value' => $redress],
            ['label' => 'Lead In to Sent To Redress rate', 'sub' => '', 'type' => 'pct', 'note' => 'Sent To Redress ÷ Leads In', 'value' => $rate($redress, $leads)],
            ['label' => 'Now Waiting on APP Number', 'sub' => '', 'type' => 'current', 'note' => 'Cohort claims currently in Parts 1/3 Sent To Redress (live)', 'value' => $cWaiting],
            ['label' => 'APP Number Received', 'sub' => '', 'type' => 'int', 'note' => 'Cohort claims ever reaching APP Number Received', 'value' => $appRecv],
            ['label' => 'Average APP Number Lead Time', 'sub' => '', 'type' => 'days', 'note' => 'Avg days Sent To Redress → APP Number Received, cohort claims that reached APP', 'value' => $avg],
            ['label' => 'Now Missing ID/POA', 'sub' => '', 'type' => 'current', 'note' => 'Cohort claims currently in Missing ID/POA (live)', 'value' => $cMissing],
            ['label' => 'Ready For DSAR', 'sub' => '', 'type' => 'int', 'note' => 'Cohort claims ever reaching Investigation - DSAR Activity', 'value' => $readyDsar],
            ['label' => 'Clients DSAR Sent', 'sub' => '', 'type' => 'int', 'note' => 'Distinct cohort clients with at least one DSAR sent', 'value' => $dsarClients],
            ['label' => 'Now in Investigation - DSAR Activity', 'sub' => '', 'type' => 'current', 'note' => 'Cohort claims currently in Investigation - DSAR Activity (live)', 'value' => $cInvest],
            ['label' => 'Individual DSARs sent', 'sub' => '', 'type' => 'int', 'note' => 'DSARs sent for the cohort (created, past draft/approved)', 'value' => $dsarSent],
            ['label' => 'Average DSARs per client', 'sub' => '', 'type' => 'ratio', 'note' => 'Individual DSARs sent ÷ Clients DSAR Sent', 'value' => $avgPer($dsarSent, $dsarClients)],
            ['label' => 'Part Dsar Received', 'sub' => '', 'type' => 'int', 'note' => 'Cohort claims ever reaching Part Dsar Received', 'value' => $partDsar],
            ['label' => 'Now Actively Claiming', 'sub' => '', 'type' => 'current', 'note' => 'Cohort claims currently Investigation - DSAR Activity or greater and not closed (live)', 'value' => $cActively],
            ['label' => 'Closed', 'sub' => '', 'type' => 'int', 'note' => 'Cohort claims ever reaching Closed', 'value' => $closed],
            ['label' => 'Closed', 'sub' => '— with another firm', 'type' => 'int', 'note' => 'Closed with applicable tag', 'value' => $tAnother],
            ['label' => 'Closed', 'sub' => '— no contact', 'type' => 'int', 'note' => 'Closed with applicable tag', 'value' => $tNoContact],
            ['label' => 'Closed', 'sub' => '— does not meet criteria', 'type' => 'int', 'note' => 'Closed with applicable tag', 'value' => $tNoCriteria],
            ['label' => 'Closed', 'sub' => '— duplicate', 'type' => 'int', 'note' => 'Closed with applicable tag', 'value' => $tDuplicate],
        ];
    }
}
