<?php

namespace App\Models;

use App\Enums\BookingStatusEnum;
use App\Observers\BookingObserver;
use App\Traits\FilterableTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Booking extends Model
{
    use HasFactory, FilterableTrait;

    protected array $filterable = ['status', 'member_id', 'game_id', 'court_id', 'booking_date'];
    protected array $searchable = ['booking_reference'];
    protected array $sortable = ['id', 'booking_date', 'start_time', 'status', 'created_at'];

    protected $fillable = [
        'booking_reference',
        'member_id',
        'game_id',
        'court_id',
        'booking_date',
        'start_time',
        'end_time',
        'players_count',
        'status',
    ];

    protected function casts(): array
    {
        return [
            'member_id'     => 'integer',
            'game_id'       => 'integer',
            'court_id'      => 'integer',
            'booking_date'  => 'date',
            'players_count' => 'integer',
            'status'        => 'integer',
        ];
    }

    protected static function boot()
    {
        parent::boot();
        static::observe(BookingObserver::class);
    }

    public function member()
    {
        return $this->belongsTo(Member::class);
    }

    public function game()
    {
        return $this->belongsTo(Game::class);
    }

    public function court()
    {
        return $this->belongsTo(Court::class);
    }

    public function participants()
    {
        return $this->hasMany(BookingParticipant::class);
    }

    public function scopeForIndex($query)
    {
        return $query->select([
            'id', 'booking_reference', 'member_id', 'game_id', 'court_id',
            'booking_date', 'start_time', 'end_time', 'players_count', 'status', 'created_at',
        ]);
    }

    public function scopeForShow($query)
    {
        return $query->with([
            'member',
            'game',
            'court',
            'participants.member',
            'participants.dependent',
        ]);
    }

    public function scopeCurrent($query)
    {
            //  intger 1 for current
        return $query->where('booking_date', '>=', now()->toDateString())
            ->whereIn('status', [
                BookingStatusEnum::PENDING->value,
                BookingStatusEnum::CONFIRMED->value,
                BookingStatusEnum::ONGOING->value,
            ]);
    }

    public function scopeHistory($query)
    {
        //  intger 2 for history

        return $query->where(function ($q) {
            $q->where('booking_date', '<', now()->toDateString())
                ->orWhereIn('status', [
                    BookingStatusEnum::COMPLETED->value,
                    BookingStatusEnum::CANCELLED->value,
                ]);
        });
    }


    public function scopeForMemberOwnerOrParticipant($query, Member $member)
    {
        return $query->where(function ($q) use ($member) {
            $q->where('member_id', $member->id)
                ->orWhereHas('participants', fn ($p) => $p->where('member_id', $member->id));
        });
    }

   
    public function scopeToday($query)
    {
        return $query->whereDate('booking_date', now()->toDateString());
    }

    /** @param  \Illuminate\Database\Eloquent\Builder<static>  $query */
    public function scopeOnBookingDate($query, string $date): \Illuminate\Database\Eloquent\Builder
    {
        return $query->whereDate('booking_date', $date);
    }
}
