import 'package:flutter/foundation.dart';

import 'package:collection/collection.dart';

import 'package:pshared/models/permissions/descriptions/role.dart';
import 'package:pshared/provider/account.dart';
import 'package:pshared/provider/invitations.dart';
import 'package:pshared/provider/permissions.dart';


class InvitationsPageController extends ChangeNotifier {
  PermissionsProvider? _permissions;
  InvitationsProvider? _invitations;
  AccountProvider? _account;

  String? _selectedRoleRef;
  int _expiryDays = 7;

  String? get selectedRoleRef => _selectedRoleRef;
  int get expiryDays => _expiryDays;

  void update({
    required PermissionsProvider permissions,
    required InvitationsProvider invitations,
    required AccountProvider account,
  }) {
    _permissions = permissions;
    _invitations = invitations;
    _account = account;
    bootstrapRoleSelection(permissions.roleDescriptions);
  }

  void setExpiryDays(int value) {
    if (_expiryDays == value) return;
    _expiryDays = value;
    notifyListeners();
  }

  void setSelectedRoleRef(String? roleRef) {
    if (_selectedRoleRef == roleRef) return;
    _selectedRoleRef = roleRef;
    notifyListeners();
  }

  Future<RoleDescription?> createRole({
    required String name,
    String? description,
  }) async {
    final permissions = _permissions;
    if (permissions == null) {
      throw StateError('Permissions provider is not ready');
    }
    final normalizedDescription = description?.trim();
    final created = await permissions.createRoleDescription(
      name: name.trim(),
      description: (normalizedDescription == null || normalizedDescription.isEmpty)
          ? null
          : normalizedDescription,
    );
    if (created != null) {
      setSelectedRoleRef(created.id);
    }
    return created;
  }

  Future<void> sendInvitation({
    required String email,
    required String name,
    required String lastName,
    required String comment,
  }) async {
    final invitations = _invitations;
    final permissions = _permissions;
    final account = _account?.account;
    if (invitations == null) {
      throw StateError('Invitations provider is not ready');
    }
    if (permissions == null) {
      throw StateError('Permissions provider is not ready');
    }
    if (account == null) {
      throw StateError('Account is not ready');
    }

    final roleRef = _selectedRoleRef ??
        permissions.roleDescriptions.firstOrNull?.storable.id;
    if (roleRef == null) {
      throw StateError('Role is not selected');
    }

    await invitations.sendInvitation(
      email: email.trim(),
      name: name.trim(),
      lastName: lastName.trim(),
      comment: comment.trim(),
      roleRef: roleRef,
      inviterRef: account.id,
      expiresAt: DateTime.now().toUtc().add(Duration(days: _expiryDays)),
    );
  }

  void bootstrapRoleSelection(List<RoleDescription> roles) {
    if (roles.isEmpty) return;
    final firstRoleRef = roles.first.storable.id;
    final isSelectedAvailable = _selectedRoleRef != null &&
        roles.any((role) => role.storable.id == _selectedRoleRef);
    if (isSelectedAvailable) return;
    _selectedRoleRef = firstRoleRef;
    notifyListeners();
  }
}
