<?php

namespace App\Models;

use App\Enums\CompanyStatus;
use App\Models\Concerns\HasUuid;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Support\PublicMedia;

class Company extends Model
{
    use HasFactory, SoftDeletes, HasUuid;

    protected $fillable = [
        'uuid', 'name', 'slug', 'legal_name',
        'document_type', 'document_number',
        'email', 'phone', 'whatsapp', 'website',
        'address', 'city', 'state', 'country', 'postal_code',
        'latitude', 'longitude',
        'logo_path', 'cover_path', 'primary_color', 'secondary_color',
        'description', 'social_links',
        'timezone', 'locale', 'currency',
        'booking_buffer_minutes', 'booking_min_advance_minutes', 'booking_max_advance_days',
        'allow_guest_booking', 'allow_customer_cancel', 'allow_customer_reschedule',
        'cancellation_hours_limit',
        'status', 'plan_id',
        'trial_ends_at', 'subscription_starts_at', 'subscription_ends_at',
        'suspended_at', 'suspension_reason',
        'settings',
    ];

    protected function casts(): array
    {
        return [
            'status'                       => CompanyStatus::class,
            'social_links'                 => 'array',
            'settings'                     => 'array',
            'latitude'                     => 'decimal:7',
            'longitude'                    => 'decimal:7',
            'allow_guest_booking'          => 'boolean',
            'allow_customer_cancel'        => 'boolean',
            'allow_customer_reschedule'    => 'boolean',
            'trial_ends_at'                => 'datetime',
            'subscription_starts_at'       => 'datetime',
            'subscription_ends_at'         => 'datetime',
            'suspended_at'                 => 'datetime',
        ];
    }

    /* ------------------------------------------------------------------
     | Relaciones
     |------------------------------------------------------------------*/

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

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

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

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

    public function mainBranch(): HasOne
    {
        return $this->hasOne(Branch::class)->where('is_main', true);
    }

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

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

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

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

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

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

    public function activeSubscription(): HasOne
    {
        return $this->hasOne(Subscription::class)
            ->whereIn('status', ['trial', 'active'])
            ->latestOfMany();
    }

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

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

    public function modules(): BelongsToMany
    {
        return $this->belongsToMany(Module::class, 'company_modules')
            ->withPivot('is_enabled', 'notes')
            ->withTimestamps();
    }

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

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

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

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

    /* ------------------------------------------------------------------
     | Scopes
     |------------------------------------------------------------------*/

    public function scopeActive(Builder $q): Builder
    {
        return $q->whereIn('status', ['trial', 'active']);
    }

    public function scopeSuspended(Builder $q): Builder
    {
        return $q->where('status', 'suspended');
    }

    /* ------------------------------------------------------------------
     | Helpers
     |------------------------------------------------------------------*/

    public function isOperational(): bool
    {
        return $this->status->canOperate();
    }

    public function isOnTrial(): bool
    {
        return $this->status === CompanyStatus::Trial
            && $this->trial_ends_at?->isFuture();
    }

    public function publicUrl(): string
    {
        return url('/empresa/'.$this->slug);
    }

    public function logoUrl(): ?string
    {
        return $this->publicAssetUrl($this->logo_path);
    }

    public function coverUrl(): ?string
    {
        return $this->publicAssetUrl($this->cover_path);
    }

    private function publicAssetUrl(?string $path): ?string
    {
        return PublicMedia::url($path);
    }

    public function getRouteKeyName(): string
    {
        return 'uuid';
    }
}
