<?php

declare(strict_types=1);

namespace App\Models;

use App\Enums\PricingMode;
use App\Enums\SessionType;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Room extends Model
{
    protected $guarded = [];

    protected function casts(): array
    {
        return [
            'pricing_mode' => PricingMode::class,
            'hourly_rate' => 'decimal:2',
            'hourly_rate_with_engineer' => 'decimal:2',
            'day_rate' => 'decimal:2',
            'takes_engineer' => 'boolean',
            'package_redeemable' => 'boolean',
            'is_active' => 'boolean',
        ];
    }

    public function addons(): HasMany
    {
        return $this->hasMany(RoomAddon::class);
    }

    public function bookings(): HasMany
    {
        return $this->hasMany(Booking::class);
    }

    public function scopeActive(Builder $query): Builder
    {
        return $query->where('is_active', true);
    }

    public function isHourly(): bool
    {
        return $this->pricing_mode === PricingMode::Hourly;
    }

    public function isDayRate(): bool
    {
        return $this->pricing_mode === PricingMode::DayRate;
    }

    /**
     * The hourly rate for a given session type.
     *
     * Studio C has takes_engineer = false and no with-engineer rate, so an
     * engineer-led request there falls back to the standard rate rather than
     * returning null and producing a £0 booking.
     */
    public function rateFor(?SessionType $sessionType): string
    {
        if ($sessionType === SessionType::WithEngineer
            && $this->takes_engineer
            && $this->hourly_rate_with_engineer !== null) {
            return $this->hourly_rate_with_engineer;
        }

        return $this->hourly_rate ?? '0.00';
    }

    /** How many slot rows a full day in this room occupies. */
    public function slotsPerDay(): int
    {
        return (int) ($this->day_length_hours * 60 / config('studio.slot_minutes'));
    }

    /** How many slot rows the room's minimum session occupies. */
    public function minimumSlots(): int
    {
        return (int) ($this->min_hours * 60 / config('studio.slot_minutes'));
    }
}
