<?php

namespace App\Models;

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

class Subscription extends Model
{
    use HasFactory;

    const STATUS_INACTIVE = 0;

    const STATUS_ACTIVE = 1;

    const STATUS_EXPIRED = 2;

    protected $guarded = [];

    protected $casts = [
        'start_date' => 'date',
        'end_date' => 'date',
        'activated_at' => 'datetime',
        'allowed_merchant_types' => 'array',
    ];

    protected $appends = [
        'end_date',
        'remaining_days',
        'is_active',
        'is_expired',
        'status_badge',
    ];

    public function getRouteKeyName()
    {
        return 'code';
    }

    /**
     * Get the user that owns the subscription
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    /**
     * Get the end date of the subscription
     */
    public function getEndDateAttribute(): Carbon
    {
        return $this->start_date->addDays($this->duration_in_days);
    }

    /**
     * Get remaining days until expiration
     */
    public function getRemainingDaysAttribute(): int
    {
        $now = now();
        $endDate = $this->end_date;

        if ($now->isAfter($endDate)) {
            return 0;
        }

        return $now->diffInDays($endDate, false);
    }

    /**
     * Check if subscription is active
     */
    public function isActive(): bool
    {
        return $this->status === self::STATUS_ACTIVE &&
               now()->isBefore($this->start_date->addDays($this->duration_in_days));
    }

    /**
     * Get is_active attribute
     */
    public function getIsActiveAttribute(): bool
    {
        return $this->isActive();
    }

    /**
     * Check if subscription is expired
     */
    public function isExpired(): bool
    {
        return now()->isAfter($this->end_date);
    }

    /**
     * Get is_expired attribute
     */
    public function getIsExpiredAttribute(): bool
    {
        return $this->isExpired();
    }

    /**
     * Deactivate the subscription
     */
    public function deactivate(): void
    {
        $this->update(['status' => self::STATUS_INACTIVE]);
    }

    /**
     * Get the computed status based on expiration
     */
    public function getComputedStatusAttribute(): string
    {
        if ($this->isActive()) {
            return 'active';
        } elseif ($this->isExpired()) {
            return 'expired';
        } else {
            return 'inactive';
        }
    }

    /**
     * Scope for active subscriptions
     */
    public function scopeActive($query)
    {
        $driver = $query->getConnection()->getDriverName();

        if ($driver === 'sqlite') {
            return $query->where('status', self::STATUS_ACTIVE)
                ->whereRaw('DATE(start_date, "+" || duration_in_days || " days") > DATE(?)', [now()]);
        } else {
            // MySQL/PostgreSQL
            return $query->where('status', self::STATUS_ACTIVE)
                ->whereRaw('DATE_ADD(start_date, INTERVAL duration_in_days DAY) > ?', [now()]);
        }
    }

    /**
     * Scope for expired subscriptions
     */
    public function scopeExpired($query)
    {
        $driver = $query->getConnection()->getDriverName();

        if ($driver === 'sqlite') {
            return $query->whereRaw('DATE(start_date, "+" || duration_in_days || " days") <= DATE(?)', [now()]);
        } else {
            // MySQL/PostgreSQL
            return $query->whereRaw('DATE_ADD(start_date, INTERVAL duration_in_days DAY) <= ?', [now()]);
        }
    }

    /**
     * Get subscription data in the format expected by the API
     */
    public function toApiArray(): array
    {
        return [
            'id' => $this->id,
            'category' => $this->category,
            'start_date' => $this->start_date->format('Y-m-d'),
            'end_date' => $this->end_date->format('Y-m-d'),
            'duration_days' => $this->duration_in_days,
            'remaining_days' => $this->remaining_days,
            'status' => $this->computed_status,
            'is_expired' => $this->is_expired,
            'is_active' => $this->is_active,
            'code_used' => $this->code,
            'created_at' => $this->created_at->format('Y-m-d H:i:s'),
        ];
    }

    /**
     * Create or update subscription from API data
     */
    public static function createOrUpdate(array $data): self
    {
        // First, deactivate any existing active subscriptions
        static::where('status', static::STATUS_ACTIVE)
            ->update(['status' => static::STATUS_INACTIVE]);

        // Set default values if not provided
        $data = array_merge([
            'slug' => \Illuminate\Support\Str::orderedUuid(),
            'start_date' => now(),
            'end_date' => now()->addDays($data['duration_in_days'] ?? 30),
            'duration_in_days' => $data['duration_in_days'] ?? 30,
            'status' => static::STATUS_ACTIVE,
        ], $data);

        return static::create($data);
    }

    public function badge(string $label, string $color, string $icon)
    {
        return '<span class="inline-flex items-center px-2.5 py-0.5 rounded text-xs font-medium bg-'.$color.'-100 text-'.$color.'-800 border border-'.$color.'-400 min-w-30 justify-center">
            <i class="ph ph-'.$icon.' -ml-0.5 mr-1.5 text-'.$color.'-400"></i>
            '.$label.'
        </span>';
    }

    public function getStatusBadgeAttribute()
    {
        if ($this->status == self::STATUS_ACTIVE) {
            return $this->badge('Actif', 'green', 'check-circle');
        } elseif ($this->status == self::STATUS_EXPIRED) {
            return $this->badge('Expiré', 'red', 'x-circle');
        } else {
            return $this->badge('Inactif', 'gray', 'minus-circle');
        }
    }
}
