import 'package:flutter/widgets.dart';
import 'package:get_it/get_it.dart';
import 'package:go_router/go_router.dart';

import '../permissions/permission_manager.dart';

typedef RouteGuard = String? Function(BuildContext, GoRouterState);

/// 라우트 접근 시 권한을 검사하는 가드.
class AuthGuard {
  const AuthGuard._();

  /// [resource]와 [action]에 대한 접근 권한을 확인한다.
  static bool can(
    String resource, {
    PermissionAction action = PermissionAction.view,
  }) {
    if (!GetIt.I.isRegistered<PermissionManager>()) {
      return false;
    }
    return GetIt.I<PermissionManager>().can(resource, action);
  }

  /// 권한이 없을 경우 [fallback] 경로로 리다이렉트하는 Guard를 생성한다.
  static RouteGuard require({
    required String resource,
    PermissionAction action = PermissionAction.view,
    required String fallback,
  }) {
    return requireAll(
      requirements: [
        PermissionRequirement(resource: resource, action: action),
      ],
      fallback: fallback,
    );
  }

  /// 여러 권한 요구사항을 모두 만족해야 통과시키는 가드를 생성한다.
  static RouteGuard requireAll({
    required Iterable<PermissionRequirement> requirements,
    required String fallback,
  }) {
    final guards = requirements.toList(growable: false);
    if (guards.isEmpty) {
      return (context, state) => null;
    }
    return (context, state) {
      if (!GetIt.I.isRegistered<PermissionManager>()) {
        return null;
      }
      final manager = GetIt.I<PermissionManager>();
      for (final requirement in guards) {
        final allowed = manager.can(requirement.resource, requirement.action);
        if (!allowed) {
          return fallback;
        }
      }
      return null;
    };
  }
}

/// 라우트 접근 시 필요한 권한 정보를 표현한다.
class PermissionRequirement {
  const PermissionRequirement({
    required this.resource,
    this.action = PermissionAction.view,
  });

  final String resource;
  final PermissionAction action;
}
