import Combine
import SwiftUI

final class VM: ObservableObject {
  /*
  @Published var text = ""
  let changeText = PassthroughSubject<String, Never>()
    
  @Published var t2 = "a:value"
  var bt2: Binding<String>!
  */

  @Published var t3 = "a:value"
  
  var subscriptions = Set<AnyCancellable>()

  init() {
      $t3
          .debounce(for: .seconds(0.3), scheduler: DispatchQueue.main)
          .sink { v in
              /**/print("ИГР VM.init t3: '\(v)'")
              // Ignore repoting application initiated strings
              // Only report user initiated strings
              guard v.hasPrefix("u:") else { return }
              Bus.send(MeetupId.Keys.meetupIdTextUI.rawValue, String(v.dropFirst(2)))
          }
          .store(in: &subscriptions)

      Bus.receiveAsync(
        &subscriptions,
        [MeetupId.Keys.meetupIdTextApp.rawValue],
        { [weak self] _, v in self?.applyFormattedValue(v) }
      )


/*
      bt2 = Binding<String>(
          get: { [weak self] in
              String(self?.t2.dropFirst(2) ?? "")
          },
          set: { [weak self] v in
              if v.hasPrefix("a:") {
                  self?.t2 = v
              } else {
                  self?.t2 = "u:\(v)"
              }
          }
      )
      
      $t2
          .debounce(for: .seconds(0.3), scheduler: DispatchQueue.main)
          .sink { v in
              /**/print("ИГР VM.init t2: '\(v)'")
              // Ignore repoting application initiated strings
              // Only report user initiated strings
              guard v.hasPrefix("u:") else { return }
              Bus.Service.singleton?.send(MeetupId.Keys.meetupIdTextUI.rawValue, String(v.dropFirst(2)))
          }
          .store(in: &subscriptions)
      
      Bus.receive(
        &subscriptions,
        [MeetupId.Keys.meetupIdTextApp.rawValue],
        { [weak self] k, v in self?.handleAppValue(k, v) }
      )
      
    // Интерпретируем текст с задержкой, потому что:
    // 1. смена @Published в ту же секунду игнорируется
    //    полем ввода, т.е. нужна задержка
    // 2. ожидаем окончания ввода (спама), чтобы
    //    обработать введённое без потерь из-за конфликта
    //    старых данных и новых.
    $text
      .debounce(for: .seconds(0.3), scheduler: DispatchQueue.main)
      .sink { [weak self] v in
          guard
              let out = MeetupId.shouldFormat(v),
              v != out
          else {
              return
          }
          /**/print("ИГР TFCVM.init changeT in/out: '\(v)'/'\(out)'")
          self?.text = out
      }
      .store(in: &subscriptions)
 */
  }
    
  func applyFormattedValue(_ value: String) {
      /**/print("ИГР VM.handleFV value: '\(value)'")
      t3 = "a:\(value)"
  }
    
}