<?php

namespace App\Models;

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

class Boarding extends Model
{
    use HasFactory;

    protected $table = 'boardings';

    protected $fillable = [
        'vessel_id',
        'captain_id',
        'fishing_type_id',
        'departure_datetime',
        'expected_return_datetime',
        'actual_return_datetime',
        'departure_location',
        'departure_point_id',
        'crew_count',
        'crew_list',
        'fishing_zones',
        'expected_catch',
        'fuel_quantity',
        'ice_quantity',
        'supplies_notes',
        'fiscal_id',
        'weather_conditions',
        'sea_conditions',
        'status',
        'emergency_contact_made',
        'emergency_notes',
        'notes',
        'metadata',
    ];

    protected $casts = [
        'departure_datetime' => 'datetime',
        'expected_return_datetime' => 'datetime',
        'actual_return_datetime' => 'datetime',
        'crew_list' => 'array',
        'expected_catch' => 'array',
        'emergency_contact_made' => 'boolean',
        'fuel_quantity' => 'decimal:2',
        'ice_quantity' => 'decimal:2',
        'metadata' => 'array',
    ];

    // Status constants
    const STATUS_SCHEDULED = 'scheduled';
    const STATUS_DEPARTED = 'departed';
    const STATUS_AT_SEA = 'at_sea';
    const STATUS_RETURNED = 'returned';
    const STATUS_OVERDUE = 'overdue';
    const STATUS_CANCELLED = 'cancelled';
    const STATUS_EMERGENCY = 'emergency';

    const STATUS_LIST = [
        self::STATUS_SCHEDULED => 'Agendada',
        self::STATUS_DEPARTED => 'Partiu',
        self::STATUS_AT_SEA => 'No Mar',
        self::STATUS_RETURNED => 'Retornou',
        self::STATUS_OVERDUE => 'Atrasada',
        self::STATUS_CANCELLED => 'Cancelada',
        self::STATUS_EMERGENCY => 'Emergência',
    ];

    // Relationships
    public function vessel()
    {
        return $this->belongsTo(Vessel::class);
    }

    public function captain()
    {
        return $this->belongsTo(Fisherman::class, 'captain_id');
    }

    public function fishingType()
    {
        return $this->belongsTo(FishingType::class);
    }

    public function departurePoint()
    {
        return $this->belongsTo(FishingPoint::class, 'departure_point_id');
    }

    public function fiscal()
    {
        return $this->belongsTo(Fiscal::class);
    }

    public function landing()
    {
        return $this->hasOne(Landing::class);
    }

    public function infractions()
    {
        return $this->hasMany(FishingInfraction::class);
    }

    // Scopes
    public function scopeActive($query)
    {
        return $query->whereIn('status', [self::STATUS_DEPARTED, self::STATUS_AT_SEA]);
    }

    public function scopeOverdue($query)
    {
        return $query->where('status', self::STATUS_OVERDUE)
            ->orWhere(function($q) {
                $q->whereIn('status', [self::STATUS_DEPARTED, self::STATUS_AT_SEA])
                  ->where('expected_return_datetime', '<', now());
            });
    }

    public function scopeReturned($query)
    {
        return $query->where('status', self::STATUS_RETURNED);
    }

    // Accessors
    public function getStatusTextAttribute()
    {
        return self::STATUS_LIST[$this->status] ?? $this->status;
    }

    public function getDepartureDateTimeFormattedAttribute()
    {
        return $this->departure_datetime ? $this->departure_datetime->format('d/m/Y H:i') : '-';
    }

    public function getExpectedReturnDateTimeFormattedAttribute()
    {
        return $this->expected_return_datetime ? $this->expected_return_datetime->format('d/m/Y H:i') : '-';
    }

    public function getDurationAttribute()
    {
        if (!$this->actual_return_datetime) return null;
        return $this->departure_datetime->diffInHours($this->actual_return_datetime);
    }

    public function getIsOverdueAttribute()
    {
        return $this->status === self::STATUS_OVERDUE ||
            ($this->expected_return_datetime && $this->expected_return_datetime->isPast() &&
             !in_array($this->status, [self::STATUS_RETURNED, self::STATUS_CANCELLED]));
    }

    // Methods
    public function depart()
    {
        $this->update(['status' => self::STATUS_DEPARTED]);
    }

    public function return($actualReturnDatetime = null, $notes = null)
    {
        $this->update([
            'status' => self::STATUS_RETURNED,
            'actual_return_datetime' => $actualReturnDatetime ?? now(),
            'notes' => $notes ?? $this->notes,
        ]);
    }

    public function markEmergency($notes = null)
    {
        $this->update([
            'status' => self::STATUS_EMERGENCY,
            'emergency_notes' => $notes,
            'emergency_contact_made' => true,
        ]);
    }

    public function cancel($reason = null)
    {
        $this->update([
            'status' => self::STATUS_CANCELLED,
            'notes' => $reason ?? $this->notes,
        ]);
    }
}
