<?php

namespace App\Models;

use App\Enums\UserStatus;
use App\Enums\UserType;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Str;
use Laravel\Fortify\TwoFactorAuthenticatable;

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

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'user_type',
        'full_name',
        'national_id',
        'company_name',
        'company_cert_number',
        'contact_person_name',
        'contact_person_id',
        'email',
        'phone',
        'password',
        'status',
        'preferred_language',
    ];

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

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'user_type' => UserType::class,
            'status' => UserStatus::class,
            'email_verified_at' => 'datetime',
            'two_factor_confirmed_at' => 'datetime',
            'password' => 'hashed',
        ];
    }

    /**
     * Get the user's initials.
     */
    public function initials(): string
    {
        return Str::of($this->full_name)
            ->explode(' ')
            ->take(2)
            ->map(fn ($word) => Str::substr($word, 0, 1))
            ->implode('');
    }

    /**
     * Check if user is an admin.
     */
    public function isAdmin(): bool
    {
        return $this->user_type === UserType::Admin;
    }

    /**
     * Check if user is an individual client.
     */
    public function isIndividual(): bool
    {
        return $this->user_type === UserType::Individual;
    }

    /**
     * Check if user is a company client.
     */
    public function isCompany(): bool
    {
        return $this->user_type === UserType::Company;
    }

    /**
     * Check if user is a client (individual or company).
     */
    public function isClient(): bool
    {
        return $this->isIndividual() || $this->isCompany();
    }

    /**
     * Check if user is active.
     */
    public function isActive(): bool
    {
        return $this->status === UserStatus::Active;
    }

    /**
     * Check if user is deactivated.
     */
    public function isDeactivated(): bool
    {
        return $this->status === UserStatus::Deactivated;
    }

    /**
     * Deactivate the user account.
     */
    public function deactivate(): void
    {
        $this->update(['status' => UserStatus::Deactivated]);
    }

    /**
     * Reactivate the user account.
     */
    public function reactivate(): void
    {
        $this->update(['status' => UserStatus::Active]);
    }

    /**
     * Scope to filter admin users.
     */
    public function scopeAdmins($query)
    {
        return $query->where('user_type', UserType::Admin);
    }

    /**
     * Scope to filter client users (individual or company).
     */
    public function scopeClients($query)
    {
        return $query->whereIn('user_type', [UserType::Individual, UserType::Company]);
    }

    /**
     * Scope to filter individual clients.
     */
    public function scopeIndividual($query)
    {
        return $query->where('user_type', UserType::Individual);
    }

    /**
     * Scope to filter company clients.
     */
    public function scopeCompanies($query)
    {
        return $query->where('user_type', UserType::Company);
    }

    /**
     * Scope to filter active users.
     */
    public function scopeActive($query)
    {
        return $query->where('status', UserStatus::Active);
    }

    /**
     * Get the consultations for the user.
     */
    public function consultations(): HasMany
    {
        return $this->hasMany(Consultation::class);
    }

    /**
     * Get the timelines for the user.
     */
    public function timelines(): HasMany
    {
        return $this->hasMany(Timeline::class);
    }

    /**
     * Get the notifications for the user.
     */
    public function customNotifications(): HasMany
    {
        return $this->hasMany(Notification::class);
    }

    /**
     * Get the admin logs for the user.
     */
    public function adminLogs(): HasMany
    {
        return $this->hasMany(AdminLog::class, 'admin_id');
    }

    /**
     * Get the timeline updates created by this admin.
     */
    public function timelineUpdates(): HasMany
    {
        return $this->hasMany(TimelineUpdate::class, 'admin_id');
    }

    /**
     * Boot the model and register cascade delete event.
     */
    protected static function booted(): void
    {
        static::deleting(function (User $user) {
            // Cascade delete consultations
            $user->consultations()->delete();

            // Cascade delete timelines and their updates
            $user->timelines->each(function ($timeline) {
                $timeline->updates()->delete();
                $timeline->delete();
            });

            // Cascade delete custom notifications
            $user->customNotifications()->delete();
        });
    }
}
