import '../blocs/organization/organization_state.dart';
import '../models/organization.dart';
import '../models/user.dart';
import 'api_client.dart';
import 'dart:developer' as developer;

class OrgApi {
  final ApiClient _apiClient;

  OrgApi(this._apiClient);

  Future<List<Organization>> getOrganizations() async {
    return await _apiClient.getList(
      '/orgs',
      fromJson: (data) => Organization.fromJson(data),
    );
  }

  Future<Organization> createOrganization(String name) async {
    developer.log('POST /orgs with payload: {"name": "$name"}', name: 'OrgApi');

    try {
      final result = await _apiClient.post(
        '/orgs',
        data: {'name': name},
        fromJson: (data) => Organization.fromJson(data),
      );

      return result;
    } catch (e) {
      rethrow;
    }
  }

  Future<List<Member>> getMembers(String orgId) async {
    return await _apiClient.getList(
      '/orgs/$orgId/members',
      fromJson: (data) => Member.fromJson(data),
    );
  }

  Future<void> updateMemberRole(
    String orgId,
    String userId,
    String role,
  ) async {
    await _apiClient.patch(
      '/orgs/$orgId/members/$userId',
      data: {'role': role},
      fromJson: (data) => data,
    );
  }

  Future<void> removeMember(String orgId, String userId) async {
    await _apiClient.delete('/orgs/$orgId/members/$userId');
  }

  Future<List<User>> searchUsers(String orgId, String query) async {
    return await _apiClient.getList(
      '/orgs/$orgId/users/search?q=$query',
      fromJson: (data) => User.fromJson(data),
    );
  }

  Future<Invitation> createInvitation(
    String orgId,
    String username,
    String role,
  ) async {
    final result = await _apiClient.post(
      '/orgs/$orgId/invitations',
      data: {'username': username, 'role': role},
      fromJson: (data) => Invitation.fromJson(data),
    );
    return result;
  }

  Future<List<Invitation>> getInvitations(String orgId) async {
    return await _apiClient.getList(
      '/orgs/$orgId/invitations',
      fromJson: (data) => Invitation.fromJson(data),
    );
  }

  Future<void> cancelInvitation(String orgId, String invitationId) async {
    await _apiClient.delete('/orgs/$orgId/invitations/$invitationId');
  }

  Future<JoinRequest> createJoinRequest(
    String orgId, {
    String? inviteToken,
  }) async {
    final data = {'orgId': orgId};
    if (inviteToken != null) {
      data['inviteToken'] = inviteToken;
    }
    final result = await _apiClient.post(
      '/join-requests',
      data: data,
      fromJson: (data) => JoinRequest.fromJson(data),
    );
    return result;
  }

  Future<List<JoinRequest>> getJoinRequests(String orgId) async {
    return await _apiClient.getList(
      '/orgs/$orgId/join-requests',
      fromJson: (data) => JoinRequest.fromJson(data),
    );
  }

  Future<void> acceptJoinRequest(
    String orgId,
    String requestId,
    String role,
  ) async {
    await _apiClient.post(
      '/orgs/$orgId/join-requests/$requestId/accept',
      data: {'role': role},
      fromJson: (data) => null,
    );
  }

  Future<void> rejectJoinRequest(String orgId, String requestId) async {
    await _apiClient.post(
      '/orgs/$orgId/join-requests/$requestId/reject',
      fromJson: (data) => null,
    );
  }

  Future<String?> getInviteLink(String orgId) async {
    final result = await _apiClient.getRaw('/orgs/$orgId/invite-link');
    return result['inviteLink'] as String?;
  }

  Future<String> regenerateInviteLink(String orgId) async {
    final result = await _apiClient.post(
      '/orgs/$orgId/invite-link/regenerate',
      fromJson: (data) => data,
    );
    return result['inviteLink'] as String;
  }
}
