//
//  ScenicSelectionViewController.swift
//  suixinkan
//

import SnapKit
import UIKit

/// 景区选择页，对齐 Android `ScenicSelectionScreen`。
final class ScenicSelectionViewController: BaseViewController, UITableViewDataSource, UITableViewDelegate {

    var onSelectionComplete: (() -> Void)?

    private let viewModel: ScenicSelectionViewModel
    private let homeAPI: HomeAPI

    private let bannerView = ScenicPermissionBannerView()
    private let searchBar = ScenicSelectionSearchBar()
    private let locationBar = ScenicCurrentLocationBar()
    private let tableView = UITableView(frame: .zero, style: .plain)
    private let emptyLabel = UILabel()

    init(viewModel: ScenicSelectionViewModel = ScenicSelectionViewModel(), homeAPI: HomeAPI? = nil) {
        self.viewModel = viewModel
        self.homeAPI = homeAPI ?? NetworkServices.shared.homeAPI
        super.init(nibName: nil, bundle: nil)
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func setupNavigationBar() {
        title = "景区选择"
        navigationController?.setNavigationBarHidden(false, animated: false)
    }

    override func setupUI() {
        view.backgroundColor = .white

        tableView.backgroundColor = .clear
        tableView.separatorStyle = .none
        tableView.dataSource = self
        tableView.delegate = self
        tableView.register(ScenicSpotCell.self, forCellReuseIdentifier: ScenicSpotCell.reuseIdentifier)
        tableView.keyboardDismissMode = .onDrag

        emptyLabel.text = "暂无景区"
        emptyLabel.font = .systemFont(ofSize: 14)
        emptyLabel.textColor = AppColor.textTertiary
        emptyLabel.textAlignment = .center
        emptyLabel.isHidden = true

        let contentStack = UIStackView(arrangedSubviews: [searchBar, locationBar])
        contentStack.axis = .vertical
        contentStack.spacing = 16
        contentStack.isLayoutMarginsRelativeArrangement = true
        contentStack.layoutMargins = UIEdgeInsets(top: 0, left: 16, bottom: 16, right: 16)

        let headerStack = UIStackView(arrangedSubviews: [bannerView, contentStack])
        headerStack.axis = .vertical
        headerStack.spacing = 16
        headerStack.setContentHuggingPriority(.required, for: .vertical)
        headerStack.setContentCompressionResistancePriority(.required, for: .vertical)

        view.addSubview(headerStack)
        view.addSubview(tableView)
        view.addSubview(emptyLabel)

        headerStack.snp.makeConstraints { make in
            make.top.equalTo(view.safeAreaLayoutGuide)
            make.leading.trailing.equalToSuperview()
        }
        tableView.snp.makeConstraints { make in
            make.top.equalTo(headerStack.snp.bottom)
            make.leading.trailing.bottom.equalToSuperview()
        }
        emptyLabel.snp.makeConstraints { make in
            make.center.equalTo(tableView)
        }
    }

    override func bindActions() {
        viewModel.onStateChange = { [weak self] in
            Task { @MainActor in self?.applyViewModel() }
        }
        viewModel.onShowMessage = { [weak self] message in
            Task { @MainActor in self?.showToast(message) }
        }
        viewModel.onSelectionComplete = { [weak self] in
            Task { @MainActor in
                self?.onSelectionComplete?()
                self?.navigationController?.popViewController(animated: true)
            }
        }
        viewModel.onNavigateApply = { [weak self] in
            Task { @MainActor in self?.pushPermissionApply() }
        }
        viewModel.onNavigateApplyStatus = { [weak self] applyCode in
            Task { @MainActor in self?.pushPermissionApplyStatus(applyCode: applyCode) }
        }

        bannerView.onApplyNow = { [weak self] in
            guard let self else { return }
            Task { await self.viewModel.onApplyNow(api: self.homeAPI) }
        }
        searchBar.onSearchTextChange = { [weak self] query in
            self?.viewModel.onSearchQueryChange(query)
        }
        locationBar.onRelocate = { [weak self] in
            guard let self else { return }
            Task { await self.viewModel.startLocation() }
        }

        viewModel.loadFromLocal()
        Task { await viewModel.startLocation() }
    }

    private func applyViewModel() {
        locationBar.apply(locationText: viewModel.currentLocationText, isLocating: viewModel.isLocating)
        emptyLabel.isHidden = !viewModel.spots.isEmpty
        tableView.reloadData()
        if viewModel.isLoading {
            showLoading()
        } else {
            hideLoading()
        }
    }

    private func pushPermissionApply(pendingData: RoleApplyPendingResponse? = nil) {
        let controller = PermissionApplyViewController(pendingData: pendingData)
        navigationController?.pushViewController(controller, animated: true)
    }

    private func pushPermissionApplyStatus(applyCode: String) {
        let controller = PermissionApplyStatusViewController(applyCode: applyCode)
        navigationController?.pushViewController(controller, animated: true)
    }

    // MARK: - UITableView

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        viewModel.spots.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(
            withIdentifier: ScenicSpotCell.reuseIdentifier,
            for: indexPath
        ) as! ScenicSpotCell
        let spot = viewModel.spots[indexPath.row]
        cell.apply(spot)
        cell.onTap = { [weak self] in
            self?.viewModel.selectSpot(spot)
        }
        return cell
    }
}
