//
//  BaseViewController.swift
//  suixinkan
//

import SnapKit
import UIKit

/// 业务 ViewController 基类，提供统一的 UI 搭建流程与通用 UI 能力。
class BaseViewController: UIViewController {

    // MARK: - Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = AppColor.pageBackground
        setupNavigationBar()
        setupUI()
        setupConstraints()
        bindActions()
        registerBaseNotifications()
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    // MARK: - Template Methods

    /// 配置导航栏，子类按需重写。
    func setupNavigationBar() {}

    /// 创建并添加子视图。
    func setupUI() {}

    /// 使用 SnapKit 设置约束。
    func setupConstraints() {}

    /// 绑定 target-action、delegate 等交互。
    func bindActions() {}

    /// Token 失效时回调，子类可重写处理跳转登录等逻辑。
    func onSessionDidExpire() {}

    // MARK: - Loading

    @MainActor
    func showLoading() {
        GlobalLoadingManager.shared.show()
    }

    @MainActor
    func hideLoading() {
        GlobalLoadingManager.shared.hide()
    }

    // MARK: - Toast / Alert

    func showToast(_ message: String, duration: TimeInterval = 2.0) {
        guard !message.isEmpty else { return }

        let container = UIView()
        container.backgroundColor = UIColor.black.withAlphaComponent(0.8)
        container.layer.cornerRadius = AppRadius.sm
        container.clipsToBounds = true
        container.alpha = 0

        let label = UILabel()
        label.text = message
        label.textColor = .white
        label.font = .app(.body)
        label.textAlignment = .center
        label.numberOfLines = 0

        container.addSubview(label)
        view.addSubview(container)

        label.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(UIEdgeInsets(top: 10, left: 16, bottom: 10, right: 16))
        }
        container.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.centerY.equalToSuperview()
            make.leading.greaterThanOrEqualToSuperview().offset(32)
            make.trailing.lessThanOrEqualToSuperview().offset(-32)
        }

        UIView.animate(withDuration: 0.25) {
            container.alpha = 1
        } completion: { _ in
            UIView.animate(withDuration: 0.25, delay: duration) {
                container.alpha = 0
            } completion: { _ in
                container.removeFromSuperview()
            }
        }
    }

    func showError(_ message: String) {
        showToast(message)
    }

    func showAlert(
        title: String?,
        message: String?,
        confirmTitle: String = "确定",
        confirmHandler: (() -> Void)? = nil
    ) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: confirmTitle, style: .default) { _ in
            confirmHandler?()
        })
        present(alert, animated: true)
    }

    // MARK: - Navigation

    func popViewController() {
        navigationController?.popViewController(animated: true)
    }

    /// 沿 presentation 链找到当前最顶层控制器，避免 Sheet 已展示时 present 冲突。
    func topMostPresentedViewController() -> UIViewController {
        var top: UIViewController = self
        while let presented = top.presentedViewController {
            top = presented
        }
        return top
    }

    /// 在当前可见 presentation 链顶端弹出页面。
    func presentOnTop(
        _ viewController: UIViewController,
        animated: Bool = true,
        completion: (() -> Void)? = nil
    ) {
        topMostPresentedViewController().present(viewController, animated: animated, completion: completion)
    }

    /// 全屏预览图片与视频媒体。
    func presentMediaPreview(items: [MediaPreviewItem], startIndex: Int) {
        guard !items.isEmpty else { return }
        presentOnTop(MediaPreviewViewController(items: items, startIndex: startIndex))
    }

    /// 全屏预览网络图片。
    func presentImagePreview(imageURLs: [String], startIndex: Int) {
        guard !imageURLs.isEmpty else { return }
        let items = imageURLs.compactMap { MediaPreviewItem.remoteImage($0) }
        presentMediaPreview(items: items, startIndex: startIndex)
    }

    // MARK: - Notifications

    private func registerBaseNotifications() {
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleSessionDidExpireNotification),
            name: NotificationName.sessionDidExpire,
            object: nil
        )
    }

    @objc private func handleSessionDidExpireNotification() {
        GlobalLoadingManager.shared.hideAll()
        onSessionDidExpire()
    }
}
