<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Str;

class Program extends Model
{
    use HasFactory;

    protected $fillable = [
        'uuid', 'title', 'description', 'organizer', 'location',
        'start_date', 'end_date',
        'checkin_start_at', 'checkin_end_at',
        'ecert_download_start_at', 'ecert_download_end_at',
        'status', 'allow_walk_in',
        'default_staff_session', 'default_external_session',
        'created_by',
    ];

    protected function casts(): array
    {
        return [
            'start_date'              => 'date',
            'end_date'                => 'date',
            'checkin_start_at'        => 'datetime',
            'checkin_end_at'          => 'datetime',
            'ecert_download_start_at' => 'datetime',
            'ecert_download_end_at'   => 'datetime',
            'allow_walk_in'           => 'boolean',
        ];
    }

    protected static function boot(): void
    {
        parent::boot();
        static::creating(fn($model) => $model->uuid ??= (string) Str::uuid());
    }

    public function getRouteKeyName(): string
    {
        return 'uuid';
    }

    public function creator()
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    public function qrCode()
    {
        return $this->hasOne(ProgramQrCode::class)->where('is_active', true)->latestOfMany();
    }

    public function qrCodes()
    {
        return $this->hasMany(ProgramQrCode::class);
    }

    public function participants()
    {
        return $this->belongsToMany(Participant::class, 'program_participants')
                    ->withPivot(['registration_source', 'is_pre_registered', 'pre_registered_session', 'status', 'registered_at'])
                    ->withTimestamps();
    }

    public function programParticipants()
    {
        return $this->hasMany(ProgramParticipant::class);
    }

    public function attendances()
    {
        return $this->hasMany(Attendance::class);
    }

    public function certificateTemplate()
    {
        return $this->hasOne(CertificateTemplate::class)->where('is_active', true)->latestOfMany();
    }

    public function certificateTemplates()
    {
        return $this->hasMany(CertificateTemplate::class);
    }

    public function certificates()
    {
        return $this->hasMany(Certificate::class);
    }

    public function questionnaire()
    {
        return $this->hasOne(ProgramQuestionnaire::class);
    }

    public function questionnaireSets()
    {
        return $this->belongsToMany(QuestionnaireSet::class, 'program_questionnaires')
                    ->withPivot(['is_confirmed', 'confirmed_at', 'confirmed_by'])
                    ->withTimestamps();
    }

    public function isCheckinOpen(): bool
    {
        $now = now();
        return $this->status === 'published'
            && $this->checkin_start_at
            && $now->between($this->checkin_start_at, $this->checkin_end_at ?? $now->addYear());
    }

    public function isDownloadOpen(): bool
    {
        $now = now();
        return $this->status === 'published'
            && $this->ecert_download_start_at
            && $now->gte($this->ecert_download_start_at)
            && (! $this->ecert_download_end_at || $now->lte($this->ecert_download_end_at));
    }
}
