<?php

namespace App\Livewire\Parent;

use App\Domain\Attendance\Models\AttendanceRecord;
use App\Domain\Identity\Models\Guardian;
use App\Domain\Identity\Services\GuardianResolver;
use App\Domain\Participant\Models\Participant;
use Carbon\Carbon;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;

#[Layout('layouts.parent')]
#[Title('سجل الحضور - بوابة ولي الأمر')]
class ParentAttendance extends Component
{
    use WithPagination;

    #[Url]
    public ?int $month = null;

    #[Url]
    public ?int $year = null;

    public function mount(): void
    {
        $this->month = $this->month ?? now()->month;
        $this->year = $this->year ?? now()->year;
    }

    public function previousMonth(): void
    {
        $date = Carbon::create($this->year, $this->month, 1)->subMonth();
        $this->month = $date->month;
        $this->year = $date->year;
        $this->resetPage();
    }

    public function nextMonth(): void
    {
        $date = Carbon::create($this->year, $this->month, 1)->addMonth();
        $this->month = $date->month;
        $this->year = $date->year;
        $this->resetPage();
    }

    public function render()
    {
        $childrenIds = $this->getChildrenIds();
        $activeChildId = session('active_child_id', $childrenIds[0] ?? null);

        if (! in_array($activeChildId, $childrenIds)) {
            $activeChildId = $childrenIds[0] ?? null;
        }

        $monthStart = Carbon::create($this->year, $this->month, 1)->startOfMonth()->toDateString();
        $monthEnd = Carbon::create($this->year, $this->month, 1)->endOfMonth()->toDateString();

        $monthLabel = Carbon::create($this->year, $this->month, 1)->translatedFormat('F Y');

        // Summary counts
        $baseQuery = AttendanceRecord::where('subject_type', Participant::class)
            ->where('subject_id', $activeChildId)
            ->whereHas('session', fn ($q) => $q->whereBetween('session_date', [$monthStart, $monthEnd]));

        $totalRecords = (clone $baseQuery)->whereNotIn('status', ['cancelled', 'exempt'])->count();
        $presentCount = (clone $baseQuery)->where('status', 'present')->count();
        $lateCount = (clone $baseQuery)->where('status', 'late')->count();
        $absentCount = (clone $baseQuery)->where('status', 'absent')->count();
        $excusedCount = (clone $baseQuery)->where('status', 'excused')->count();

        $attendanceRate = $totalRecords > 0
            ? round((($presentCount + $lateCount) / $totalRecords) * 100, 1)
            : null;

        // Paginated records
        $records = AttendanceRecord::where('subject_type', Participant::class)
            ->where('subject_id', $activeChildId)
            ->whereHas('session', fn ($q) => $q->whereBetween('session_date', [$monthStart, $monthEnd]))
            ->with(['session.group.program'])
            ->orderByDesc(
                \App\Domain\Training\Models\TrainingSession::select('session_date')
                    ->whereColumn('training_sessions.id', 'attendance_records.training_session_id')
                    ->limit(1)
            )
            ->paginate(20);

        return view('livewire.parent.parent-attendance', [
            'records' => $records,
            'monthLabel' => $monthLabel,
            'totalRecords' => $totalRecords,
            'presentCount' => $presentCount,
            'lateCount' => $lateCount,
            'absentCount' => $absentCount,
            'excusedCount' => $excusedCount,
            'attendanceRate' => $attendanceRate,
            'activeChildId' => $activeChildId,
        ]);
    }

    private function getGuardian(): Guardian
    {
        $user = auth()->user();

        // Display only. Authorisation and scoping go through GuardianResolver:
        // ->first() on a non-unique column meant a guardian holding two rows
        // saw one set of children and was 403'd on the rest, and an adult
        // member with no guardian row hard-failed on every screen here.
        return app(GuardianResolver::class)->guardiansFor($user)->first()
            ?? Guardian::where('user_id', $user->id)->firstOrFail();
    }

    private function getChildrenIds(): array
    {
        return app(GuardianResolver::class)->participantIdsFor(auth()->user());
    }
}
