<?php

namespace App\Models;

use App\Services\PermissionService;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Str;

class User extends Authenticatable
{
    use HasFactory, Notifiable, SoftDeletes;

    protected $fillable = [
        'uuid',
        'tenant_id',
        'employee_id',
        'user_type_id',
        'name',
        'email',
        'mobile',
        'username',
        'password',
        'default_branch_id',
        'department_id',
        'counter_id',
        'data_scope_override',
        'language',
        'timezone',
        'avatar',
        'status',
        'must_change_password',
        'mfa_enabled',
        'mfa_secret',
        'allow_web_login',
        'allow_mobile_login',
        'email_verified_at',
        'mobile_verified_at',
        'last_login_at',
        'last_login_ip',
        'password_changed_at',
        'created_by',
    ];

    protected $hidden = [
        'password',
        'remember_token',
        'mfa_secret',
    ];

    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'mobile_verified_at' => 'datetime',
            'last_login_at' => 'datetime',
            'password_changed_at' => 'datetime',
            'password' => 'hashed',
            'must_change_password' => 'boolean',
            'mfa_enabled' => 'boolean',
            'allow_web_login' => 'boolean',
            'allow_mobile_login' => 'boolean',
        ];
    }

    protected static function boot()
    {
        parent::boot();
        static::creating(function ($model) {
            if (! $model->uuid) {
                $model->uuid = (string) Str::uuid();
            }
        });
    }

    public function tenant()
    {
        return $this->belongsTo(Tenant::class);
    }

    public function employee()
    {
        return $this->belongsTo(Employee::class);
    }

    public function userType()
    {
        return $this->belongsTo(UserType::class);
    }

    public function defaultBranch()
    {
        return $this->belongsTo(Branch::class, 'default_branch_id');
    }

    public function department()
    {
        return $this->belongsTo(Department::class);
    }

    public function counter()
    {
        return $this->belongsTo(Counter::class);
    }

    public function roles()
    {
        return $this->belongsToMany(Role::class, 'user_roles');
    }

    public function permissionOverrides()
    {
        return $this->hasMany(UserPermissionOverride::class);
    }

    public function allowedBranches()
    {
        return $this->belongsToMany(Branch::class, 'user_branches');
    }

    public function loginHistories()
    {
        return $this->hasMany(LoginHistory::class);
    }

    // Role & Permission Helper Methods
    public function isPlatformUser(): bool
    {
        return $this->userType && $this->userType->category === 'platform';
    }

    public function isPlatformSuperAdmin(): bool
    {
        return $this->hasRole('platform_super_admin');
    }

    public function hasRole(string $roleSlug): bool
    {
        return $this->roles->contains('slug', $roleSlug);
    }

    public function hasPermission(string $permissionSlug): bool
    {
        return app(PermissionService::class)->hasPermission($this, $permissionSlug);
    }

    public function getDataScope(): string
    {
        return app(PermissionService::class)->getDataScope($this);
    }

    public function getPrimaryRoleName(): string
    {
        $primaryRole = $this->roles->first();

        return $primaryRole ? $primaryRole->name : 'User';
    }

    public function canViewAllBranches(): bool
    {
        return in_array($this->getDataScope(), ['all_branches', 'tenant', 'platform'], true);
    }

    public function accessibleBranches()
    {
        if (! $this->tenant_id) {
            return collect();
        }

        if ($this->canViewAllBranches()) {
            return Branch::where('tenant_id', $this->tenant_id)->where('status', 'active')->orderBy('name')->get();
        }

        if ($this->getDataScope() === 'selected_branches') {
            return $this->allowedBranches()->where('branches.status', 'active')->orderBy('branches.name')->get();
        }

        return Branch::where('tenant_id', $this->tenant_id)->whereKey($this->default_branch_id)->where('status', 'active')->get();
    }

    public function canAccessBranch(int $branchId): bool
    {
        return $this->accessibleBranches()->contains('id', $branchId);
    }

    public function getDashboardUrl(): string
    {
        if ($this->isPlatformUser()) {
            return route('platform.dashboard');
        }

        if ($this->hasRole('receptionist')) {
            return route('app.front_desk');
        } elseif ($this->hasRole('typist')) {
            return route('app.work_queue');
        } elseif ($this->hasRole('processing_supervisor')) {
            return route('app.processing');
        } elseif ($this->hasRole('pro')) {
            return route('app.pro');
        } elseif ($this->hasRole('cashier')) {
            return route('app.cashier');
        } elseif ($this->hasRole('accountant')) {
            return route('app.accounting');
        } elseif ($this->hasRole('hr')) {
            return route('app.hr');
        } elseif ($this->hasRole('sales')) {
            return route('app.crm');
        } elseif ($this->hasRole('renewal_executive')) {
            return route('app.renewals');
        } elseif ($this->hasRole('customer_service')) {
            return route('app.customer_service');
        } elseif ($this->hasRole('document_controller')) {
            return route('app.documents');
        } elseif ($this->hasRole('auditor')) {
            return route('app.audit');
        }

        return route('app.dashboard');
    }
}
