<?php

namespace App\Services\Finance;

use App\Models\Expense;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Validation\ValidationException;

class ExpenseScopeService
{
    public function defaultScope(User $user): string
    {
        $nav = app(FinanceNavService::class);

        if ($nav->canViewCompanyExpenses($user)) {
            return 'company';
        }

        if ($user->hasPermission('finance_team_view')) {
            return 'team';
        }

        return 'self';
    }

    public function canUseScope(User $user, string $scope): bool
    {
        $nav = app(FinanceNavService::class);

        return match ($scope) {
            'company' => $nav->canViewCompanyExpenses($user),
            'team' => $user->hasPermission('finance_team_view'),
            'self' => $nav->userHasAnyPermission($user, ['finance_self_view', 'expenses_create_own'])
                || $nav->canViewCompanyExpenses($user)
                || $user->hasPermission('finance_team_view'),
            default => false,
        };
    }

    public function resolveScope(User $user, ?string $scope): string
    {
        $scope = $scope ?: $this->defaultScope($user);

        if (! $this->canUseScope($user, $scope)) {
            throw ValidationException::withMessages([
                'scope' => 'You are not allowed to view expenses for this scope.',
            ]);
        }

        return $scope;
    }

    /**
     * @param  Builder<Expense>  $query
     */
    public function applyScope(Builder $query, User $user, string $scope): void
    {
        if ($scope === 'company') {
            return;
        }

        if ($scope === 'team') {
            $ids = $user->visibleStaffUserIds();
            $query->where(function ($q) use ($ids) {
                $q->whereIn('user_id', $ids)->orWhereIn('submitted_by', $ids);
            });

            return;
        }

        $query->where(function ($q) use ($user) {
            $q->where('user_id', $user->id)->orWhere('submitted_by', $user->id);
        });
    }
}
