<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class ListingAvailability extends Model
{
    use HasFactory;

    protected $fillable = [
        'listing_id',
        'date',
        'start_time',
        'end_time',
        'available_slots',
        'booked_slots',
        'is_available',
    ];

    protected function casts(): array
    {
        return [
            'date' => 'date',
            'start_time' => 'datetime:H:i',
            'end_time' => 'datetime:H:i',
            'is_available' => 'boolean',
        ];
    }

    /**
     * Listing this availability belongs to
     */
    public function listing(): BelongsTo
    {
        return $this->belongsTo(Listing::class);
    }

    /**
     * Reservations for this availability
     */
    public function reservations(): HasMany
    {
        return $this->hasMany(Reservation::class);
    }

    /**
     * Get remaining slots
     */
    public function getRemainingSlots(): int
    {
        return $this->available_slots - $this->booked_slots;
    }

    /**
     * Check if has available slots
     */
    public function hasAvailableSlots(int $requiredSlots = 1): bool
    {
        return $this->is_available && $this->getRemainingSlots() >= $requiredSlots;
    }

    /**
     * Book slots
     */
    public function bookSlots(int $slots): void
    {
        $this->increment('booked_slots', $slots);
        
        if ($this->getRemainingSlots() <= 0) {
            $this->update(['is_available' => false]);
        }
    }

    /**
     * Release slots
     */
    public function releaseSlots(int $slots): void
    {
        $this->decrement('booked_slots', $slots);
        
        if ($this->getRemainingSlots() > 0 && !$this->is_available) {
            $this->update(['is_available' => true]);
        }
    }

    /**
     * Scope for available slots
     */
    public function scopeAvailable($query)
    {
        return $query->where('is_available', true);
    }

    /**
     * Scope for future dates
     */
    public function scopeFuture($query)
    {
        return $query->where('date', '>=', now()->toDateString());
    }
}
