<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Filament\Models\Contracts\HasName;
use OwenIt\Auditing\Contracts\Auditable;
use OwenIt\Auditing\Auditable as AuditableTrait;
use Spatie\Permission\Traits\HasRoles;
use Althinect\FilamentSpatieRolesPermissions\Concerns\HasSuperAdmin;
use Illuminate\Support\Str;
use Filament\Models\Contracts\FilamentUser;
use Filament\Panel;

class User extends Authenticatable implements Auditable, HasName, FilamentUser
{
    use HasFactory, Notifiable, AuditableTrait, HasRoles, HasSuperAdmin;

    protected $fillable = [
        'nama',
        'email',
        'password',
        'gred',
        'no_institusi_jabatan',
        'tarikh_masa_log_masuk',
        'alamat_ip',
        'gambar',
        'aktif',
        'slug', // add slug to fillable
    ];

    protected $attributes = [
        'jenis_pengguna' => 0,
    ];

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

    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
            'tarikh_masa_log_masuk' => 'datetime',
        ];
    }

    public function getFilamentName(): string
    {
        return $this->getAttributeValue('nama');
    }

    // Relations
    public function institusiJabatan()
    {
        return $this->belongsTo(\App\Models\InstitusiJabatan::class, 'no_institusi_jabatan', 'no');
    }

    protected static function boot()
    {
        parent::boot();

        // Define an event listener for the creating event
        static::creating(function ($pengguna) {
            // Modify the 'nama' attribute to uppercase before insertion
            $pengguna->nama = strtoupper($pengguna->nama);

            // ✅ AUTO CREATE SLUG
            if (empty($user->slug)) {
                $pengguna->slug = Str::slug($pengguna->nama) . '-' . self::randomAlphaNumeric(8);
            }
        });

        static::updating(function ($pengguna) {
            // Retrieve the original model instance before update

            $pengguna->nama = strtoupper($pengguna->nama);
        });

        // ✅ SELEPAS UPDATE BERJAYA
        static::updated(function ($pengguna) {
            // ✔️ Check sama ada email memang berubah
            if ($pengguna->wasChanged('email')) {
                $oldEmail = $pengguna->getOriginal('email');
                $newEmail = $pengguna->email;

                // ✔️ Update hanya jika ada rekod tugasan guna email lama
                Tugasan::where('email', $oldEmail)->update([
                    'email' => $newEmail,
                ]);
            }
        });
    }

    protected static function randomAlphaNumeric(int $length = 8): string
    {
        $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        $result = '';

        for ($i = 0; $i < $length; $i++) {
            $result .= $characters[random_int(0, strlen($characters) - 1)];
        }

        return $result;
    }

    public function jenisPengguna()
    {
        return $this->belongsTo(JenisPengguna::class, 'jenis_pengguna', 'no');
    }

    public function dokumenRujukan()
    {
        return $this->hasMany(DokumenRujukan::class, 'email_ketua_jabatan', 'email');
    }

    public function senaraiGred()
    {
        return $this->belongsTo(Gred::class, 'gred', 'no');
    }

    public function tugasan()
    {
        return $this->hasMany(Tugasan::class, 'email', 'email');
    }

    public static function senaraiPengguna($institusi, $jabatan)
    {
        $senarai_pengguna = Pengguna::where('users.aktif', 1)->leftJoin('institusi_jabatan', 'institusi_jabatan.no', '=', 'users.no_institusi_jabatan')->leftJoin('jabatan', 'jabatan.no', '=', 'institusi_jabatan.no_jabatan')->leftJoin('gred', 'gred.no', '=', 'users.gred')->leftJoin('institusi', 'institusi.no', '=', 'institusi_jabatan.no_institusi')->leftJoin('jenis_pengguna', 'jenis_pengguna.no', '=', 'users.jenis_pengguna')->select('users.email as email', 'users.nama as nama', 'users.gred as gred', 'institusi_jabatan.no_jabatan as jabatan', 'users.aktif as aktif', 'users.jenis_pengguna as jenis_pengguna', 'institusi_jabatan.unit_tugas_sampingan as unit_tugas_sampingan', 'institusi_jabatan.no_institusi as no_institusi', 'gred.nama as nama_gred', 'institusi.nama as nama_institusi', 'jenis_pengguna.nama as nama_jenis_pengguna', 'users.no_institusi_jabatan as no_institusi_jabatan', 'jabatan.nama as nama_jabatan')->where('institusi.no', $institusi);

        if (!empty($jabatan)) {
            $senarai_pengguna->where('jabatan.no', $jabatan);
        }

        $senarai_pengguna = $senarai_pengguna->orderBy('users.nama')->get();

        return $senarai_pengguna;
    }

    public function getRouteKeyName(): string
    {
        return 'slug'; // Laravel will now use slug for route model binding
    }

    public function canAccessPanel(Panel $panel): bool
    {
        return true;
    }
}
