<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use App\Models\BaseModel;

class Role extends BaseModel
{
    protected $table = 'roles';

    protected $fillable = [
        'name',
        'slug',
        'description',
        'dashboard_route',
        'priority',
        'is_active',
        'created_at',
        'updated_at',
    ];

    public $timestamps = true;

    protected $casts = [
        'priority'   => 'integer',
        'is_active'  => 'boolean',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

    /* ============================================================
     * Scopes
     * ============================================================
     */

    public function scopeActive(Builder $q): Builder
    {
        return $q->where('is_active', 1);
    }

    public function scopeOrderByPriority(Builder $q, string $dir = 'asc'): Builder
    {
        return $q->orderBy('priority', $dir);
    }

    /* ============================================================
     * Helpers (CI-compatible)
     * ============================================================
     */

    /**
     * Find roles by names or slugs (case-insensitive), active only, ordered by priority ASC.
     */

// Put these INSIDE the Role model, replacing the current implementations

public static function findByNamesOrSlugs(array $keys): array
{
    $keys = array_values(array_filter(array_map('strval', $keys)));
    if (empty($keys)) return [];

    $lower = array_map('mb_strtolower', $keys);
    $placeholders = implode(',', array_fill(0, count($lower), '?'));

    return static::query()
        ->active()
        ->where(function (Builder $q) use ($lower, $placeholders) {
            $q->whereRaw("LOWER(name) IN ($placeholders)", $lower)
              ->orWhereRaw("LOWER(slug) IN ($placeholders)", $lower);
        })
        ->orderBy('priority', 'asc')
        ->get()
        ->all();
}

public static function getIdsByNames(array $names): array
{
    $names = array_values(array_filter(array_map('strval', $names)));
    if (empty($names)) return [];

    $lower = array_map('mb_strtolower', $names);
    $placeholders = implode(',', array_fill(0, count($lower), '?'));

    $ids = static::query()
        ->select('id')
        ->whereRaw("LOWER(name) IN ($placeholders)", $lower)
        ->pluck('id')
        ->all();

    return array_map('intval', $ids);
}

    /**
     * Get dashboard_route by name or slug (case-insensitive), active only.
     */
    public static function getRouteByNameOrSlug(string $key): ?string
    {
        $key = trim((string) $key);
        if ($key === '') return null;

        $lower = mb_strtolower($key);

        $role = static::query()
            ->active()
            ->where(function (Builder $q) use ($lower) {
                $q->whereRaw('LOWER(name) = ?', [$lower])
                  ->orWhereRaw('LOWER(slug) = ?', [$lower]);
            })
            ->first();

        return $role?->dashboard_route;
    }

    /**
     * Equivalent to CI getRoles(): returns all roles.
     */
    public static function getRoles()
    {
        return static::query()->get();
    }

    /**
     * DB-agnostic LOWER(column) expression for whereIn.
     * Laravel doesn't allow whereIn on expressions directly, so we use whereRaw.
     * This helper returns the SQL snippet used in whereRaw calls.
     */
    protected static function lowerExpr(string $column): string
    {
        // Used only inside whereRaw with bindings.
        // Example: whereInRaw not available, so we build "LOWER(column) in (?, ?, ?)" via whereRaw below
        // In our code above we used whereIn(static::lowerExpr('name'), $lower) which is not allowed by Eloquent.
        // To keep things correct, we implement a macro-like helper below instead.
        return $column;
    }

    /* ============================================================
     * Optional: validation rules helper (FormRequest/controller)
     * ============================================================
     */

    public static function rules(?int $id = null): array
    {
        return [
            'name'            => ['required', 'string', 'max:255'],
            'slug'            => ['required', 'string', 'max:255', 'unique:roles,slug,' . ($id ?? 'NULL') . ',id'],
            'description'     => ['nullable', 'string', 'max:2000'],
            'dashboard_route' => ['nullable', 'string', 'max:255'],
            'priority'        => ['nullable', 'integer', 'min:0'],
            'is_active'       => ['nullable', 'boolean'],
        ];
    }
}