import UIKit
import Shared
import Combine
import Navigation
import XXNavigation
import DrawerFeature
import DependencyInjection
import ScrollViewController

public final class OnboardingCodeController: UIViewController {
  @Dependency var navigator: Navigator
  @Dependency var barStylist: StatusBarStylist

  private lazy var screenView = OnboardingCodeView()
  private lazy var scrollViewController = ScrollViewController()

  private let isEmail: Bool
  private let content: String
  private let viewModel: OnboardingCodeViewModel
  private var cancellables = Set<AnyCancellable>()
  private var drawerCancellables = Set<AnyCancellable>()

  public init(
    _ isEmail: Bool,
    _ content: String,
    _ confirmationId: String
  ) {
    self.viewModel = .init(
      isEmail: isEmail,
      content: content,
      confirmationId: confirmationId
    )
    self.isEmail = isEmail
    self.content = content
    super.init(nibName: nil, bundle: nil)
  }

  required init?(coder: NSCoder) { nil }

  public override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    navigationItem.backButtonTitle = ""
    barStylist.styleSubject.send(.darkContent)
    navigationController?.navigationBar.customize(translucent: true)
  }

  public override func viewDidLoad() {
    super.viewDidLoad()
    setupScrollView()
    setupBindings()

    screenView.setupSubtitle(
      isEmail ?
      Localized.Onboarding.EmailConfirmation.subtitle(content) :
      Localized.Onboarding.PhoneConfirmation.subtitle(content)
    )

    screenView.didTapInfo = { [weak self] in
      guard let self else { return }
      if self.isEmail {
        self.presentInfo(
          title: Localized.Onboarding.EmailConfirmation.Info.title,
          subtitle: Localized.Onboarding.EmailConfirmation.Info.subtitle
        )
      } else {
        self.presentInfo(
          title: Localized.Onboarding.PhoneConfirmation.Info.title,
          subtitle: Localized.Onboarding.PhoneConfirmation.Info.subtitle
        )
      }
    }
  }

  private func setupScrollView() {
    addChild(scrollViewController)
    view.addSubview(scrollViewController.view)
    scrollViewController.view.snp.makeConstraints { $0.edges.equalToSuperview() }
    scrollViewController.didMove(toParent: self)
    scrollViewController.contentView = screenView
    scrollViewController.scrollView.backgroundColor = Asset.neutralWhite.color
  }

  private func setupBindings() {
    screenView
      .inputField
      .textPublisher
      .sink { [unowned self] in
        viewModel.didInput($0)
      }.store(in: &cancellables)

    viewModel
      .statePublisher
      .map(\.status)
      .removeDuplicates()
      .receive(on: DispatchQueue.main)
      .sink { [unowned self] in
        screenView.update(status: $0)
      }.store(in: &cancellables)

    viewModel
      .statePublisher
      .map(\.didConfirm)
      .receive(on: DispatchQueue.main)
      .sink { [unowned self] in
        guard $0 == true else { return }
        if isEmail {
          navigator.perform(PresentOnboardingPhone())
        } else {
          navigator.perform(PresentChatList())
        }
      }.store(in: &cancellables)

    screenView
      .nextButton
      .publisher(for: .touchUpInside)
      .receive(on: DispatchQueue.main)
      .sink { [unowned self] in
        viewModel.didTapNext()
      }.store(in: &cancellables)

    screenView
      .resendButton
      .publisher(for: .touchUpInside)
      .receive(on: DispatchQueue.main)
      .sink { [unowned self] in
        viewModel.didTapResend()
      }.store(in: &cancellables)

    viewModel
      .statePublisher
      .map(\.resendDebouncer)
      .receive(on: DispatchQueue.main)
      .sink { [unowned self] in
        screenView.resendButton.isEnabled = $0 == 0
        if $0 == 0 {
          screenView.resendButton.setTitle(Localized.Profile.Code.resend(""), for: .normal)
        } else {
          screenView.resendButton.setTitle(Localized.Profile.Code.resend("(\($0))"), for: .disabled)
        }
      }.store(in: &cancellables)
  }

  private func presentInfo(title: String, subtitle: String) {
    let actionButton = CapsuleButton()
    actionButton.set(style: .seeThrough, title: Localized.Settings.InfoDrawer.action)

    let drawer = DrawerController(with: [
      DrawerText(
        font: Fonts.Mulish.bold.font(size: 26.0),
        text: title,
        color: Asset.neutralActive.color,
        alignment: .left,
        spacingAfter: 19
      ),
      DrawerText(
        font: Fonts.Mulish.regular.font(size: 16.0),
        text: subtitle,
        color: Asset.neutralBody.color,
        alignment: .left,
        lineHeightMultiple: 1.1,
        spacingAfter: 37
      ),
      DrawerStack(views: [
        actionButton,
        FlexibleSpace()
      ])
    ])

    actionButton.publisher(for: .touchUpInside)
      .receive(on: DispatchQueue.main)
      .sink {
        drawer.dismiss(animated: true) { [weak self] in
          guard let self = self else { return }
          self.drawerCancellables.removeAll()
        }
      }.store(in: &drawerCancellables)

    navigator.perform(PresentDrawer())
  }
}