<?php

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;

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

    protected $fillable = [
        'name',
        'email',
        'password',
        'role',
        'employee_number',   // plain string ID like "UL-0012", NOT a FK
        'phone',
        'avatar',
        'is_active',
        'theme',
        'sidebar_style',
        'last_login_at',
    ];

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

    protected $casts = [
        'email_verified_at' => 'datetime',
        'last_login_at'     => 'datetime',
        'password'          => 'hashed',
        'is_active'         => 'boolean',
    ];

    // ── Role helpers ───────────────────────────────────────
    public function isSuperAdmin(): bool { return $this->role === 'super_admin'; }
    public function isHrAdmin(): bool    { return $this->role === 'hr_admin'; }
    public function isPresident(): bool  { return $this->role === 'president'; }
    public function isDeptHead(): bool   { return $this->role === 'dept_head'; }
    public function isEmployee(): bool   { return $this->role === 'employee'; }
    public function isHrOrAdmin(): bool  { return in_array($this->role, ['super_admin', 'hr_admin']); }
    public function isManagement(): bool { return in_array($this->role, ['super_admin', 'hr_admin', 'president']); }

    public function hasRole(string ...$roles): bool
    {
        return in_array($this->role, $roles);
    }

    // ── Module access ──────────────────────────────────────
    public function canAccess(string $module): bool
    {
        return match ($module) {
            'employees'  => $this->hasRole('super_admin', 'hr_admin', 'president', 'dept_head'),
            'payroll'    => $this->hasRole('super_admin', 'hr_admin', 'president'),
            'discipline' => $this->hasRole('super_admin', 'hr_admin', 'president', 'dept_head'),
            'reports'    => $this->hasRole('super_admin', 'hr_admin', 'president'),
            default      => true,
        };
    }

    // ── Accessors ───────────────────────────────────────────

    /**
     * The user's department is resolved through their employee record.
     * departments.head_user_id → users.id is a one-way FK (no cycle).
     * users does NOT store department_id, so there is no circular FK.
     */
    public function getDepartmentIdAttribute(): ?int
    {
        return $this->employee?->department_id;
    }

    public function getDepartmentAttribute(): ?Department
    {
        return $this->employee?->department;
    }

    public function getRoleLabelAttribute(): string
    {
        return match ($this->role) {
            'super_admin' => 'Super Admin',
            'hr_admin'    => 'HR Administrator',
            'president'   => 'President / CEO',
            'dept_head'   => 'Department Head',
            'employee'    => 'Employee',
            default       => ucfirst($this->role),
        };
    }

    public function getRoleBadgeAttribute(): string
    {
        return match ($this->role) {
            'super_admin' => 'danger',
            'hr_admin'    => 'primary',
            'president'   => 'dark',
            'dept_head'   => 'info',
            'employee'    => 'secondary',
            default       => 'secondary',
        };
    }

    public function getThemeConfigAttribute(): array
    {
        $themes = config('themes', []);
        $key    = $this->theme ?? 'navy';
        return $themes[$key] ?? $themes['navy'] ?? [];
    }

    // ── Relationships ───────────────────────────────────────

    /**
     * One-to-one: users ← employees (employees.user_id → users.id).
     * This is the authoritative source of a user's department, position, etc.
     */
    public function employee(): \Illuminate\Database\Eloquent\Relations\HasOne
    {
        return $this->hasOne(Employee::class);
    }

    // Leave approval relationships
    public function leavesApprovedAsDeptHead()  { return $this->hasMany(Leave::class, 'dept_head_id'); }
    public function leavesApprovedAsHR()        { return $this->hasMany(Leave::class, 'hr_approver_id'); }
    public function leavesApprovedAsPresident() { return $this->hasMany(Leave::class, 'president_approver_id'); }
    public function evaluationsGiven()          { return $this->hasMany(PerformanceEvaluation::class, 'evaluator_id'); }
    public function disciplineReported()        { return $this->hasMany(DisciplineRecord::class, 'reported_by'); }
}
