<?php

namespace App\Policies;

use App\Models\Expense;
use App\Models\User;
use App\Services\Finance\FinanceNavService;

class ExpensePolicy
{
    public function viewAny(User $user): bool
    {
        return app(FinanceNavService::class)->userHasAnyPermission($user, [
            'finance_view',
            'finance_treasury_view',
            'finance_operational',
            'finance_team_view',
            'finance_self_view',
            'expenses_create_own',
        ]);
    }

    public function create(User $user): bool
    {
        return app(FinanceNavService::class)->userHasAnyPermission($user, [
            'finance_create',
            'finance_view',
            'finance_treasury_view',
            'finance_operational',
            'finance_team_view',
            'finance_self_view',
            'expenses_create_own',
        ]);
    }

    public function view(User $user, Expense $expense): bool
    {
        if ((int) $expense->company_id !== (int) $user->company_id) {
            return false;
        }

        $nav = app(FinanceNavService::class);

        if ($nav->canViewCompanyExpenses($user)) {
            return true;
        }

        if ($user->hasPermission('finance_team_view')) {
            $ids = $user->visibleStaffUserIds();

            return in_array((int) $expense->user_id, $ids, true)
                || in_array((int) $expense->submitted_by, $ids, true);
        }

        return (int) $expense->user_id === (int) $user->id
            || (int) $expense->submitted_by === (int) $user->id;
    }

    public function update(User $user, Expense $expense): bool
    {
        if (! $this->view($user, $expense)) {
            return false;
        }

        if ($expense->isLocked()) {
            return false;
        }

        if ($user->hasPermission('finance_edit')) {
            return true;
        }

        return $expense->status === 'pending'
            && ((int) $expense->user_id === (int) $user->id || (int) $expense->submitted_by === (int) $user->id);
    }

    public function delete(User $user, Expense $expense): bool
    {
        if ((int) $expense->company_id !== (int) $user->company_id) {
            return false;
        }

        if ($expense->isLocked()) {
            return false;
        }

        if ($user->hasPermission('finance_delete')) {
            return true;
        }

        return $expense->status === 'pending'
            && ((int) $expense->user_id === (int) $user->id || (int) $expense->submitted_by === (int) $user->id);
    }

    public function review(User $user, Expense $expense): bool
    {
        return $user->canApproveExpense($expense);
    }
}
