<?php

namespace App\Components\Dashboard;

use App\Models\Claim\Claim;
use App\Models\Claim\Status;
use App\Models\Claim\StatusHistory;
use App\Models\Client\Client;
use Livewire\Component;

class Stats extends Component
{
    public function render()
    {
        $statuses = Status::whereIn('display_name', [
            'Missing ID/POA',
            'Investigation - DSAR Activity',
            'Closed',
            'Sent To Redress',
            'APP Number Received',
            'Investigation - DSARs Sent',
            'Part Dsar Received',
        ])->get(['id', 'display_name', 'sort_order']);

        $statusIds        = $statuses->pluck('id', 'display_name');
        $statusSortOrders = $statuses->pluck('sort_order', 'display_name');

        // Stock metrics — clients currently sitting at each stage
        $missingIdPoaCount  = $this->currentClientsInStatus($statusIds['Missing ID/POA'] ?? null);
        $investigationCount = $this->currentClientsInStatus($statusIds['Investigation - DSAR Activity'] ?? null);

        $investigationSort  = $statusSortOrders['Investigation - DSAR Activity'] ?? null;
        $closedSort         = $statusSortOrders['Closed'] ?? null;
        $activelyClaimingCount = ($investigationSort !== null && $closedSort !== null)
            ? Claim::whereHas('status', fn($q) => $q
                ->where('sort_order', '>=', $investigationSort)
                ->where('sort_order', '<', $closedSort)
            )->count()
            : 0;

        // Throughput metrics — clients who entered each stage in the period
        $clientsToday = Client::whereDate('created_at', today())->count();
        $clientsWeek  = Client::whereBetween('created_at', [now()->startOfWeek(), now()])->count();
        $clientsMonth = Client::whereBetween('created_at', [now()->startOfMonth(), now()])->count();

        $sentToRedressToday = $this->distinctClientsInStatus($statusIds['Sent To Redress'] ?? null, today(), now());
        $sentToRedressWeek  = $this->distinctClientsInStatus($statusIds['Sent To Redress'] ?? null, now()->startOfWeek(), now());
        $sentToRedressMonth = $this->distinctClientsInStatus($statusIds['Sent To Redress'] ?? null, now()->startOfMonth(), now());

        $appNumberToday = $this->distinctClientsInStatus($statusIds['APP Number Received'] ?? null, today(), now());
        $appNumberWeek  = $this->distinctClientsInStatus($statusIds['APP Number Received'] ?? null, now()->startOfWeek(), now());
        $appNumberMonth = $this->distinctClientsInStatus($statusIds['APP Number Received'] ?? null, now()->startOfMonth(), now());

        $status24Today = $this->distinctClientsInStatus($statusIds['Investigation - DSAR Activity'] ?? null, today(), now());
        $status24Week  = $this->distinctClientsInStatus($statusIds['Investigation - DSAR Activity'] ?? null, now()->startOfWeek(), now());
        $status24Month = $this->distinctClientsInStatus($statusIds['Investigation - DSAR Activity'] ?? null, now()->startOfMonth(), now());

        $status34Today = $this->distinctClientsInStatus($statusIds['Investigation - DSARs Sent'] ?? null, today(), now());
        $status34Week  = $this->distinctClientsInStatus($statusIds['Investigation - DSARs Sent'] ?? null, now()->startOfWeek(), now());
        $status34Month = $this->distinctClientsInStatus($statusIds['Investigation - DSARs Sent'] ?? null, now()->startOfMonth(), now());

        $partDsarToday = $this->distinctClientsInStatus($statusIds['Part Dsar Received'] ?? null, today(), now());
        $partDsarWeek  = $this->distinctClientsInStatus($statusIds['Part Dsar Received'] ?? null, now()->startOfWeek(), now());
        $partDsarMonth = $this->distinctClientsInStatus($statusIds['Part Dsar Received'] ?? null, now()->startOfMonth(), now());

        $closedToday = $this->distinctClientsInStatus($statusIds['Closed'] ?? null, today(), now());
        $closedWeek  = $this->distinctClientsInStatus($statusIds['Closed'] ?? null, now()->startOfWeek(), now());
        $closedMonth = $this->distinctClientsInStatus($statusIds['Closed'] ?? null, now()->startOfMonth(), now());

        return view('components.dashboard.stats', compact(
            'missingIdPoaCount', 'investigationCount', 'activelyClaimingCount',
            'clientsToday', 'clientsWeek', 'clientsMonth',
            'sentToRedressToday', 'sentToRedressWeek', 'sentToRedressMonth',
            'appNumberToday', 'appNumberWeek', 'appNumberMonth',
            'status24Today', 'status24Week', 'status24Month',
            'status34Today', 'status34Week', 'status34Month',
            'partDsarToday', 'partDsarWeek', 'partDsarMonth',
            'closedToday', 'closedWeek', 'closedMonth',
        ));
    }

    private function currentClientsInStatus(?int $statusId): int
    {
        if ($statusId === null) {
            return 0;
        }

        return Claim::where('status_id', $statusId)->count();
    }

    private function distinctClientsInStatus(?int $statusId, $from, $to): int
    {
        if ($statusId === null) {
            return 0;
        }

        return StatusHistory::where('status_histories.status_id', $statusId)
            ->where('status_histories.subject_type', Claim::class)
            ->whereBetween('status_histories.started_at', [$from, $to])
            ->join('claims', 'claims.id', '=', 'status_histories.subject_id')
            ->distinct()
            ->count('claims.client_id');
    }
}
