<?php

namespace App\Models;

use App\Casts\PointCast;
use App\Observers\ScooterObserver;
use App\Services\WalletService;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use MatanYadaev\EloquentSpatial\Objects\Point;
use MatanYadaev\EloquentSpatial\Traits\HasSpatial;

class Scooter extends Model
{
    use HasFactory, HasSpatial;

    protected $guarded = ['id', 'created_at', 'updated_at', 'deleted_at'];

    protected $casts = [
        'init_location' => Point::class,
        'location'      => Point::class,
        // 'init_location' => PointCast::class,
        // 'location'      => PointCast::class,
    ];

    protected $appends = ['image', 'base_fare', 'price_per_minute', 'gift_mony', 'can_use_it'];

    protected static function boot()
    {
        parent::boot();
        Scooter::observe(ScooterObserver::class);
    }

    public function getImageAttribute()
    {
        $media = $this->media()->where('option', 'image')->first();
        $image = $media ? asset('storage/images/scooters/' . $media->media) : null;
        return $media ? ['id' => (int) $media->id, 'media' => $image] : null;
    }

    public function getImageShowAttribute()
    {
        $media = $this->media()->where('option', 'image')->first();
        $image = $media ? asset('storage/images/scooters/' . $media->media) : null;
        return $image;
    }

    public function getBaseFareAttribute()
    {
        return $this->type == 'scooter' ? setting('scooter_base_fare') ?? 5 : setting('bicycle_base_fare') ?? 5;
    }

    public function getPricePerMinuteAttribute()
    {
        return $this->type == 'scooter' ? setting('scooter_price_per_minute') ?? 5 : setting('bicycle_price_per_minute') ?? 5;
    }

    public function getGiftMonyAttribute()
    {
        return $this->type == 'scooter' ? setting('scooter_gift_mony') ?? 5 : setting('bicycle_gift_mony') ?? 5;
    }

    public function getCanUseItAttribute()
    {
        return $this->last_battery_percentage > 30 ? true : false;
    }

    public function getCanUseItDependingOnBalanceAttribute()
    {
        $availableBalance = (new WalletService())->getBalance();

        return $availableBalance >= ($this->base_fare + $this->price_per_minute * 10);
    }

    public function scopeAvailable($query)
    {
        return $query->where(['is_active' => true, 'in_order' => false])
            ->whereDoesntHave('trips', function ($query) {
                return $query->whereNotIn('status', ['ended', 'canceled', 'auto_canceled', 'auto_stop']);
            });
    }

    public function media()
    {
        return $this->morphOne(AppMedia::class, 'app_mediaable');
    }

    public function area()
    {
        return $this->belongsTo(Area::class);
    }

    public function greenAreas()
    {
        return $this->belongsToMany(Area::class, AreaScooter::class)->withTimestamps();
    }

    public function trips()
    {
        return $this->hasMany(Trip::class);
    }
}
