import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:injectable/injectable.dart';
import 'package:krow/core/application/clients/api/api_client.dart';
import 'package:krow/core/application/clients/api/api_exception.dart';
import 'package:krow/core/data/models/event/event_model.dart';
import 'package:krow/core/data/models/pagination_wrapper/pagination_wrapper.dart';
import 'package:krow/features/events/data/events_gql.dart';

@Injectable()
class EventsApiProvider {
  final ApiClient _client;

  EventsApiProvider({required ApiClient client}) : _client = client;

  Future<PaginationWrapper?> fetchEvents(String status, {String? after}) async {
    final QueryResult result = await _client.query(
        schema: getEventsQuery,
        body: {'status': status, 'first': 30, 'after': after});
    if (result.hasException) {
     throw parseBackendError(result.exception);
    }

    if (result.data == null || result.data!['client_events'] == null) {
      return null;
    }

    return PaginationWrapper<EventModel?>.fromJson(
        result.data!['client_events'], (json) {
      try {
        return EventModel.fromJson(json);
      }catch (e) {
        print(e);
        return null;
      }
        });
  }

  Future<EventModel?> fetchEventById(String id) async {
    final QueryResult result = await _client.query(schema: getEventById, body: {
      'id': id,
    });
    if (result.hasException) {
      throw parseBackendError(result.exception);
    }

    if (result.data == null || result.data!['client_event'] == null) {
      return null;
    }

    return EventModel.fromJson(result.data!['client_event']);
  }

  Future<void> cancelClientEvent(String id) async {
    final QueryResult result = await _client.mutate(
      schema: cancelClientEventMutation,
      body: {'event_id': id},
    );
    if (result.hasException) {
      throw parseBackendError(result.exception);
    }
  }

  Future<void> completeClientEvent(String id, {String? comment}) async {
    final QueryResult result = await _client.mutate(
      schema: completeClientEventMutation,
      body: {'event_id': id, if(comment!=null)'comment': comment.trim()},
    );
    if (result.hasException) {
      print(result.exception.toString());
      throw parseBackendError(result.exception);
    }
  }

  Future<void> trackClientClockin(String positionStaffId) async {
    final QueryResult result = await _client.mutate(
      schema: trackClientClockinMutation,
      body: {'position_staff_id': positionStaffId},
    );
    if (result.hasException) {
      throw parseBackendError(result.exception);
    }
  }

  Future<void> trackClientClockout(String positionStaffId) async {
    final QueryResult result = await _client.mutate(
      schema: trackClientClockoutMutation,
      body: {'position_staff_id': positionStaffId},
    );
    if (result.hasException) {
      throw parseBackendError(result.exception);
    }
  }

  Future<void> notShowedPositionStaff(String positionStaffId) async {
    final QueryResult result = await _client.mutate(
      schema: notShowedPositionStaffMutation,
      body: {'position_staff_id': positionStaffId},
    );
    if (result.hasException) {
      throw parseBackendError(result.exception);
    }
  }

  Future<void> replacePositionStaff(
      String positionStaffId, String reason) async {
    final QueryResult result = await _client.mutate(
      schema: replacePositionStaffMutation,
      body: {'position_staff_id': positionStaffId, 'reason': reason.trim()},
    );
    if (result.hasException) {
      throw parseBackendError(result.exception);
    }
  }
}
