<?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;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;

class DeliveryAgent extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'user_id',
        'agent_code',
        'phone',
        'vehicle_type',
        'vehicle_number',
        'license_number',
        'address',
        'city',
        'state',
        'pincode',
        'latitude',
        'longitude',
        'status',
        'is_online',
        'availability_status',
        'total_deliveries',
        'total_earnings',
        'rating',
        'rating_count',
        'last_active_at',
    ];

    protected function casts(): array
    {
        return [
            'latitude' => 'decimal:8',
            'longitude' => 'decimal:8',
            'is_online' => 'boolean',
            'total_deliveries' => 'integer',
            'total_earnings' => 'decimal:2',
            'rating' => 'decimal:2',
            'rating_count' => 'integer',
            'last_active_at' => 'datetime',
        ];
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

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

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

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

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

    public function activeAssignments(): HasMany
    {
        return $this->assignments()
            ->whereNotIn('status', ['delivered', 'cancelled', 'rejected']);
    }

    public function isAvailable(): bool
    {
        return $this->is_online 
            && $this->availability_status === 'online'
            && $this->status === 'active';
    }

    public function updateLocation(float $latitude, float $longitude): void
    {
        $this->update([
            'latitude' => $latitude,
            'longitude' => $longitude,
            'last_active_at' => now(),
        ]);
    }

    protected static function boot(): void
    {
        parent::boot();

        static::creating(function ($agent) {
            if (empty($agent->agent_code)) {
                $agent->agent_code = static::generateAgentCode();
            }
        });

        static::created(function ($agent) {
            // Create wallet for new agent
            DeliveryWallet::create([
                'delivery_agent_id' => $agent->id,
            ]);
        });
    }

    protected static function generateAgentCode(): string
    {
        do {
            $code = 'DA-' . strtoupper(uniqid());
        } while (static::where('agent_code', $code)->exists());

        return $code;
    }
}
