<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use App\Services\PermissionResolverService;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

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

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'name',
        'email',
        'password_hash',
        'role_id',
        'group_id',
        'tier_id',
        'status',
        'location',
        'permissions',
        'failed_login_attempts',
        'account_locked_until',
    ];

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

    /**
     * Get the password for authentication.
     *
     * @return string
     */
    public function getAuthPassword()
    {
        return $this->password_hash;
    }

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password_hash' => 'hashed',
            'permissions' => 'array',
            'locked_until' => 'datetime',
        ];
    }

    /**
     * Relationships
     */
    public function role()
    {
        // Changed to use UserRole model and user_role_id primary key
        return $this->belongsTo(UserRole::class, 'role_id', 'user_role_id');
    }

    public function group()
    {
        return $this->belongsTo(Group::class, 'group_id', 'user_group_id');
    }

    public function tier()
    {
        return $this->belongsTo(UserTier::class, 'tier_id');
    }

    public function phones()
    {
        return $this->hasMany(UserPhone::class, 'user_id');
    }

    public function userRoles()
    {
        return $this->hasMany(UserRole::class, 'user_id');
    }

    public function lexaConversations()
    {
        return $this->hasMany(LexaConversation::class, 'user_id');
    }

    public function lexaChatHistory()
    {
        return $this->hasMany(LexaChatHistory::class, 'user_id');
    }

    /**
     * Chat relationships
     */
    public function chats()
    {
        return $this->belongsToMany(ChatRoom::class, 'chat_participants', 'user_id', 'chat_id')
                    ->withPivot(['role', 'last_seen', 'is_muted', 'is_blocked'])
                    ->withTimestamps()
                    ->using(ChatParticipant::class)
                    ->as('participation');
    }

    public function chatMessages()
    {
        return $this->hasMany(ChatMessage::class, 'sender_id');
    }

    public function sentChatMessages()
    {
        return $this->hasMany(ChatMessage::class, 'sender_id');
    }

    public function chatParticipants()
    {
        return $this->hasMany(ChatParticipant::class, 'user_id');
    }

    public function chatRequestsSent()
    {
        return $this->hasMany(ChatRequest::class, 'sender_id');
    }

    public function chatRequestsReceived()
    {
        return $this->hasMany(ChatRequest::class, 'receiver_id');
    }

    public function chatSettings()
    {
        return $this->hasOne(UserChatSetting::class, 'user_id');
    }

    public function assignedMatters()
    {
        return $this->belongsToMany(Matter::class, 'matter_lawyers', 'lawyer_id', 'matter_id')
            ->withPivot(['role_id', 'is_lead_lawyer', 'created_by', 'updated_by'])
            ->withTimestamps();
    }

    public function unreadMessagesCount()
    {
        return ChatMessage::whereHas('chat.participants', fn($q) => $q->where('user_id', $this->id))
            ->where('sender_id', '!=', $this->id)
            ->where('is_read', false)
            ->count();
    }

    /*
    public function userGroups()
    {
        return $this->hasMany(UserGroup::class, 'user_id');
    }
    */

    /**
     * Check if the user account is locked
     */
    public function isLocked()
    {
        if (!$this->account_locked_until) {
            return false;
        }

        $lockedUntil = $this->account_locked_until;

        // Handle string datetime from database
        if (is_string($lockedUntil)) {
            $lockedUntil = \Carbon\Carbon::parse($lockedUntil);
        }

        return $lockedUntil->isFuture();
    }

    /**
     * Increment failed login attempts
     */
    public function incrementFailedAttempts()
    {
        $this->increment('failed_login_attempts');

        // Lock account after 5 failed attempts for 15 minutes
        if ($this->failed_login_attempts >= 5) {
            $this->locked_until = now()->addMinutes(15);
            $this->save();
        }
    }

    /**
     * Reset failed login attempts
     */
    public function resetFailedAttempts()
    {
        $this->update([
            'failed_login_attempts' => 0,
            'locked_until' => null,
        ]);
    }

    /**
     * Check if user has a specific permission
     */
    public function hasPermission($permission)
    {
        $permissions = $this->permissions ?? [];
        return in_array($permission, $permissions);
    }

    public function hasFeaturePermission(string $featureSlug, string $action = 'can_view'): bool
    {
        return app(PermissionResolverService::class)->hasPermission($this, $featureSlug, $action);
    }

    public function canFeature(string $featureSlug, string $action = 'can_view'): bool
    {
        return $this->hasFeaturePermission($featureSlug, $action);
    }

    public function canAccessModule(string $moduleSlug): bool
    {
        return app(PermissionResolverService::class)->canAccessModule($this, $moduleSlug);
    }
}
