<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use App\Models\BaseModel;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\Log;

class RolePermission extends BaseModel
{
    protected $table = 'role_permissions';

    protected $fillable = [
        'role_id',
        'permission_id',
        'can_create',
        'can_read',
        'can_update',
        'can_delete',
        'can_manage',
        'created_at',
        'updated_at',
    ];

    public $timestamps = true;

    protected $casts = [
        'role_id'        => 'integer',
        'permission_id'  => 'integer',
        'can_create'     => 'boolean',
        'can_read'       => 'boolean',
        'can_update'     => 'boolean',
        'can_delete'     => 'boolean',
        'can_manage'     => 'boolean',
        'created_at'     => 'datetime',
        'updated_at'     => 'datetime',
    ];

    /* ============================================================
     * Relationships
     * ============================================================
     */

    public function role(): BelongsTo
    {
        return $this->belongsTo(Role::class, 'role_id');
    }

    public function permission(): BelongsTo
    {
        return $this->belongsTo(Permission::class, 'permission_id');
    }

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

    public function scopeForRole(Builder $q, int $roleId): Builder
    {
        return $q->where('role_id', $roleId);
    }

    public function scopeForPermission(Builder $q, int $permissionId): Builder
    {
        return $q->where('permission_id', $permissionId);
    }

    /* ============================================================
     * CI-compatible methods
     * ============================================================
     */

    /**
     * Fetch permissions assigned to a specific role.
     * (CI: getRolePermissions)
     */
    public static function getRolePermissions(int $roleId)
    {
        try {
            return static::query()->forRole($roleId)->get();
        } catch (\Throwable $e) {
            Log::error("Error fetching role permissions for role ID {$roleId}: {$e->getMessage()}");
            throw $e;
        }
    }

    /**
     * Alias (CI: getPermissionsByRole)
     */
    public static function getPermissionsByRole(int $roleId)
    {
        return static::query()->forRole($roleId)->get();
    }

    /**
     * Delete all role_permissions rows for role.
     * (CI: deleteByRole)
     */
    public static function deleteByRole(int $roleId): int
    {
        return static::query()->forRole($roleId)->delete(); // returns deleted rows count
    }

    /* ============================================================
     * Enhancements / helpers
     * ============================================================
     */

    /**
     * Compute effective permission flags.
     * If can_manage is true, treat all CRUD as true.
     */
    public function effectiveAbilities(): array
    {
        $manage = (bool) $this->can_manage;

        return [
            'can_create' => $manage ? true : (bool) $this->can_create,
            'can_read'   => $manage ? true : (bool) $this->can_read,
            'can_update' => $manage ? true : (bool) $this->can_update,
            'can_delete' => $manage ? true : (bool) $this->can_delete,
            'can_manage' => $manage,
        ];
    }

    /**
     * Convenience: set CRUD flags quickly.
     */
    public function setCrud(bool $create, bool $read, bool $update, bool $delete, bool $manage = false): self
    {
        $this->can_create = $create;
        $this->can_read   = $read;
        $this->can_update = $update;
        $this->can_delete = $delete;
        $this->can_manage = $manage;
        return $this;
    }

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

    public static function rules(bool $updating = false): array
    {
        return [
            'role_id'       => [$updating ? 'sometimes' : 'required', 'integer', 'min:1', 'exists:roles,id'],
            'permission_id' => [$updating ? 'sometimes' : 'required', 'integer', 'min:1', 'exists:permissions,id'],

            'can_create'    => ['nullable', 'boolean'],
            'can_read'      => ['nullable', 'boolean'],
            'can_update'    => ['nullable', 'boolean'],
            'can_delete'    => ['nullable', 'boolean'],
            'can_manage'    => ['nullable', 'boolean'],
        ];
    }
}