<?php

namespace App\Livewire\Parent;

use App\Domain\Identity\Models\Guardian;
use App\Domain\Identity\Services\GuardianResolver;
use App\Domain\Participant\Models\Participant;
use App\Domain\Training\Enums\SessionStatus;
use App\Domain\Training\Models\TrainingSchedule;
use App\Domain\Training\Models\TrainingSession;
use Carbon\Carbon;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;

#[Layout('layouts.parent')]
#[Title('الجدول الأسبوعي - بوابة ولي الأمر')]
class ParentSchedule extends Component
{
    public int $weekOffset = 0;

    public ?string $selectedDate = null;

    public function mount(): void
    {
        $this->selectedDate = now()->toDateString();
    }

    public function previousWeek(): void
    {
        $this->weekOffset--;
    }

    public function nextWeek(): void
    {
        $this->weekOffset++;
    }

    public function selectDate(string $date): void
    {
        $this->selectedDate = $date;
    }

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

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

        // Get active group IDs for the selected child
        $activeGroupIds = [];
        if ($activeChildId) {
            $participant = Participant::find($activeChildId);
            if ($participant) {
                $activeGroupIds = $participant->activeEnrollments()
                    ->pluck('training_group_id')
                    ->toArray();
            }
        }

        // Calculate week boundaries
        $weekStart = now()->startOfWeek(Carbon::SATURDAY)->addWeeks($this->weekOffset);
        $weekEnd = $weekStart->copy()->addDays(6);

        // Days of the week for navigation
        $weekDays = [];
        for ($i = 0; $i < 7; $i++) {
            $day = $weekStart->copy()->addDays($i);
            $weekDays[] = [
                'date' => $day->toDateString(),
                'day_name' => $day->translatedFormat('l'),
                'day_number' => $day->format('d'),
                'is_today' => $day->isToday(),
                'is_selected' => $day->toDateString() === $this->selectedDate,
            ];
        }

        // Get recurring schedules for the active groups
        $schedules = collect();
        if (! empty($activeGroupIds)) {
            $schedules = TrainingSchedule::whereIn('training_group_id', $activeGroupIds)
                ->where('is_active', true)
                ->effectiveOn($this->selectedDate ?? now()->toDateString())
                ->with(['group.program', 'facility', 'trainer'])
                ->get();
        }

        // Get actual sessions for the selected date
        $sessions = collect();
        if (! empty($activeGroupIds) && $this->selectedDate) {
            $sessions = TrainingSession::whereIn('training_group_id', $activeGroupIds)
                ->where('session_date', $this->selectedDate)
                ->with(['group.program', 'facility', 'trainer'])
                ->orderBy('start_time')
                ->get();
        }

        // Get all sessions for the week (for indicators on day selector)
        $weekSessions = collect();
        if (! empty($activeGroupIds)) {
            $weekSessions = TrainingSession::whereIn('training_group_id', $activeGroupIds)
                ->whereBetween('session_date', [$weekStart->toDateString(), $weekEnd->toDateString()])
                ->select('session_date', 'status')
                ->get()
                ->groupBy(fn ($s) => $s->session_date->toDateString());
        }

        return view('livewire.parent.parent-schedule', [
            'weekDays' => $weekDays,
            'weekStart' => $weekStart,
            'weekEnd' => $weekEnd,
            'schedules' => $schedules,
            'sessions' => $sessions,
            'weekSessions' => $weekSessions,
            '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());
    }
}
