<?php

namespace App\Models;

use Carbon\CarbonInterface;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class TenantPackage extends Model
{
    use HasFactory;

    protected $table = 'tenant_packages';

    protected $fillable = [
        'tenant_id',
        'package_id',
        'paddle_subscription_id',
        'price',
        'purchased_at',
        'expires_at',
        'used_events',
        'active',
    ];

    protected $casts = [
        'price' => 'decimal:2',
        'purchased_at' => 'datetime',
        'expires_at' => 'datetime',
        'used_events' => 'integer',
        'active' => 'boolean',
        'event_warning_sent_at' => 'datetime',
        'event_warning_threshold' => 'float',
        'event_limit_notified_at' => 'datetime',
        'expiry_warning_sent_at' => 'datetime',
        'expired_notified_at' => 'datetime',
    ];

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

    public function package(): BelongsTo
    {
        return $this->belongsTo(Package::class)->withTrashed();
    }

    public function isActive(): bool
    {
        if ($this->package && $this->package->isEndcustomer()) {
            return (bool) $this->active;
        }

        return $this->active && (! $this->expires_at || $this->expires_at->isFuture());
    }

    public function canCreateEvent(): bool
    {
        if (! $this->isActive()) {
            return false;
        }

        if (! $this->package->isReseller()) {
            return false;
        }

        $maxEvents = $this->package->max_events_per_year;

        if ($maxEvents === null) {
            return true;
        }

        $maxEvents = max(0, (int) $maxEvents);

        return $this->used_events < $maxEvents;
    }

    public function getRemainingEventsAttribute(): ?int
    {
        if (! $this->package->isReseller()) {
            return 0;
        }

        $max = $this->package->max_events_per_year;

        if ($max === null) {
            return null;
        }

        $max = max(0, (int) $max);

        return max(0, $max - $this->used_events);
    }

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

        static::creating(function (self $tenantPackage) {
            if (! $tenantPackage->purchased_at) {
                $tenantPackage->purchased_at = now();
            }

            $package = $tenantPackage->package;

            if ($package && $package->isReseller()) {
                // Reseller packages represent prepaid Event-Kontingente and should not expire by default.
            } elseif (! $tenantPackage->expires_at) {
                $tenantPackage->expires_at = now()->addYear();
            }

            if ($tenantPackage->active === null) {
                $tenantPackage->active = true;
            }
        });

        static::updating(function (self $tenantPackage) {
            $package = $tenantPackage->package;

            if ($package && $package->isReseller()) {
                if (
                    $tenantPackage->isDirty('expires_at')
                    && $tenantPackage->expires_at instanceof CarbonInterface
                    && $tenantPackage->expires_at->isPast()
                ) {
                    $tenantPackage->active = false;
                }

                return;
            }
        });
    }
}
