<?php

namespace App\Models;

use App\Enums\ReservationSource;
use App\Enums\ReservationStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Str;

class Reservation extends Model
{
    use HasFactory;

    protected $fillable = [
        'reservation_code',
        'user_id',
        'guest_phone_normalized',
        'guest_phone_raw',
        'guest_name',
        'source',
        'created_by_owner_id',
        'sms_sent_at',
        'listing_id',
        'listing_availability_id',
        'listing_schedule_id',
        'reservation_date',
        'guest_count',
        'unit_price',
        'total_amount',
        'status',
        'customer_note',
        'owner_note',
        'approved_at',
        'rejected_at',
        'cancelled_at',
        'completed_at',
    ];

    protected function casts(): array
    {
        return [
            'reservation_date' => 'date',
            'unit_price' => 'decimal:2',
            'total_amount' => 'decimal:2',
            'status' => ReservationStatus::class,
            'source' => ReservationSource::class,
            'sms_sent_at' => 'datetime',
            'approved_at' => 'datetime',
            'rejected_at' => 'datetime',
            'cancelled_at' => 'datetime',
            'completed_at' => 'datetime',
        ];
    }

    /**
     * Boot the model
     */
    protected static function boot()
    {
        parent::boot();

        static::creating(function ($reservation) {
            if (empty($reservation->reservation_code)) {
                $reservation->reservation_code = self::generateReservationCode();
            }
        });
    }

    /**
     * Generate unique reservation code
     */
    public static function generateReservationCode(): string
    {
        do {
            $code = 'KG' . strtoupper(Str::random(8));
        } while (self::where('reservation_code', $code)->exists());

        return $code;
    }

    /**
     * Customer who made the reservation
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    /**
     * Alias for user - customer
     */
    public function customer(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id');
    }

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

    /**
     * Kaptan tarafından manuel eklenmişse kaydı oluşturan kullanıcı
     */
    public function createdByOwner(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by_owner_id');
    }

    /**
     * Availability slot being reserved (eski yapı - geriye uyumluluk)
     */
    public function availability(): BelongsTo
    {
        return $this->belongsTo(ListingAvailability::class, 'listing_availability_id');
    }

    /**
     * Schedule being reserved (yeni yapı)
     */
    public function schedule(): BelongsTo
    {
        return $this->belongsTo(ListingSchedule::class, 'listing_schedule_id');
    }

    /**
     * Approve the reservation
     */
    public function approve(?string $note = null): void
    {
        $this->update([
            'status' => ReservationStatus::APPROVED,
            'approved_at' => now(),
            'owner_note' => $note,
        ]);
    }

    /**
     * Reject the reservation
     */
    public function reject(?string $note = null): void
    {
        $this->update([
            'status' => ReservationStatus::REJECTED,
            'rejected_at' => now(),
            'owner_note' => $note,
        ]);
        
        // Release capacity
        $this->releaseCapacity();
    }

    /**
     * Cancel the reservation
     */
    public function cancel(): void
    {
        $this->update([
            'status' => ReservationStatus::CANCELLED,
            'cancelled_at' => now(),
        ]);
        
        // Release capacity
        $this->releaseCapacity();
    }

    /**
     * Release capacity (hem eski hem yeni yapı için)
     */
    protected function releaseCapacity(): void
    {
        // Yeni yapı: schedule
        if ($this->listing_schedule_id && $this->schedule) {
            $this->schedule->releaseCapacity($this->guest_count);
        }
        // Eski yapı: availability (geriye uyumluluk)
        elseif ($this->listing_availability_id && $this->availability) {
            $this->availability->releaseSlots($this->guest_count);
        }
    }

    /**
     * Mark as completed
     */
    public function markAsCompleted(): void
    {
        $this->update([
            'status' => ReservationStatus::COMPLETED,
            'completed_at' => now(),
        ]);
    }

    /**
     * Check if reservation can be cancelled
     */
    public function canBeCancelled(): bool
    {
        return in_array($this->status, [
            ReservationStatus::PENDING,
            ReservationStatus::APPROVED,
        ]);
    }

    /**
     * Scope for pending reservations
     */
    public function scopePending($query)
    {
        return $query->where('status', ReservationStatus::PENDING);
    }

    /**
     * Scope for approved reservations
     */
    public function scopeApproved($query)
    {
        return $query->where('status', ReservationStatus::APPROVED);
    }

    public function review(): HasOne
    {
        return $this->hasOne(CaptainReview::class);
    }
}
