// ignore_for_file: depend_on_referenced_packages, avoid_web_libraries_in_flutter, avoid_print

import 'dart:async';

import 'package:didvan/models/ai/files_model.dart';
import 'package:didvan/services/storage/storage.dart';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'package:mime/mime.dart';

class AiApiService {
  static const String baseUrl = 'https://api.didvan.app/ai';

  static Future<http.MultipartRequest> initial(
      {required final String url,
      required final String message,
      final int? chatId,
      final FilesModel? file,
      final bool? edite}) async {
    final headers = {
      "Authorization": "Bearer ${await StorageService.getValue(key: 'token')}",
      'Content-Type': 'multipart/form-data'
    };

    var request = http.MultipartRequest('POST', Uri.parse(baseUrl + url))
      ..headers.addAll(headers);

    request.fields['prompt'] = message;
    if (chatId != null) {
      request.fields['chatId'] = chatId.toString();
    }
    if (edite != null) {
      request.fields['edit'] = edite.toString().toLowerCase();
    }

    if (file != null) {
      if (file.duration != null) {
        request.fields['duration'] = file.duration!.inSeconds.toString();
      }
      Uint8List bytes;
      String filename;
      String mimeType;
      if (kIsWeb) {
        // For web platform
        if (file.bytes != null) {
          bytes = file.bytes!;
        } else {
          final Uri audioUri = Uri.parse(file.path.replaceAll('%3A', ':'));

          final http.Response audioResponse = await http.get(audioUri);

          bytes = audioResponse.bodyBytes;

          // final f = File.fromUri(Uri.parse(file.path));
          // bytes = await f.readAsBytes();

          // Fetch the blob using JavaScript interop
          // final blob = await html.window
          //     .fetch(file.path.replaceAll('%3A', ':'))
          //     .then((response) => response.blob());

          // // Read the blob as an array buffer
          // final reader = html.FileReader();
          // reader.readAsArrayBuffer(blob);
          // await reader.onLoadEnd.first;
          // bytes = reader.result as Uint8List;
        }
      } else {
        bytes = await file.main.readAsBytes();
      }
      if (file.isRecorded) {
        filename = '${DateTime.now().millisecondsSinceEpoch ~/ 1000}.mp4';

        mimeType = lookupMimeType(filename, headerBytes: bytes) ?? 'audio/mp4';
      } else {
        filename = file.name!;
        mimeType = lookupMimeType(filename, headerBytes: bytes) ??
            'application/octet-stream';
      }

      request.files.add(http.MultipartFile.fromBytes(
        'file',
        bytes,
        filename: filename,
        contentType: MediaType.parse(mimeType),
      ));
    }

    // print("req: ${request.files}");
    // print("req: ${request.fields}");

    return request;
  }

  Future<Stream<List<int>>> getResponse(http.MultipartRequest req) async {
    try {
      final response = await http.Client().send(req);
      if (response.statusCode != 200) {
        final errorBody = await response.stream.bytesToString();
        print(
            'body: ${req.url} sc: ${response.statusCode}');
        print('res: $errorBody');
        throw Exception(
            'sc is ${response.statusCode}');
      } else {
        return response.stream.asBroadcastStream();
      }
    } catch (e) {
      print('req ${req.url}: $e');
      throw Exception('Failed to load data due to an exception.');
    }
  }
}
