// generated by bun run generate from the SwiftUI SDK and codegen/catalog.ts.
// edit the generator or catalog, then regenerate.
import SwiftUI
import UIKit

private final class SecureFieldModel: ObservableObject {
  @Published var controlled = OneNativeControlled<String>("")
  @Published var controlledFocus = OneNativeControlled<Bool>(false)
  @Published var label: String = ""
  @Published var disabled: Bool = false
  @Published var prompt: String = ""
  @Published var textFieldStyle: String = "automatic"
  @Published var submitLabel: String = ""
  @Published var textInputAutocapitalization: String = ""
  @Published var autocorrectionDisabled: Bool = false
  @Published var keyboardType: String = ""
  @Published var textContentType: String = ""
  @Published var accessibility = OneNativeAccessibility()
  @Published var swiftStyle = OneNativeStyle()
  var active = false
  var onSDKEvent: ((String, String) -> Void)?
  func emitSDKEvent(_ name: String, _ value: String) { if active { onSDKEvent?(name, value) } }

  var syncStateId: Int = 0
  private var syncToken: Int = 0
  func bindSyncState(_ id: Int) {
    if id == syncStateId { return }
    if syncStateId != 0 { OneNativeSyncRegistry.unobserve(Int32(syncStateId), token: syncToken) }
    syncStateId = id
    syncToken = 0
    if id == 0 { return }
    if let current = OneNativeSyncRegistry.get(Int32(id)) as? String { controlled.adopt(current) }
    syncToken = OneNativeSyncRegistry.observe(Int32(id)) { [weak self] value in
      guard let self, let next = value as? String else { return }
      self.controlled.adopt(next)
    }
  }
  deinit {
    if syncStateId != 0 { OneNativeSyncRegistry.unobserve(Int32(syncStateId), token: syncToken) }
  }
  var onChange: ((String, Int, Int) -> Void)?
  func change(_ value: String) {
    guard active, !disabled, controlled.value != value else { return }
    controlled.change(value)
    if syncStateId != 0 { OneNativeSyncRegistry.set(Int32(syncStateId), value: value as NSObject) }
    onChange?(value, controlled.eventCount, controlled.revision)
  }
  var hasNativeFocus = false
  var onFocusChange: ((Bool, Int, Int) -> Void)?
  func changeFocus(_ value: Bool) {
    hasNativeFocus = value
    guard active, !disabled, controlledFocus.value != value else { return }
    controlledFocus.change(value)
    onFocusChange?(value, controlledFocus.eventCount, controlledFocus.revision)
  }
  var onSubmit: ((Int) -> Void)?
  private var submitCount = 0
  func submit() {
    guard active, !disabled else { return }
    submitCount += 1
    onSubmit?(submitCount)
  }
}
@objcMembers public final class OneNativeSecureFieldView: UIView, OneNativeComposable, OneNativeFocusedContent {
  public var onSDKEvent: ((String, String) -> Void)?

  public var onChange: ((String, Int, Int) -> Void)?
  public var onFocusChange: ((Bool, Int, Int) -> Void)?
  public var onSubmit: ((Int) -> Void)?
  private var model = SecureFieldModel()
  @nonobjc var containsComposedFocus: Bool { model.hasNativeFocus }
  public var onHeight: ((CGFloat) -> Void)?
  private var controller: OneNativeHostingController<OneNativeMeasuredStandalone<SecureFieldContent>>?
  public override init(frame: CGRect) { super.init(frame: frame) }
  required init?(coder: NSCoder) { fatalError("init(coder:) is unavailable") }
  public func configureAccessibility(_ label: String, hint: String, value: String, identifier: String) {
    let next = OneNativeAccessibility(label: label, hint: hint, value: value, identifier: identifier)
    if model.accessibility != next { model.accessibility = next }
  }
  public func configureStyle(_ style: [String: Any]) {
    let next = OneNativeStyle(dictionary: style)
    if model.swiftStyle != next {
      let previousRows = model.swiftStyle.sdkModifiers.filter { $0.first?.hasPrefix("listRow") == true }
      let nextRows = next.sdkModifiers.filter { $0.first?.hasPrefix("listRow") == true }
      model.swiftStyle = next
      if previousRows != nextRows { compositionParent?.refreshRow(for: self) }
    }
  }
  public func configure(_ value: String, acknowledgedEvent: Int, revision: Int, syncStateId: Int, focused: Bool, acknowledgedFocusEvent: Int, focusRevision: Int, label: String, disabled: Bool, prompt: String, textFieldStyle: String, submitLabel: String, textInputAutocapitalization: String, autocorrectionDisabled: Bool, keyboardType: String, textContentType: String) {
    if let next = model.controlled.applying(value, acknowledged: acknowledgedEvent, revision: revision) { model.controlled = next }
    model.bindSyncState(syncStateId)
    if let next = model.controlledFocus.applying(focused, acknowledged: acknowledgedFocusEvent, revision: focusRevision) { model.controlledFocus = next }
    if model.label != label { model.label = label }
    if model.disabled != disabled { model.disabled = disabled }
    if model.prompt != prompt { model.prompt = prompt }
    if model.textFieldStyle != textFieldStyle { model.textFieldStyle = textFieldStyle }
    if model.submitLabel != submitLabel { model.submitLabel = submitLabel }
    if model.textInputAutocapitalization != textInputAutocapitalization { model.textInputAutocapitalization = textInputAutocapitalization }
    if model.autocorrectionDisabled != autocorrectionDisabled { model.autocorrectionDisabled = autocorrectionDisabled }
    if model.keyboardType != keyboardType { model.keyboardType = keyboardType }
    if model.textContentType != textContentType { model.textContentType = textContentType }
  }


  private weak var compositionParent: OneNativeCompositionParent?
  public func compositionContent() -> AnyView { AnyView(SecureFieldContent(model: model)) }
  // composed, activation follows the parent: a subtree mounted before root attachment
  // stays silent until the root attaches.
  public func composeInto(_ parent: OneNativeCompositionParent) {
    controller?.detach(); controller = nil
    compositionParent = parent
    bindCallbacks()
    model.active = parent.compositionActive
  }
  public func decompose() { compositionParent = nil; model.active = false }
  public func propagateActive(_ active: Bool) { model.active = active }
  public override func didMoveToWindow() { super.didMoveToWindow(); updateHost() }
  public override func layoutSubviews() { super.layoutSubviews(); updateHost() }
  private func bindCallbacks() {
    model.onSDKEvent = { [weak self] name, value in self?.onSDKEvent?(name, value) }

    model.onChange = { [weak self] value, count, revision in self?.onChange?(value, count, revision) }
    model.onFocusChange = { [weak self] value, count, revision in self?.onFocusChange?(value, count, revision) }
    model.onSubmit = { [weak self] submitCount in self?.onSubmit?(submitCount) }
  }
  private func updateHost() {
    guard compositionParent == nil else { return }
    model.active = false
    guard window != nil else { controller?.detach(); return }
    if controller == nil {
      bindCallbacks()
      controller = OneNativeHostingController(rootView: OneNativeMeasuredStandalone(content: SecureFieldContent(model: model), onHeight: { [weak self] height in self?.onHeight?(height) }))
    }
    controller?.attach(to: self)
    model.active = controller?.isAttached == true
  }
  public func reset() {
    compositionParent = nil
    model.active = false; model.onSDKEvent = nil; model.onChange = nil; model.onFocusChange = nil; model.onSubmit = nil
    controller?.detach(); controller = nil; model = SecureFieldModel()
  }
}
private struct SecureFieldContent: View {
  @ObservedObject var model: SecureFieldModel
  @FocusState private var focused: Bool
  var body: some View {
    SecureField(text: Binding(
        get: { model.controlled.value },
        set: { value in model.change(value) }
      ), prompt: model.prompt.isEmpty ? nil : Text(model.prompt)) {
        Text(model.label)
      }
      .oneNativeTextFieldStyle(model.textFieldStyle)
      .oneNativeSubmitLabel(model.submitLabel)
      .oneNativeTextInputAutocapitalization(model.textInputAutocapitalization)
      .autocorrectionDisabled(model.autocorrectionDisabled)
      .oneNativeKeyboardType(model.keyboardType)
      .oneNativeTextContentType(model.textContentType)
      .onSubmit(of: .text) { model.submit() }
      .focused($focused)
      .onChange(of: focused) { _, isFocused in
        model.changeFocus(isFocused)
      }
      .onChange(of: model.controlledFocus.value) { _, isFocused in
        if focused != isFocused { focused = isFocused }
      }
      .onAppear {
        if model.controlledFocus.value { focused = true }
      }
      .disabled(model.disabled)
      .oneNativeAccessibility(model.accessibility)
      .oneNativeStyle(model.swiftStyle, emit: model.emitSDKEvent)
  }
}
