// ignore_for_file: public_member_api_docs, sort_constructors_first
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

import 'dart:async';

import 'package:architecture_example/domain/entities/photo.dart';
import 'package:architecture_example/domain/usecases/photos/add_photo_to_favorites.dart';
import 'package:architecture_example/domain/usecases/photos/check_if_photo_is_in_favorites.dart';
import 'package:architecture_example/domain/usecases/photos/display_photo.dart';
import 'package:architecture_example/domain/usecases/photos/remove_photo_from_favorites.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

part 'photo_details_state.dart';

class PhotoDetailsCubit extends Cubit<PhotoDetailsState> {
  final DisplayPhoto _displayPhoto;
  final CheckIfPhotoIsInFavorites _checkIfPhotoIsInFavorites;
  final AddPhotoToFavorites _addPhotoToFavorites;
  final RemovePhotoFromFavorites _removePhotoFromFavorites;

  PhotoDetailsCubit(
    this._displayPhoto,
    this._checkIfPhotoIsInFavorites,
    this._addPhotoToFavorites,
    this._removePhotoFromFavorites,
  ) : super(PhotoDetailsInitial());

  FutureOr<void> load(int photoId) async {
    final photo = await _displayPhoto.call(photoId);
    final isFavorite = await _checkIfPhotoIsInFavorites.call(photoId);

    emit(
      photo.fold(
        (value) => PhotoDetailsSuccess(
          value,
          isFavorite: isFavorite.fold((value) => value, (error) => false),
        ),
        (error) => PhotoDetailsFailure(error.toString()),
      ),
    );
  }

  FutureOr<void> addToFavorites() async {
    if (state is! PhotoDetailsSuccess) {
      return;
    }
    final actualState = state as PhotoDetailsSuccess;
    final response = await _addPhotoToFavorites.call(actualState.photo);
    if (response.isOk) {
      emit(PhotoDetailsSuccess(actualState.photo, isFavorite: true));
    }
  }

  FutureOr<void> removeFromFavorites() async {
    if (state is! PhotoDetailsSuccess) {
      return;
    }
    final actualState = state as PhotoDetailsSuccess;
    final response = await _removePhotoFromFavorites.call(actualState.photo.id);
    if (response.isOk) {
      emit(PhotoDetailsSuccess(actualState.photo, isFavorite: false));
    }
  }
}
