//
//  SplashOverlay.swift
//  ylgamehall
//
//  与 LaunchScreen 同款启动图 + UIProgressView + 状态文字标签的复合 view，
//  大厅 / 子游戏 boot pipeline 期间覆盖在 WebView 上方，加载完成 fade out 后移除。
//
//  内置错误态 UI（title + message + 单按钮）：仅大厅启动期使用——拉远端配置 /
//  解压 / IPA 升级失败时调 showError(...)，按错误 kind 切换"重试" / "前往设置"
//  按钮语义；子游戏目前不调用，沿用 fatal alert 路径。
//

import UIKit

final class SplashOverlay: UIView {

    private let imageView = UIImageView()
    private let progressView = UIProgressView(progressViewStyle: .default)
    private let label = UILabel()

    // 错误态 UI（默认隐藏；showError 时显示，覆盖在 label/progress 区域）
    private let errorContainer = UIStackView()
    private let errorTitleLabel = UILabel()
    private let errorMessageLabel = UILabel()
    private let retryButton = UIButton(type: .system)

    /// 用户点重试按钮时调（启动期 splash 期间）
    var onRetry: (() -> Void)?

    init() {
        super.init(frame: .zero)
        backgroundColor = .black

        // 与 LaunchScreen.storyboard 同款 contentMode = scaleAspectFill：
        // 素材是 1136×640（16:9）横屏画面，现代 iPhone 横屏约 19.5:9 比 16:9 更宽，
        // scaleAspectFill 高度撑满 + 宽度按比例放大→左右轻微裁切；启动图左右是空白底色，
        // logo + 文字主体居中可见，裁切无影响。
        // 等价 daoqi msext LaunchImage Asset Catalog 时代「启动图覆盖整屏」的体感，
        // 避免 scaleAspectFit 在现代屏左右补大黑边。
        imageView.contentMode = .scaleAspectFill
        imageView.image = UIImage(named: "SplashImage")
        imageView.clipsToBounds = true
        imageView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(imageView)

        // SplashImage 底部是白色留白，白字会完全融进去 → 用黑色。
        label.textColor = .black
        label.font = .systemFont(ofSize: 14, weight: .medium)
        label.textAlignment = .center
        label.numberOfLines = 1
        label.translatesAutoresizingMaskIntoConstraints = false
        addSubview(label)

        progressView.translatesAutoresizingMaskIntoConstraints = false
        progressView.isHidden = true
        // 进度条填充黑色 + 轨道用**不透明**浅灰（systemGray5）。
        // 之前用 label.withAlphaComponent(0.15) 半透明轨道，会透出 splash 启动图的颜色，
        // 黑色填充推进时视觉上像"把彩色压成黑色 → 颜色逐渐加深"。改实色轨道后两侧都是
        // 实色，过渡是干脆的"黑色滑过灰色"，无加深错觉。
        progressView.progressTintColor = .black
        progressView.trackTintColor = .systemGray5
        addSubview(progressView)

        setupErrorContainer()

        NSLayoutConstraint.activate([
            imageView.topAnchor.constraint(equalTo: topAnchor),
            imageView.bottomAnchor.constraint(equalTo: bottomAnchor),
            imageView.leadingAnchor.constraint(equalTo: leadingAnchor),
            imageView.trailingAnchor.constraint(equalTo: trailingAnchor),

            label.centerXAnchor.constraint(equalTo: centerXAnchor),
            label.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor, constant: -32),
            label.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor, constant: 24),
            label.trailingAnchor.constraint(lessThanOrEqualTo: trailingAnchor, constant: -24),

            progressView.centerXAnchor.constraint(equalTo: centerXAnchor),
            progressView.bottomAnchor.constraint(equalTo: label.topAnchor, constant: -12),
            progressView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.7),

            errorContainer.centerXAnchor.constraint(equalTo: centerXAnchor),
            errorContainer.centerYAnchor.constraint(equalTo: centerYAnchor, constant: 60),
            errorContainer.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor, constant: 24),
            errorContainer.trailingAnchor.constraint(lessThanOrEqualTo: trailingAnchor, constant: -24),
            errorContainer.widthAnchor.constraint(lessThanOrEqualTo: widthAnchor, multiplier: 0.7)
        ])
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) { fatalError("SplashOverlay does not support init(coder:)") }

    func update(text: String, progress: Double?) {
        label.text = text
        if let p = progress {
            progressView.isHidden = false
            // 用 animated:true 让填充宽度在两个 progress 值之间平滑过渡。
            // 下载回调来得快（甚至同一 RunLoop 多次），不动画会出现"看不到中间帧、
            // 一瞬间跳到 100%"的视觉。animated:true 是 UIKit 的标准进度条用法。
            progressView.setProgress(Float(p), animated: true)
        } else {
            progressView.isHidden = true
            progressView.setProgress(0, animated: false)
        }
    }

    /// 显示错误态。隐藏 imageView / label / progress，背景改为浅色系统背景，
    /// 展示 title + message + 单个按钮（点击触发 onRetry）。
    /// 按钮文字由调用方按错误 kind 决定（"重试" / "前往设置"），同一个按钮承担双语义。
    /// 启动图是浅色 + 复杂图案（不适合在上面叠文字），错误态下改纯净浅背景对比清晰。
    func showError(title: String, message: String, actionTitle: String = "重试") {
        imageView.isHidden = true
        label.isHidden = true
        progressView.isHidden = true
        backgroundColor = .systemBackground
        errorTitleLabel.text = title
        errorMessageLabel.text = message
        var cfg = retryButton.configuration
        cfg?.title = actionTitle
        retryButton.configuration = cfg
        errorContainer.isHidden = false
    }

    /// 关闭错误态，恢复 splash 默认状态（启动图 + loading 文案；runBootPipeline 重新进入时调）。
    func hideError() {
        errorContainer.isHidden = true
        imageView.isHidden = false
        label.isHidden = false
        backgroundColor = .black
    }

    private func setupErrorContainer() {
        // 错误态在浅色 systemBackground 上展示，文字用 .label / .secondaryLabel
        // 系统语义色（浅模式深、深模式浅），保证两种 iOS appearance 下都看得清。
        errorTitleLabel.textColor = .label
        errorTitleLabel.font = .systemFont(ofSize: 18, weight: .semibold)
        errorTitleLabel.textAlignment = .center
        errorTitleLabel.numberOfLines = 1

        errorMessageLabel.textColor = .secondaryLabel
        errorMessageLabel.font = .systemFont(ofSize: 14)
        errorMessageLabel.textAlignment = .center
        errorMessageLabel.numberOfLines = 0

        var cfg = UIButton.Configuration.filled()
        cfg.title = "重试"
        cfg.baseBackgroundColor = .black
        cfg.baseForegroundColor = .white
        cfg.cornerStyle = .medium
        cfg.contentInsets = NSDirectionalEdgeInsets(top: 8, leading: 24, bottom: 8, trailing: 24)
        retryButton.configuration = cfg

        retryButton.addAction(UIAction { [weak self] _ in self?.onRetry?() }, for: .touchUpInside)

        errorContainer.axis = .vertical
        errorContainer.alignment = .center
        errorContainer.spacing = 12
        errorContainer.isHidden = true
        errorContainer.translatesAutoresizingMaskIntoConstraints = false
        errorContainer.addArrangedSubview(errorTitleLabel)
        errorContainer.addArrangedSubview(errorMessageLabel)
        errorContainer.addArrangedSubview(retryButton)
        addSubview(errorContainer)

        NSLayoutConstraint.activate([
            retryButton.heightAnchor.constraint(equalToConstant: 40),
            retryButton.widthAnchor.constraint(greaterThanOrEqualToConstant: 120)
        ])
    }
}
