import 'dart:io';

import 'package:didvan/models/enums.dart';
import 'package:didvan/models/message_data/message_data.dart';
import 'package:didvan/models/message_data/radar_attachment.dart';
import 'package:didvan/providers/core_provider.dart';
import 'package:didvan/services/media/media.dart';
import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_vibrate/flutter_vibrate.dart';
import 'package:record/record.dart';

class DirectState extends CoreProvier {
  final _recorder = Record();
  final List<MessageData> messages = [];
  late final int typeId;
  final Map<String, List<int>> dailyMessages = {};

  String? text;
  RadarAttachment? replyRadar;
  File? recordedFile;
  int? audioDuration;

  bool isRecording = false;

  Future<void> getMessages() async {
    appState = AppState.busy;
    final RequestService service = RequestService(RequestHelper.direct(typeId));
    await service.httpGet();
    if (service.isSuccess) {
      final messageDatas = service.result['messages'];
      for (var i = 0; i < messageDatas.length; i++) {
        messages.add(MessageData.fromJson(messageDatas[i]));
        _addToDailyGrouped(messages.last);
      }
      appState = AppState.idle;
      return;
    }
    appState = AppState.failed;
  }

  void deleteRecordedFile() {
    recordedFile!.delete();
    recordedFile = null;
    notifyListeners();
  }

  Future<void> startRecording() async {
    text = null;
    await _recorder.hasPermission();
    if (!kIsWeb) {
      Vibrate.feedback(FeedbackType.medium);
    }
    isRecording = true;
    _recorder.start();
    notifyListeners();
  }

  Future<void> stopRecording({required bool sendImidiately}) async {
    final path = await _recorder.stop();
    isRecording = false;
    if (path == null) {
      notifyListeners();
      return;
    }
    if (kIsWeb) {
      final uri = Uri.file(path);
      recordedFile = File.fromUri(uri);
    } else {
      recordedFile = File(path);
    }
    if (sendImidiately) {
      await sendMessage();
    } else {
      notifyListeners();
    }
  }

  void _addToDailyGrouped(MessageData message) {
    String createdAt = message.createdAt.replaceAll('T', ' ').split(' ').first;
    if (!dailyMessages.containsKey(createdAt)) {
      dailyMessages.addAll({
        createdAt: [messages.last.id]
      });
    } else {
      dailyMessages[createdAt]!.add(messages.last.id);
    }
  }

  Future<void> sendMessage() async {
    if ((text == null || text!.isEmpty) && recordedFile == null) return;
    MediaService.audioPlayer.stop();
    messages.insert(
      0,
      MessageData(
        id: 0,
        writedByAdmin: false,
        readed: false,
        createdAt:
            DateTime.now().subtract(const Duration(minutes: 210)).toString(),
        text: text,
        audio: null,
        audioFile: recordedFile,
        radar: replyRadar,
        audioDuration: audioDuration,
      ),
    );
    _addToDailyGrouped(messages.first);
    final body = {};
    if (text != null) {
      body.addAll({'text': text});
    }
    if (replyRadar != null) {
      body.addAll({'radarId': replyRadar!.id});
    }
    final uploadFile = recordedFile;
    text = null;
    recordedFile = null;
    replyRadar = null;
    notifyListeners();
    final service =
        RequestService(RequestHelper.sendDirectMessage(typeId), body: body);
    if (uploadFile == null) {
      service.post();
    } else {
      service.multipart(
        file: uploadFile,
        method: 'POST',
        fieldName: 'audio',
        fileName: 'voice-message',
        mediaExtension: 'm4a',
        mediaFormat: 'audio',
      );
    }
  }
}
