<?php

namespace App\Models;

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

class Visit extends Model
{
    use HasFactory;

    protected $fillable = [
        'request_id',
        'host_email',
        'host_name',
        'host_phone',
        'location_id',
        'visit_reason',
        'main_visitor_email',
        'meeting_type',
        'date',
        'start_time',
        'end_time',
        'date_from',
        'date_to',
        'status',
        'rejection_reason',
        'registration_token',
        'token_expires_at',
        'visitor_registered_at',
        'reviewed_by_email',
        'reviewed_at',
        'number_of_visitors',
    ];

    protected $casts = [
        'date' => 'date',
        'date_from' => 'date',
        'date_to' => 'date',
        'token_expires_at' => 'datetime',
        'visitor_registered_at' => 'datetime',
        'reviewed_at' => 'datetime',
        'number_of_visitors' => 'integer',
    ];

    /**
     * Get the location for this visit
     */
    public function location()
    {
        return $this->belongsTo(Location::class);
    }

    /**
     * Get the host user for this visit
     */
    public function host()
    {
        return $this->belongsTo(UserRole::class, 'host_email', 'email');
    }

    /**
     * Get the reviewer for this visit
     */
    public function reviewer()
    {
        return $this->belongsTo(UserRole::class, 'reviewed_by_email', 'email');
    }

    /**
     * Get all visitors for this visit
     */
    public function visitors()
    {
        return $this->hasMany(Visitor::class);
    }

    /**
     * Get the main visitor for this visit
     */
    public function mainVisitor()
    {
        return $this->hasOne(Visitor::class)->where('is_main_visitor', true);
    }

    /**
     * Get additional visitors (excluding main visitor)
     */
    public function additionalVisitors()
    {
        return $this->hasMany(Visitor::class)->where('is_main_visitor', false);
    }

    /**
     * Get status history for this visit
     */
    public function statusHistory()
    {
        return $this->hasMany(VisitStatusHistory::class)->orderBy('created_at', 'desc');
    }

    /**
     * Scope to filter by status
     */
    public function scopeStatus($query, string $status)
    {
        return $query->where('status', $status);
    }

    /**
     * Scope to filter by host email
     */
    public function scopeByHost($query, string $email)
    {
        return $query->where('host_email', $email);
    }

    /**
     * Scope to filter by location
     */
    public function scopeByLocation($query, int $locationId)
    {
        return $query->where('location_id', $locationId);
    }

    /**
     * Scope to filter by date range
     */
    public function scopeDateRange($query, $from, $to)
    {
        return $query->whereBetween('date', [$from, $to]);
    }

    /**
     * Scope for today's visits
     */
    public function scopeToday($query)
    {
        return $query->where(function($q) {
            $q->where(function($subQ) {
                // Single meetings: date equals today
                $subQ->where('meeting_type', 'single')
                    ->whereDate('date', today());
            })->orWhere(function($subQ) {
                // Multiple meetings: today is between date_from and date_to
                $subQ->where('meeting_type', 'multiple')
                    ->whereDate('date_from', '<=', today())
                    ->whereDate('date_to', '>=', today());
            });
        });
    }

    /**
     * Check if token is expired
     */
    public function isTokenExpired(): bool
    {
        return $this->token_expires_at < now();
    }

    /**
     * Check if visit can be edited
     */
    public function canBeEdited(): bool
    {
        return in_array($this->status, ['Pending Visitor', 'Pending Approve', 'Pending Host']);
    }

    /**
     * Check if visit can be deleted
     */
    public function canBeDeleted(): bool
    {
        return !in_array($this->status, ['Completed', 'Rejected', 'Expired', 'Canceled']);
    }
}
