<?php

namespace App\Traits;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;

trait HasRowLevelSecurity
{
    /**
     * Boot the Row Level Security trait for a model.
     */
    protected static function bootHasRowLevelSecurity(): void
    {
        // Automatically set the user key on creation
        static::creating(function ($model) {
            if (!app()->runningInConsole() && Auth::check()) {
                $user = Auth::user();
                if (!$user->is_superadmin && 
                    !$user->roles->contains('name', 'Supervisor') && 
                    !$user->roles->contains('name', 'Admin') && 
                    !$user->roles->contains('name', 'Writer') && 
                    !$user->roles->contains('name', 'HR')) {
                    
                    $column = static::getRowLevelSecurityKey();
                    if ($column && empty($model->{$column})) {
                        $model->{$column} = $user->id;
                    }
                }
            }
        });

        // Apply global scope to filter queries
        static::addGlobalScope('row_level_security', function (Builder $builder) {
            // Do not apply RLS in console/CLI (cron jobs, queue workers, artisan)
            if (app()->runningInConsole()) {
                return;
            }

            // Prevent infinite recursion loops when Laravel auth attempts to load/verify the user
            static $isResolving = false;
            if ($isResolving) {
                return;
            }

            $isResolving = true;
            try {
                // Apply RLS only if a user is logged in
                if (Auth::check()) {
                    $user = Auth::user();

                    // Admin-level users bypass RLS
                    if ($user->is_superadmin || 
                        $user->roles->contains('name', 'Supervisor') || 
                        $user->roles->contains('name', 'Admin') || 
                        $user->roles->contains('name', 'Writer') || 
                        $user->roles->contains('name', 'HR')) {
                        return;
                    }

                    // Check if the model defines custom RLS logic
                    if (method_exists(static::class, 'applyRowLevelSecurity')) {
                        static::applyRowLevelSecurity($builder, $user);
                        return;
                    }

                    $column = static::getRowLevelSecurityKey();
                    if ($column) {
                        // Prepend the table name to avoid "ambiguous column" database errors
                        $table = $builder->getModel()->getTable();
                        $builder->where($table . '.' . $column, $user->id);
                    }
                }
            } finally {
                $isResolving = false;
            }
        });
    }

    /**
     * Get the column name used for Row Level Security.
     */
    protected static function getRowLevelSecurityKey(): ?string
    {
        // Allow models to define a custom RLS_KEY constant
        if (defined('static::RLS_KEY')) {
            return static::RLS_KEY;
        }

        // For the User model itself, the security key is 'id'
        if (static::class === \App\Models\User::class) {
            return 'id';
        }

        // Guess based on model fillable fields
        $instance = new static();
        $fillable = $instance->getFillable();

        if (in_array('user_id', $fillable)) {
            return 'user_id';
        }

        if (in_array('userid', $fillable)) {
            return 'userid';
        }

        return null;
    }
}
