import 'dart:typed_data';

import 'package:hl_lieferservice/model/delivery.dart';
import 'package:hl_lieferservice/feature/delivery/detail/service/notes_service.dart';
import 'package:rxdart/rxdart.dart';

class NoteRepository {
  final NoteService service;

  final _notesStream = BehaviorSubject<List<Note>?>.seeded(null);
  final _imageNoteStream = BehaviorSubject<List<ImageNote>?>.seeded(null);
  final _noteTemplateStream = BehaviorSubject<List<NoteTemplate>?>.seeded(null);

  Stream<List<Note>?> get notes => _notesStream.stream;
  Stream<List<ImageNote>?> get images => _imageNoteStream.stream;
  Stream<List<NoteTemplate>?> get templates => _noteTemplateStream.stream;

  List<Note> get _currentNotes => _notesStream.value ?? [];
  List<ImageNote> get _currentImages => _imageNoteStream.value ?? [];

  NoteRepository({required this.service});

  Future<void> addNote(String deliveryId, String content) async {
    final note = await service.addNote(content, int.parse(deliveryId));
    _currentNotes.add(note);

    _notesStream.add(_currentNotes);
  }

  Future<void> editNote(String noteId, String content) async {
    final newNote = Note(content: content, id: int.parse(noteId));
    await service.editNote(newNote);

    final currentNotes = _notesStream.value;
    final index = _currentNotes.indexWhere((note) => note.id == int.parse(noteId));

    if (index != -1) {
      _currentNotes[index] = newNote;
      _notesStream.add(currentNotes);
    }
  }

  Future<void> deleteNote(String noteId) async {
    await service.deleteNote(int.parse(noteId));
    final currentNotes = _notesStream.value;
    final index = _currentNotes.indexWhere((note) => note.id == int.parse(noteId));
    _currentNotes.removeAt(index);

    _notesStream.add(currentNotes);
  }

  Future<void> loadNotes(String deliveryId) async {
    var (notes, images) = await service.getNotes(deliveryId);

    _notesStream.add(notes);
    _imageNoteStream.add(images);
  }

  Future<void> loadTemplates() async {
    _noteTemplateStream.add(await service.getNoteTemplates());
  }

  Future<void> addImage(String deliveryId, Uint8List bytes) async {
    final fileName =
        "delivery_note_${deliveryId}_${DateTime.timestamp().microsecondsSinceEpoch}.jpg";

    String objectId = await service.uploadImage(
      deliveryId,
      fileName,
      bytes,
      "image/png",
    );
    _currentImages.add(ImageNote.make(objectId, fileName, bytes));
    _imageNoteStream.add(_currentImages);
  }

  Future<void> addNamedImage(String deliveryId, Uint8List bytes, String filename) async {
    String objectId = await service.uploadImage(
      deliveryId,
      filename,
      bytes,
      "image/png",
    );

    _currentImages.add(ImageNote.make(objectId, filename, bytes));
    _imageNoteStream.add(_currentImages);
  }

  Future<void> deleteImage(String deliveryId, String objectId) async {
    await service.removeImage(objectId);

    final index = _currentImages.indexWhere((imageNote) => imageNote.objectId == objectId);
    _currentImages.removeAt(index);
    _imageNoteStream.add(_currentImages);
  }
}
