import 'dart:developer';
import 'dart:io';

import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:http/http.dart';
import 'package:http_parser/http_parser.dart';
import 'package:injectable/injectable.dart';
import 'package:krow/core/application/clients/api/api_client.dart';
import 'package:krow/core/data/models/client/client.dart';
import 'package:krow/features/profile/data/gql_schemas.dart';

@singleton
class ClientProfileApiProvider {
  ClientProfileApiProvider(this._client);

  final ApiClient _client;

  Stream<ClientModel> getMeWithCache() async* {
    await for (var response in _client.queryWithCache(
      schema: getPersonalInfoSchema,
    )) {
      if (response == null) continue;

      if (response.hasException) {
        throw Exception(response.exception.toString());
      }

      try {
        final profileData =
            response.data?['client_profile'] as Map<String, dynamic>? ?? {};
        if (profileData.isEmpty) continue;

        yield ClientModel.fromJson(profileData);
      } catch (except) {
        log(
          'Exception in StaffApi on getMeWithCache()',
          error: except,
        );
        continue;
      }
    }
  }

  Future<ClientModel> updatePersonalInfo({
    required String firstName,
    required String lastName,
    required String phone,
    String? avatarPath,
  }) async {
    MultipartFile? multipartFile;
    if (avatarPath != null) {
      var byteData = File(avatarPath).readAsBytesSync();

      multipartFile = MultipartFile.fromBytes(
        'file',
        byteData,
        filename: '${DateTime.now().millisecondsSinceEpoch}.jpg',
        contentType: MediaType('image', 'jpg'),
      );
    }

    final QueryResult result = await _client.mutate(
      schema: multipartFile != null
          ? updateStaffMutationWithAvatarSchema
          : updateStaffMutationSchema,
      body: {
        'input': {
          'first_name': firstName.trim(),
          'last_name': lastName.trim(),
          'phone': phone.trim(),
        },
        if (multipartFile != null) 'file': multipartFile,
      },
    );

    if (result.hasException) {
      throw Exception(result.exception.toString());
    }

    return ClientModel.fromJson(
      (result.data as Map<String, dynamic>)['update_client_profile'],
    );
  }

  Future<void> deactivateClientProfile() async {
    final QueryResult result = await _client.mutate(
      schema: deactivateClientProfileSchema,
    );

    if (result.hasException) {
      throw Exception(result.exception.toString());
    }
  }
}
