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

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

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

  final ApiClient _client;

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

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

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

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

  Future<Staff> updateStaffPersonalInfo({
    required String firstName,
    required String? middleName,
    required String lastName,
    required String email,
    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,
          'middle_name': middleName,
          'last_name': lastName,
          'email': email,
        },
        if (multipartFile != null) 'file': multipartFile,
      },
    );

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

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