import 'dart:async';
import 'dart:convert';

import 'package:injectable/injectable.dart';
import 'package:keyboard/data/api/request/chat_prologue_request.dart';
import 'package:keyboard/data/api/response/chat_prologue_response.dart';
import 'package:keyboard/data/api/response/chat_super_reply_response.dart';
import 'package:keyboard/data/api/response/chat_super_speak_response.dart';

import '../../base/base_response.dart';
import '../../di/get_it.dart';
import '../../utils/atmob_log.dart';
import '../../utils/http_handler.dart';
import '../../utils/sse_parse_util.dart';
import '../api/atmob_api.dart';
import '../api/atmob_stream_api.dart';
import '../api/request/chat_super_reply_request.dart';
import '../api/request/chat_super_speak_request.dart';
import '../api/request/deep_seek_chat_request.dart';

@lazySingleton
class ChatRepository {
  final AtmobStreamApi atmobStreamApi;
  final AtmobApi atmobApi;
  var tag = "ChatRepository";

  ChatRepository(this.atmobStreamApi, this.atmobApi) {
    AtmobLog.d(tag, '$tag....init');
  }

  Future<ChatSuperReplyResponse> chatSuperReply({
    required String content,
    required String keyboardId,
    required String characterId,
  }) {
    return atmobApi
        .chatSuperReply(
          ChatSuperReplyRequest(
            content: content,
            keyboardId: keyboardId,
            characterId: characterId,
          ),
        )
        .then(HttpHandler.handle(true));
  }

  Future<ChatSuperSpeakResponse> chatSuperSpeak({
    required String content,
    required String keyboardId,
    required String characterId,
  }) {
    return atmobApi
        .chatSuperSpeak(
          ChatSuperSpeakRequest(
            content: content,
            keyboardId: keyboardId,
            characterId: characterId,
          ),
        )
        .then(HttpHandler.handle(true));
  }

  Future<ChatPrologueResponse> chatPrologue({required String name}) {
    return atmobApi
        .chatPrologue(ChatPrologueRequest(name: name))
        .then(HttpHandler.handle(true));
  }

  Future<Stream<Message>> streamDeepSeek(String chatContent) {
    return atmobStreamApi
        .deepSeekChat(DeepSeekChatRequest(chatContent))
        .then((response) async {
          List<String>? contentType = response.headers['Content-Type'];
          if (contentType != null) {
            for (var value in contentType) {
              if (value.contains('text/event-stream')) {
                return response.stream;
              } else if (value.contains('application/json')) {
                BaseResponse<String> baseResponse = BaseResponse.fromJson(
                  jsonDecode(
                    await response.stream
                        .map((bytes) => utf8.decoder.convert(bytes))
                        .toList()
                        .then((value) => value.join()),
                  ),
                  (json) => json as String,
                );
                throw ServerErrorException(
                  baseResponse.code,
                  baseResponse.message,
                );
              }
            }
          }
          throw Exception('Invalid content type');
        })
        .then((stream) => SSEParseUtil.parse(stream));
  }

  static ChatRepository getInstance() {
    return getIt.get<ChatRepository>();
  }
}
