<?php
// ARCHIVO: #1 - app/Models/User.php
// VERSIÓN: 2.0 (REVISADO Y CORREGIDO)
// PREDECESORES: Ninguno (archivo base del sistema)
// DESCRIPCIÓN: Modelo principal de usuarios con todas las funcionalidades UrbanOSS
// COMPATIBILIDAD: Laravel 11.47, PHP 8.2+
// FECHA: 2024-01-01
// AUTOR: UrbanOSS Platform

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class User extends Authenticatable
{
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable, SoftDeletes;

    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'users';

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
        'condominio_id',
        'role',
        'telefono',
        'documento',
        'foto',
        'fecha_ingreso',
        'fecha_salida',
        'estado',
        'whatsapp',
        'configuracion',
        'ultimo_acceso',
        'ip_registro',
        'observaciones'
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
            'configuracion' => 'array',
            'ultimo_acceso' => 'datetime',
            'fecha_ingreso' => 'date',
            'fecha_salida' => 'date',
            'deleted_at' => 'datetime',
        ];
    }

    /**
     * Relación con condominio.
     */
    public function condominio(): BelongsTo
    {
        return $this->belongsTo(Condominio::class);
    }

    /**
     * Relación con unidades como propietario.
     */
    public function unidades(): HasMany
    {
        return $this->hasMany(Unidad::class, 'propietario_id');
    }

    /**
     * Relación con pagos realizados.
     */
    public function pagos(): HasMany
    {
        return $this->hasMany(Pago::class);
    }

    /**
     * Relación con notificaciones recibidas.
     */
    public function notificaciones(): HasMany
    {
        return $this->hasMany(Notificacion::class);
    }

    /**
     * Relación con accesos registrados.
     */
    public function accesosRegistrados(): HasMany
    {
        return $this->hasMany(Acceso::class, 'registrado_por');
    }

    /**
     * Relación con pagos aprobados.
     */
    public function pagosAprobados(): HasMany
    {
        return $this->hasMany(Pago::class, 'aprobado_por');
    }

    /**
     * Relación con reclamaciones respondidas.
     */
    public function reclamacionesRespondidas(): HasMany
    {
        return $this->hasMany(Reclamacion::class, 'respondido_por');
    }

    /**
     * Determina si el usuario es superadministrador.
     */
    public function isSuperAdmin(): bool
    {
        return $this->role === 'superadmin';
    }

    /**
     * Determina si el usuario es administrador de condominio.
     */
    public function isAdmin(): bool
    {
        return $this->role === 'admin';
    }

    /**
     * Determina si el usuario es propietario.
     */
    public function isPropietario(): bool
    {
        return $this->role === 'propietario';
    }

    /**
     * Determina si el usuario es inquilino.
     */
    public function isInquilino(): bool
    {
        return $this->role === 'inquilino';
    }

    /**
     * Determina si el usuario es guardia de seguridad.
     */
    public function isGuardia(): bool
    {
        return $this->role === 'guardia';
    }

    /**
     * Obtiene la ruta del dashboard según el rol.
     */
    public function getDashboardRoute(): string
    {
        return match($this->role) {
            'superadmin' => 'admin.superadmin.dashboard',
            'admin' => 'admin.dashboard',
            'propietario', 'inquilino' => 'resident.dashboard',
            'guardia' => 'security.dashboard',
            default => 'home'
        };
    }

    /**
     * Obtiene el mensaje de bienvenida según el rol.
     */
    public function getWelcomeMessage(): string
    {
        $messages = [
            'superadmin' => 'Super Administrador de Plataforma',
            'admin' => 'Administrador de Condominio',
            'propietario' => 'Propietario',
            'inquilino' => 'Inquilino',
            'guardia' => 'Guardia de Seguridad',
        ];

        return $messages[$this->role] ?? 'Usuario';
    }

    /**
     * Obtiene el nombre del contexto (condominio o plataforma).
     */
    public function getContextName(): string
    {
        if ($this->condominio_id && $this->condominio) {
            return $this->condominio->nombre;
        }
        
        return $this->isSuperAdmin() ? 'Plataforma UrbanOSS' : 'Sin Condominio Asignado';
    }

    /**
     * Verifica si el usuario está activo.
     */
    public function isActive(): bool
    {
        return $this->estado === 'activo';
    }

    /**
     * Verifica si el usuario necesita aprobación.
     */
    public function needsApproval(): bool
    {
        return $this->estado === 'pendiente';
    }

    /**
     * Registra el último acceso del usuario.
     */
    public function recordAccess(?string $ip = null): void
    {
        $this->update([
            'ultimo_acceso' => now(),
            'ip_registro' => $ip ?? request()->ip()
        ]);
    }

    /**
     * Genera un token de registro para nuevos usuarios.
     */
    public function generateRegistrationToken(): string
    {
        $token = hash('sha256', $this->email . now()->timestamp . bin2hex(random_bytes(16)));
        
        cache()->put('user_registration_token_' . $token, [
            'user_id' => $this->id,
            'condominio_id' => $this->condominio_id,
            'role' => $this->role,
            'expires_at' => now()->addHours(48)
        ], now()->addHours(48));
        
        return $token;
    }

    /**
     * Valida un token de registro.
     */
    public static function validateRegistrationToken(string $token): ?array
    {
        return cache()->get('user_registration_token_' . $token);
    }

    /**
     * Obtiene el número de WhatsApp formateado.
     */
    public function getWhatsAppNumber(): ?string
    {
        if (empty($this->whatsapp)) {
            return null;
        }
        
        $number = preg_replace('/[^0-9]/', '', $this->whatsapp);
        
        // Asegurar código de país para Perú
        if (strlen($number) === 9 && !str_starts_with($number, '51')) {
            $number = '51' . $number;
        }
        
        return $number;
    }

    /**
     * Obtiene la URL de chat de WhatsApp.
     */
    public function getWhatsAppUrl(): ?string
    {
        $number = $this->getWhatsAppNumber();
        
        return $number ? "https://wa.me/{$number}" : null;
    }

    /**
     * Obtiene la URL para mensaje de WhatsApp con texto predefinido.
     */
    public function getWhatsAppMessageUrl(string $message = ''): ?string
    {
        $number = $this->getWhatsAppNumber();
        
        if (!$number) {
            return null;
        }
        
        $encodedMessage = urlencode($message);
        return "https://wa.me/{$number}?text={$encodedMessage}";
    }

    /**
     * Scope para usuarios activos.
     */
    public function scopeActive($query)
    {
        return $query->where('estado', 'activo');
    }

    /**
     * Scope para usuarios pendientes de aprobación.
     */
    public function scopePending($query)
    {
        return $query->where('estado', 'pendiente');
    }

    /**
     * Scope para usuarios por condominio.
     */
    public function scopeByCondominio($query, $condominioId)
    {
        return $query->where('condominio_id', $condominioId);
    }

    /**
     * Scope para usuarios por rol.
     */
    public function scopeByRole($query, $role)
    {
        return $query->where('role', $role);
    }

    /**
     * Scope para usuarios excluyendo eliminados (soft deletes).
     */
    public function scopeNotDeleted($query)
    {
        return $query->whereNull('deleted_at');
    }

    /**
     * Obtiene todos los roles disponibles.
     */
    public static function getRoles(): array
    {
        return [
            'superadmin' => 'Super Administrador',
            'admin' => 'Administrador',
            'propietario' => 'Propietario',
            'inquilino' => 'Inquilino',
            'guardia' => 'Guardia de Seguridad',
        ];
    }

    /**
     * Obtiene el nombre legible del rol.
     */
    public function getRoleDisplayAttribute(): string
    {
        $roles = self::getRoles();
        return $roles[$this->role] ?? ucfirst($this->role);
    }

    /**
     * Verifica si el usuario puede acceder a un condominio específico.
     */
    public function canAccessCondominio($condominioId): bool
    {
        if ($this->isSuperAdmin()) {
            return true;
        }
        
        return (int) $this->condominio_id === (int) $condominioId;
    }

    /**
     * Verifica si el usuario puede administrar otro usuario.
     */
    public function canManageUser(User $user): bool
    {
        if ($this->isSuperAdmin()) {
            return true;
        }
        
        if ($this->isAdmin()) {
            return $this->condominio_id === $user->condominio_id;
        }
        
        return false;
    }

    /**
     * Registra actividad del usuario en el sistema.
     */
    public function logActivity(string $action, array $data = [], string $description = ''): void
    {
        activity()
            ->causedBy($this)
            ->withProperties($data)
            ->log($description ?: "Usuario {$this->name} realizó: {$action}");
    }

    /**
     * Obtiene el avatar del usuario (foto o iniciales).
     */
    public function getAvatarUrl(): string
    {
        if ($this->foto) {
            return asset('storage/' . $this->foto);
        }
        
        // Generar avatar con iniciales
        $initials = strtoupper(substr($this->name, 0, 2));
        $color = substr(md5($this->email), 0, 6);
        
        return "https://ui-avatars.com/api/?name={$initials}&background={$color}&color=fff&size=128";
    }

    /**
     * Obtiene el nombre completo formateado.
     */
    public function getFullNameAttribute(): string
    {
        return $this->name;
    }

    /**
     * Obtiene el estado formateado.
     */
    public function getEstadoDisplayAttribute(): string
    {
        $estados = [
            'activo' => 'Activo',
            'inactivo' => 'Inactivo',
            'pendiente' => 'Pendiente de Aprobación',
        ];
        
        return $estados[$this->estado] ?? ucfirst($this->estado);
    }

    /**
     * Marca al usuario como aprobado.
     */
    public function markAsApproved(): bool
    {
        return $this->update([
            'estado' => 'activo',
            'email_verified_at' => now()
        ]);
    }

    /**
     * Boot del modelo.
     */
    protected static function boot()
    {
        parent::boot();
        
        static::creating(function ($user) {
            if (empty($user->configuracion)) {
                $user->configuracion = [
                    'notificaciones_email' => true,
                    'notificaciones_push' => true,
                    'tema_oscuro' => false,
                    'idioma' => 'es'
                ];
            }
        });
    }
}