<?php

namespace App\Traits;

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

trait HasAccessScope
{
    /**
     * Scope a query to only include records accessible by the given user based on their RBAC access scope.
     *
     * @param Builder $query
     * @param User|null $user
     * @param string $module
     * @return Builder
     */
    public function scopeForUser(Builder $query, ?User $user = null, string $module = 'leads'): Builder
    {
        $user = $user ?? auth()->user();

        if (!$user) {
            return $query->whereRaw('1 = 0'); // Deny if not logged in
        }

        // Super Admin & Admin have global unrestricted access
        if ($user->isSuperAdmin() || $user->isAdmin()) {
            return $query;
        }

        // Determine effective scope for this module / capability
        $scope = $user->getEffectivePermissionScope($module . '.view');

        $tableName = $this->getTable();

        return match ($scope) {
            'all' => $query,

            'own' => match ($tableName) {
                'leads'       => $query->where('assigned_to', $user->id),
                'follow_ups'  => $query->where('user_id', $user->id),
                'quotations'  => $query->whereHas('lead', fn($q) => $q->where('assigned_to', $user->id)),
                'customers'   => $query->where(function($q) use ($user) {
                    $q->whereHas('leads', fn($l) => $l->where('assigned_to', $user->id))
                      ->orWhereDoesntHave('leads'); // allow unassigned global customers or filter
                }),
                default       => $query
            },

            'team' => match ($tableName) {
                'leads' => $query->where(function($q) use ($user) {
                    $teamUserIds = array_merge([$user->id], $user->directReports()->pluck('id')->toArray());
                    $q->whereIn('assigned_to', $teamUserIds);
                }),
                'follow_ups' => $query->where(function($q) use ($user) {
                    $teamUserIds = array_merge([$user->id], $user->directReports()->pluck('id')->toArray());
                    $q->whereIn('user_id', $teamUserIds);
                }),
                'quotations' => $query->whereHas('lead', function($q) use ($user) {
                    $teamUserIds = array_merge([$user->id], $user->directReports()->pluck('id')->toArray());
                    $q->whereIn('assigned_to', $teamUserIds);
                }),
                default => $query
            },

            'department' => match ($tableName) {
                'leads' => $query->where(function($q) use ($user) {
                    $deptUserIds = User::where('department', $user->department)->pluck('id')->toArray();
                    $q->whereIn('assigned_to', $deptUserIds);
                }),
                'follow_ups' => $query->where(function($q) use ($user) {
                    $deptUserIds = User::where('department', $user->department)->pluck('id')->toArray();
                    $q->whereIn('user_id', $deptUserIds);
                }),
                'quotations' => $query->whereHas('lead', function($q) use ($user) {
                    $deptUserIds = User::where('department', $user->department)->pluck('id')->toArray();
                    $q->whereIn('assigned_to', $deptUserIds);
                }),
                default => $query
            },

            default => $query
        };
    }
}
