<?php

namespace App\Domain\Identity\Services;

use App\Domain\Identity\Models\Permission;
use App\Domain\Identity\Models\Role;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

class PermissionService
{
    public function can(User $user, string $permission, ?Model $record = null): bool
    {
        // Super admin bypasses all
        if ($user->is_super_admin) {
            return true;
        }

        // Get user's role (primary role via role_id for performance)
        $role = $user->primaryRole;
        if (!$role) {
            // Fallback: check many-to-many roles
            $role = $user->roles->first();
            if (!$role) {
                return false;
            }
            if (!$role->relationLoaded('permissions')) {
                $role->load('permissions');
            }
        }

        // Check if role has this permission
        $rolePermission = $role->permissions->firstWhere('name', $permission);
        if (!$rolePermission) {
            return false;
        }

        // If no specific record to check, permission exists = allowed
        if ($record === null) {
            return true;
        }

        // Scope check against the specific record
        $scope = $rolePermission->pivot->scope;

        return match ($scope) {
            'all' => true,
            'academy' => true, // tenant scope already applied
            'branch' => $this->checkBranchScope($user, $record),
            'own' => $this->checkOwnScope($user, $record),
            'own_groups' => $this->checkOwnGroupsScope($user, $record),
            'own_children' => $this->checkOwnChildrenScope($user, $record),
            default => false,
        };
    }

    public function applyScope(Builder $query, User $user, string $permission): Builder
    {
        if ($user->is_super_admin) {
            return $query;
        }

        $role = $user->primaryRole;
        if (!$role) {
            $role = $user->roles->first();
            if (!$role) {
                return $query->whereRaw('1 = 0');
            }
            if (!$role->relationLoaded('permissions')) {
                $role->load('permissions');
            }
        }

        $rolePermission = $role->permissions->firstWhere('name', $permission);
        if (!$rolePermission) {
            return $query->whereRaw('1 = 0');
        }

        $scope = $rolePermission->pivot->scope;
        $table = $query->getModel()->getTable();

        return match ($scope) {
            'all', 'academy' => $query,
            'branch' => $query->where("{$table}.branch_id", $user->branch_id),
            'own' => $query->where("{$table}.created_by", $user->id),
            default => $query,
        };
    }

    private function checkBranchScope(User $user, Model $record): bool
    {
        if (!property_exists($record, 'branch_id') && !isset($record->branch_id)) {
            return true;
        }
        return $record->branch_id === $user->branch_id;
    }

    private function checkOwnScope(User $user, Model $record): bool
    {
        if (!property_exists($record, 'created_by') && !isset($record->created_by)) {
            return true;
        }
        return $record->created_by === $user->id;
    }

    private function checkOwnGroupsScope(User $user, Model $record): bool
    {
        // Will be implemented when assignments exist (Phase 5)
        return false;
    }

    private function checkOwnChildrenScope(User $user, Model $record): bool
    {
        // Will be implemented when participants + guardian_participant exist (Phase 2)
        return false;
    }
}
