import UIKit
import Lottie

class PAMLottieManager {
  private static let lottieViewTag = 9998

  var backgroundAlpha: Double = 0.2
  private let getKeyWindow: () -> UIWindow?

  init(getKeyWindow: @escaping () -> UIWindow?) {
    self.getKeyWindow = getKeyWindow
  }

  func showLottie(params: PAM_LottieLoadingParams) {
    DispatchQueue.main.async {
      guard let window = self.getKeyWindow() else { return }

      // Remove existing
      window.viewWithTag(PAMLottieManager.lottieViewTag)?.removeFromSuperview()

      let lottieView = UIView(frame: window.bounds)
      lottieView.backgroundColor = UIColor.black.withAlphaComponent(self.backgroundAlpha)
      lottieView.tag = PAMLottieManager.lottieViewTag
      lottieView.alpha = 0.0

      let containerView = self.makeContainerView()
      lottieView.addSubview(containerView)
      NSLayoutConstraint.activate([
        containerView.centerXAnchor.constraint(equalTo: lottieView.centerXAnchor),
        containerView.centerYAnchor.constraint(equalTo: lottieView.centerYAnchor),
        containerView.widthAnchor.constraint(equalTo: lottieView.widthAnchor, multiplier: 0.8),
      ])

      // Animation view
      let animView = LottieAnimationView()
      animView.translatesAutoresizingMaskIntoConstraints = false
      containerView.addSubview(animView)
      NSLayoutConstraint.activate([
        animView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 16),
        animView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor),
        animView.widthAnchor.constraint(equalToConstant: 182),
        animView.heightAnchor.constraint(equalToConstant: 72),
      ])
      animView.loopMode = .loop
      animView.animationSpeed = 2.0
      self.loadLottieAnimation(from: params.lottie) { animation in
        DispatchQueue.main.async {
          if let anim = animation { animView.animation = anim; animView.play() }
        }
      }

      // Title / subtitle
      var lastAnchor: NSLayoutYAxisAnchor = animView.bottomAnchor
      if let title = params.title {
        let label = self.makeLabel(text: title, fontSize: 20, weight: .semibold, colorHex: PAMColors.titleColor)
        containerView.addSubview(label)
        NSLayoutConstraint.activate([
          label.topAnchor.constraint(equalTo: lastAnchor, constant: 8),
          label.centerXAnchor.constraint(equalTo: containerView.centerXAnchor),
          label.widthAnchor.constraint(lessThanOrEqualToConstant: 250),
        ])
        lastAnchor = label.bottomAnchor
      }
      if let subtitle = params.subtitle {
        let label = self.makeLabel(text: subtitle, fontSize: 14, weight: .medium, colorHex: PAMColors.subtitleColor)
        label.numberOfLines = 0
        containerView.addSubview(label)
        NSLayoutConstraint.activate([
          label.topAnchor.constraint(equalTo: lastAnchor, constant: 8),
          label.centerXAnchor.constraint(equalTo: containerView.centerXAnchor),
          label.widthAnchor.constraint(lessThanOrEqualToConstant: 250),
        ])
        lastAnchor = label.bottomAnchor
      }
      NSLayoutConstraint.activate([
        containerView.bottomAnchor.constraint(equalTo: lastAnchor, constant: 16)
      ])

      window.addSubview(lottieView)
      lottieView.fadeIn()
    }
  }

  func hideLottie(params: PAM_LottieLoadingParams) {
    DispatchQueue.main.async {
      guard let window = self.getKeyWindow() else { return }

      guard let lottieView = window.viewWithTag(PAMLottieManager.lottieViewTag),
            let containerView = lottieView.subviews.first(where: {
              $0.backgroundColor == UIColor(hex: PAMColors.containerBg)
            }) else {
        window.viewWithTag(PAMLottieManager.lottieViewTag)?.fadeOutAndRemove()
        return
      }

      // Update text labels
      if let titleLabel = containerView.subviews.first(where: {
        ($0 as? UILabel)?.font.pointSize == 20
      }) as? UILabel, let title = params.title {
        titleLabel.text = title
      }
      if let subtitleLabel = containerView.subviews.first(where: {
        ($0 as? UILabel)?.font.pointSize == 14
      }) as? UILabel, let subtitle = params.subtitle {
        subtitleLabel.text = subtitle
      }

      // Swap animation
      if let animationView = containerView.subviews.first(where: { $0 is LottieAnimationView }) as? LottieAnimationView {
        self.loadLottieAnimation(from: params.lottie) { newAnimation in
          DispatchQueue.main.async {
            guard let anim = newAnimation else {
              print("⚠️ load Lottie thất bại: \(params.lottie.uri)")
              lottieView.fadeOutAndRemove()
              return
            }
            animationView.animation = anim
            animationView.loopMode = .playOnce
            animationView.animationSpeed = 1.0
            animationView.play { finished in
              if finished { lottieView.fadeOutAndRemove() }
            }
          }
        }
      }
    }
  }

  func loadLottieAnimation(from source: PAM_NativeAssetSource, completion: @escaping (LottieAnimation?) -> Void) {
    let uri = source.uri.trimmingCharacters(in: .whitespacesAndNewlines)

    if uri.hasPrefix("{") && uri.hasSuffix("}") {
      if let data = uri.data(using: .utf8) {
        do {
          completion(try LottieAnimation.from(data: data))
        } catch {
          print("⚠️ Error parsing Lottie JSON: \(error)")
          completion(nil)
        }
      } else { completion(nil) }
      return
    }

    if uri.hasPrefix("http://") || uri.hasPrefix("https://") {
      guard let url = URL(string: uri) else { completion(nil); return }
      LottieAnimation.loadedFrom(url: url) { completion($0) }
    } else {
      let url = URL(fileURLWithPath: uri)
      LottieAnimation.loadedFrom(url: url) { animation in
        if let animation = animation {
          completion(animation)
        } else {
          var name = uri
          if name.hasSuffix(".json") { name = String(name.dropLast(5)) }
          completion(LottieAnimation.named(name))
        }
      }
    }
  }

  // MARK: - Helpers

  private func makeContainerView() -> UIView {
    let v = UIView()
    v.translatesAutoresizingMaskIntoConstraints = false
    v.backgroundColor = UIColor(hex: PAMColors.containerBg)
    v.layer.cornerRadius = 12
    v.clipsToBounds = true
    v.layoutMargins = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
    return v
  }

  private func makeLabel(text: String, fontSize: CGFloat, weight: UIFont.Weight, colorHex: String) -> UILabel {
    let label = UILabel()
    label.text = text
    label.font = .systemFont(ofSize: fontSize, weight: weight)
    label.textColor = UIColor(hex: colorHex)
    label.textAlignment = .center
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
  }
}

// Optional<UIWindow> convenience for guard let in hideLottie
private extension Optional where Wrapped == UIWindow {
  func viewWithTag(_ tag: Int) -> UIView? {
    return self?.viewWithTag(tag)
  }
}
