import UIKit
import Shared
import AppCore
import Combine
import Defaults
import XXClient
import BackupFeature
import XXMessengerClient
import CombineSchedulers
import CountryListFeature
import PermissionsFeature
import ComposableArchitecture

enum ProfileNavigationRoutes {
  case none
  case library
  case libraryPermission
}

struct ProfileViewState: Equatable {
  var email: String?
  var phone: String?
  var photo: UIImage?
}

final class ProfileViewModel {
  @KeyObject(.avatar, defaultValue: nil) var avatar: Data?
  @KeyObject(.email, defaultValue: nil) var emailStored: String?
  @KeyObject(.phone, defaultValue: nil) var phoneStored: String?
  @KeyObject(.username, defaultValue: nil) var username: String?
  @KeyObject(.sharingEmail, defaultValue: false) var isEmailSharing: Bool
  @KeyObject(.sharingPhone, defaultValue: false) var isPhoneSharing: Bool

  @Dependency(\.app.bgQueue) var bgQueue
  @Dependency(\.permissions) var permissions
  @Dependency(\.app.messenger) var messenger
  @Dependency(\.app.hudManager) var hudManager
  @Dependency(\.backupService) var backupService

  var name: String { username! }

  var state: AnyPublisher<ProfileViewState, Never> {
    stateRelay.eraseToAnyPublisher()
  }
  private let stateRelay = CurrentValueSubject<ProfileViewState, Never>(.init())

  var navigation: AnyPublisher<ProfileNavigationRoutes, Never> {
    navigationRoutes.eraseToAnyPublisher()
  }
  private let navigationRoutes = PassthroughSubject<ProfileNavigationRoutes, Never>()

  init() {
    refresh()
  }

  func refresh() {
    var cleanPhone = phoneStored

    if let phone = cleanPhone {
      let country = Country.findFrom(phone)
      cleanPhone = "\(country.prefix)\(phone.dropLast(2))"
    }

    stateRelay.value = .init(
      email: emailStored,
      phone: cleanPhone,
      photo: avatar != nil ? UIImage(data: avatar!) : nil
    )
  }

  func didRequestLibraryAccess() {
    if permissions.library.status() {
      navigationRoutes.send(.library)
    } else {
      navigationRoutes.send(.libraryPermission)
    }
  }

  func didNavigateSomewhere() {
    navigationRoutes.send(.none)
  }

  func didChoosePhoto(_ photo: UIImage) {
    stateRelay.value.photo = photo
    avatar = photo.jpegData(compressionQuality: 0.0)
  }

  func didTapDelete(isEmail: Bool) {
    hudManager.show()

    bgQueue.schedule { [weak self] in
      guard let self else { return }
      do {
        try self.messenger.ud.get()!.removeFact(
          .init(
            type: isEmail ? .email : .phone,
            value: isEmail ? self.emailStored! : self.phoneStored!
          )
        )
        if isEmail {
          self.emailStored = nil
          self.isEmailSharing = false
        } else {
          self.phoneStored = nil
          self.isPhoneSharing = false
        }
        self.backupService.didUpdateFacts()
        self.hudManager.hide()
        self.refresh()
      } catch {
        let xxError = CreateUserFriendlyErrorMessage.live(error.localizedDescription)
        self.hudManager.show(.init(content: xxError))
      }
    }
  }
}