<?php

namespace App\Models\Clients;

use App\Models\Auth\User;
use App\Models\Products\LicenseToken;
use App\Models\Environments\Environment;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Client extends Model
{
    use HasFactory, SoftDeletes;

    protected $table = 'clients';

    /**
     * Campos que se pueden asignar masivamente.
     */
    protected $fillable = [
        'name',
        'shortname',
        'crm_id',
        'cif',
        'razon_social',
        'fecha_inicio_relacion',
        'description',
        'contacts',
        'jira',
        'actived',
        'metadata',
        'observation',
    ];

    /**
     * Casts para tipos seguros.
     */
    protected $casts = [
        'actived' => 'boolean',
        'metadata'   => 'array',
        'fecha_inicio_relacion' => 'date',
        'contacts' => 'array',
    ];

    /**
     * Accessor para asegurar que contacts siempre sea un array.
     */
    public function getContactsAttribute($value)
    {
        if (is_array($value)) {
            return $value;
        }

        if (is_string($value)) {
            $decoded = json_decode($value, true);
            return is_array($decoded) ? $decoded : [];
        }

        return [];
    }

    /**
     * Un cliente tiene muchos usuarios vinculados.
     */
    public function users()
    {
        return $this->belongsToMany(
            User::class,
            'client_user',
            'client_id',
            'user_id'
        );
    }

    /**
     * Un cliente tiene muchos entornos.
     */
    public function environments()
    {
        return $this->hasMany(Environment::class);
    }

    /**
     * Un cliente tiene muchos tokens de licencia.
     */
    public function tokens()
    {
        return $this->hasMany(LicenseToken::class);
    }

    /**
     * Determina el estado de las licencias del cliente.
     *
     * @return string 'activo'|'vencen_pronto'|'vencida'|'desactivada'
     */
    public function getLicenseStatus(): string
    {
        $tokens = $this->tokens;

        // Si no hay tokens, consideramos desactivada
        if ($tokens->isEmpty()) {
            return 'desactivada';
        }

        // Obtener todas las licencias activas
        $activeTokens = $tokens->where('active', true);

        // Si todas las licencias están desactivadas
        if ($activeTokens->isEmpty()) {
            return 'desactivada';
        }

        $now = Carbon::now();
        $oneMonthFromNow = $now->copy()->addMonth();

        $hasExpired = false;
        $hasExpiringSoon = false;

        foreach ($activeTokens as $token) {
            if (!$token->end_at) {
                // Si no tiene fecha de vencimiento, se considera activa
                continue;
            }

            $endAt = Carbon::parse($token->end_at);

            // Verificar si está vencida (hoy o antes)
            if ($endAt->lte($now)) {
                $hasExpired = true;
            }
            // Verificar si vence pronto (dentro de un mes o menos, pero en el futuro)
            elseif ($endAt->lte($oneMonthFromNow)) {
                $hasExpiringSoon = true;
            }
        }

        // Prioridad: vencida > vencen pronto > activo
        if ($hasExpired) {
            return 'vencida';
        }

        if ($hasExpiringSoon) {
            return 'vencen_pronto';
        }

        return 'activo';
    }
}

