import Foundation
import StoreKit
import React

@objc(LayersSKAN)
class LayersSKAN: NSObject {

  private var conversionValue: Int = 0
  private var isRegistered: Bool = false

  // MARK: - Availability Check

  @objc
  func isAvailable(_ resolve: @escaping (Any?) -> Void, rejecter reject: @escaping (String?, String?, Error?) -> Void) {
    #if targetEnvironment(simulator)
      resolve(false)
    #else
      if #available(iOS 14.0, *) {
        resolve(true)
      } else {
        resolve(false)
      }
    #endif
  }

  // MARK: - Version Detection

  @objc
  func getVersion(_ resolve: @escaping (Any?) -> Void, rejecter reject: @escaping (String?, String?, Error?) -> Void) {
    if #available(iOS 16.1, *) {
      resolve("4.0")
    } else if #available(iOS 15.4, *) {
      resolve("3.0")
    } else if #available(iOS 14.5, *) {
      resolve("2.2")
    } else if #available(iOS 14.0, *) {
      resolve("2.0")
    } else {
      resolve("0.0")
    }
  }

  // MARK: - Registration

  @objc
  func registerAppForAdNetworkAttribution(_ resolve: @escaping (Any?) -> Void, rejecter reject: @escaping (String?, String?, Error?) -> Void) {
    #if targetEnvironment(simulator)
      print("[Layers SKAN] Skipping registration on simulator")
      resolve(nil)
      return
    #endif

    if #available(iOS 14.0, *) {
      SKAdNetwork.registerAppForAdNetworkAttribution()
      isRegistered = true
      print("[Layers SKAN] App registered for ad network attribution")
      resolve(nil)
    } else {
      reject("UNAVAILABLE", "SKAdNetwork requires iOS 14.0+", nil)
    }
  }

  // MARK: - Conversion Value Updates (SKAN 3.0)

  @objc
  func updateConversionValue(_ value: NSNumber, resolver resolve: @escaping (Any?) -> Void, rejecter reject: @escaping (String?, String?, Error?) -> Void) {
    #if targetEnvironment(simulator)
      print("[Layers SKAN] Simulated conversion value update: \(value)")
      conversionValue = value.intValue
      resolve(nil)
      return
    #endif

    guard #available(iOS 14.0, *) else {
      reject("UNAVAILABLE", "SKAdNetwork requires iOS 14.0+", nil)
      return
    }

    let intValue = value.intValue
    guard intValue >= 0 && intValue <= 63 else {
      reject("INVALID_VALUE", "Conversion value must be 0-63", nil)
      return
    }

    // Only allow increasing values
    guard intValue >= conversionValue else {
      print("[Layers SKAN] Ignoring decrease from \(conversionValue) to \(intValue)")
      resolve(nil)
      return
    }

    if #available(iOS 14.0, *) {
      LayersSKANCompat.updateConversionValue(intValue) { error in
        if let error = error {
          print("[Layers SKAN] Error updating conversion value: \(error.localizedDescription)")
          reject("UPDATE_FAILED", error.localizedDescription, error)
        } else {
          self.conversionValue = intValue
          print("[Layers SKAN] Conversion value updated to: \(intValue)")
          resolve(nil)
        }
      }
    }
  }

  // MARK: - Postback Conversion Value (SKAN 4.0)

  @objc
  func updatePostbackConversionValue(_ value: NSNumber, coarseValue: String?, lockWindow: NSNumber?, resolver resolve: @escaping (Any?) -> Void, rejecter reject: @escaping (String?, String?, Error?) -> Void) {
    #if targetEnvironment(simulator)
      print("[Layers SKAN] Simulated postback update: value=\(value), coarse=\(coarseValue ?? "nil"), lock=\(lockWindow ?? 0)")
      conversionValue = value.intValue
      resolve(nil)
      return
    #endif

    let intValue = value.intValue
    guard intValue >= 0 && intValue <= 63 else {
      reject("INVALID_VALUE", "Fine conversion value must be 0-63", nil)
      return
    }

    let coarseStr = coarseValue?.lowercased()
    let lock = lockWindow?.boolValue ?? false

    if #available(iOS 14.0, *) {
      LayersSKANCompat.updatePostbackConversionValue(intValue, coarseString: coarseStr, lockWindow: lock) { error in
        if let error = error {
          print("[Layers SKAN] Error updating postback: \(error.localizedDescription)")
          reject("UPDATE_FAILED", error.localizedDescription, error)
        } else {
          self.conversionValue = intValue
          print("[Layers SKAN] Postback updated: value=\(intValue), coarse=\(coarseStr ?? "nil"), lock=\(lock)")
          resolve(nil)
        }
      }
    } else {
      reject("UNAVAILABLE", "SKAdNetwork requires iOS 14.0+", nil)
    }
  }

  // MARK: - Impression Attribution (SKAN 4.0)

  @objc
  func startImpression(_ signature: String, resolver resolve: @escaping (Any?) -> Void, rejecter reject: @escaping (String?, String?, Error?) -> Void) {
    guard #available(iOS 16.1, *) else {
      reject("UNAVAILABLE", "Impression attribution requires iOS 16.1+", nil)
      return
    }

    // Note: This requires additional setup with ad networks
    // For now, just log it
    print("[Layers SKAN] Start impression: \(signature)")
    resolve(nil)
  }

  @objc
  func endImpression(_ signature: String, resolver resolve: @escaping (Any?) -> Void, rejecter reject: @escaping (String?, String?, Error?) -> Void) {
    guard #available(iOS 16.1, *) else {
      reject("UNAVAILABLE", "Impression attribution requires iOS 16.1+", nil)
      return
    }

    print("[Layers SKAN] End impression: \(signature)")
    resolve(nil)
  }

  // MARK: - Current State

  @objc
  func getCurrentConversionValue(_ resolve: @escaping (Any?) -> Void, rejecter reject: @escaping (String?, String?, Error?) -> Void) {
    resolve(conversionValue)
  }

  @objc
  func getAttributionData(_ resolve: @escaping (Any?) -> Void, rejecter reject: @escaping (String?, String?, Error?) -> Void) {
    // Note: Attribution data is delivered via postbacks, not directly readable
    // This is a placeholder for compatibility
    resolve(nil)
  }

  // MARK: - React Native Bridge

  @objc
  static func requiresMainQueueSetup() -> Bool {
    return false
  }
}
