<?php

namespace App\Livewire\Portal;

use App\Domain\Attendance\Models\AttendanceRecord;
use App\Domain\Participant\Models\Participant;
use App\Domain\Training\Enums\EvaluationStatus;
use App\Domain\Training\Models\Evaluation;
use App\Domain\Training\Models\TrainingSession;
use App\Livewire\Portal\Concerns\PortalScreen;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Attributes\Url;
use Livewire\Component;

/**
 * One session-centric timeline rather than separate schedule and attendance
 * screens.
 *
 * A member does not think "my schedule" and "my attendance" — they think about
 * a session: when it is, who is taking it, whether they were there, whether
 * they can be excused from it. Splitting that across two tabs is what made the
 * old portal feel like a database.
 *
 * Trainer identity and `substitute_reason` are loaded because a parent whose
 * child had a different coach on Tuesday is owed the reason, and the columns
 * have always been there unread. Cancellations carry `cancelled_reason` for
 * the same reason: an empty week must not read the same as Eid.
 */
#[Layout('layouts.portal')]
#[Title('التدريب')]
class PortalTraining extends Component
{
    use PortalScreen;

    /** upcoming | past */
    #[Url(as: 'v')]
    public string $view = 'upcoming';

    public function mount(): void
    {
        $this->authorizePortal();
    }

    public function updatedView(): void
    {
        if (! in_array($this->view, ['upcoming', 'past'], true)) {
            $this->view = 'upcoming';
        }
    }

    public function render()
    {
        $participantId = $this->activeParticipantId();
        $participant = $this->portal()->activeParticipant();

        $groupIds = $participant
            ? $participant->activeEnrollments()->pluck('training_group_id')->all()
            : [];

        $sessions = collect();
        $attendance = collect();

        if ($groupIds !== []) {
            $query = TrainingSession::whereIn('training_group_id', $groupIds)
                ->with(['group.program', 'facility', 'trainer.person', 'assistantTrainer.person']);

            $sessions = $this->view === 'upcoming'
                ? $query->where('session_date', '>=', now()->toDateString())
                    ->orderBy('session_date')->orderBy('start_time')->limit(30)->get()
                : $query->where('session_date', '<', now()->toDateString())
                    ->orderByDesc('session_date')->orderByDesc('start_time')->limit(30)->get();

            // One query for every session on screen rather than one per row.
            $attendance = AttendanceRecord::where('subject_type', Participant::class)
                ->where('subject_id', $participantId)
                ->whereIn('training_session_id', $sessions->pluck('id'))
                ->get()
                ->keyBy('training_session_id');
        }

        return view('livewire.portal.portal-training', [
            'sessions' => $sessions,
            'attendance' => $attendance,
            'evaluations' => Evaluation::where('participant_id', $participantId)
                ->where('status', EvaluationStatus::Shared)
                ->with('group')
                ->orderByDesc('evaluation_date')
                ->limit(5)
                ->get(),
        ]);
    }
}
