<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{

    use HasFactory, Notifiable, \Spatie\Permission\Traits\HasRoles;

    const ROLE_DEVELOPER = 'developer';
    const ROLE_OWNER = 'owner';
    const ROLE_SPV = 'spv';
    const ROLE_DESIGNER = 'designer';
    const ROLE_KASIR = 'kasir';
    const ROLE_OPERATOR = 'operator';
    const ROLE_ADMINISTRASI = 'administrasi';

    // ROLES constant can stay for reference or seeding
    const ROLES = [
        self::ROLE_DEVELOPER => 'Developer',
        self::ROLE_OWNER => 'Owner',
        self::ROLE_SPV => 'Supervisor',
        self::ROLE_DESIGNER => 'Designer',
        self::ROLE_KASIR => 'Kasir',
        self::ROLE_OPERATOR => 'Operator',
        self::ROLE_ADMINISTRASI => 'Administrasi',
    ];

    protected $fillable = [
        'name',
        'email',
        'password',
        'role', // We keep this for now, but will eventually deprecate
        'is_active',
    ];

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

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

    // Role check methods - mapped to Spatie hasRole
    public function isDeveloper(): bool
    {
        return $this->hasRole(self::ROLE_DEVELOPER);
    }

    public function isOwner(): bool
    {
        return $this->hasRole(self::ROLE_OWNER);
    }

    public function isDesigner(): bool
    {
        return $this->hasRole(self::ROLE_DESIGNER);
    }

    public function isKasir(): bool
    {
        return $this->hasRole(self::ROLE_KASIR);
    }

    public function isOperator(): bool
    {
        return $this->hasRole(self::ROLE_OPERATOR);
    }

    public function isSPV(): bool
    {
        return $this->hasRole(self::ROLE_SPV);
    }
    public function isAdministrasi(): bool
    {
    return $this->role === self::ROLE_ADMINISTRASI;
    }

    // Override hasRole to support checking legacy column if needed, or just rely on Spatie
    // Spatie has its own hasRole, so we shouldn't override it unless necessary.
    // However, the previous hasRole implementation took string|array. Spatie's takes string|int|array.
    // So we can arguably just remove the custom hasRole and use the trait's one.
    // But we need to ensure the `role` column is synced. Use a seeder for that.

    public function canAccessDashboard(): bool
    {
        return true;
    }

    public function canManageUsers(): bool
    {
        // Example: check a specific permission or role
        return $this->hasRole(self::ROLE_DEVELOPER) || $this->can('manage users');
    }

    public function canCreateOrders(): bool
    {
        return $this->hasRole([self::ROLE_DEVELOPER, self::ROLE_DESIGNER]) || $this->can('create orders');
    }

    public function canProcessPayments(): bool
    {
        return $this->hasRole([self::ROLE_DEVELOPER, self::ROLE_KASIR]) || $this->can('process payments');
    }

    public function canUpdateProduction(): bool
    {
        return $this->hasRole([self::ROLE_DEVELOPER, self::ROLE_OPERATOR]) || $this->can('update production');
    }

    public function canViewReports(): bool
    {
        return $this->hasRole([self::ROLE_DEVELOPER, self::ROLE_OWNER]) || $this->can('view reports');
    }

    public function canPrintSPK(): bool
    {
        return $this->hasRole([self::ROLE_DEVELOPER, self::ROLE_DESIGNER]) || $this->can('print spk');
    }

    public function canApproveCancellations(): bool
    {
        return $this->hasRole([self::ROLE_DEVELOPER, self::ROLE_OWNER, self::ROLE_SPV]) || $this->can('approve cancellations');
    }

    public function canRequestCancellations(): bool
    {
        return $this->can('request cancellations');
    }

    public function getRoleLabel(): string
    {
        // Return the first role label or the legacy column
        $roleInfo = $this->roles->first();
        if ($roleInfo) {
            return ucfirst($roleInfo->name);
        }
        return self::ROLES[$this->role] ?? $this->role ?? 'Guest';
    }

    // Relationships
    public function designedOrders(): HasMany
    {
        return $this->hasMany(Order::class, 'designer_id');
    }

    public function processedPayments(): HasMany
    {
        return $this->hasMany(Order::class, 'cashier_id');
    }

    public function handledProduction(): HasMany
    {
        return $this->hasMany(Order::class, 'operator_id');
    }
}
