//
//  PaymentCollectionDetailsViewController.swift
//  suixinkan
//

import Kingfisher
import SnapKit
import UIKit

/// 收款详情页，展示收款二维码、设金额、保存二维码与语音开关。
final class PaymentCollectionDetailsViewController: BaseViewController {

    private let viewModel = PaymentCollectionDetailsViewModel()
    private let paymentAPI = NetworkServices.shared.paymentAPI

    private let scrollView = UIScrollView()
    private let contentContainerView = UIView()
    private let contentStack = UIStackView()

    private let backgroundImageView = UIImageView()
    private let brandHeaderStack = UIStackView()
    private let brandLogoImageView = UIImageView()
    private let brandTitleLabel = UILabel()
    private let brandSubtitleLabel = UILabel()

    private let qrCardView = UIView()
    private let scenicNameLabel = UILabel()
    private let qrContainerView = UIView()
    private let qrImageView = UIImageView()
    private let qrPlaceholderView = UIView()
    private let qrErrorLabel = UILabel()
    private let refreshButton = UIButton(type: .system)
    private let setAmountButton = UIButton(type: .system)
    private let saveQRButton = UIButton(type: .system)
    private let actionRow = UIStackView()

    private let infoCardView = UIView()
    private let scenicRow = PaymentInfoRowView(title: "景区名称")
    private let merchantRow = PaymentInfoRowView(title: "收款方")
    private let staffRow = PaymentInfoRowView(title: "员工 ID")
    private let photographerRow = PaymentInfoRowView(title: "摄影师名称")
    private let storeRow = PaymentInfoRowView(title: "店铺名称")

    private let recordRow = PaymentNavigationRowView(title: "收款记录")

    private let settingsCardView = UIView()
    private let voiceCardView = UIView()
    private let voiceTitleLabel = UILabel()
    private let voiceSwitch = UISwitch()

    private var amountDialog: PaymentSetAmountDialogView?
    private var appliedBrandConfig: PayPageConfig?
    private var appliedBrandingRefreshVersion = -1

    private var previousStandardAppearance: UINavigationBarAppearance?
    private var previousScrollEdgeAppearance: UINavigationBarAppearance?
    private var previousCompactAppearance: UINavigationBarAppearance?
    private var previousNavigationTintColor: UIColor?
    private var previousNavigationTranslucency = false

    private var brandScreenHeight: CGFloat {
        UIScreen.main.bounds.height
    }

    private var brandLogoHeight: CGFloat {
        if brandScreenHeight <= 700 { return 82 }
        if brandScreenHeight <= 820 { return 96 }
        return 112
    }

    private var brandQRContainerSize: CGFloat {
        if brandScreenHeight <= 700 { return 170 }
        if brandScreenHeight <= 820 { return 190 }
        return 210
    }

    private var brandQRImageSize: CGFloat {
        if brandScreenHeight <= 700 { return 146 }
        if brandScreenHeight <= 820 { return 166 }
        return 182
    }

    private var brandSectionSpacing: CGFloat {
        if brandScreenHeight <= 700 { return 8 }
        if brandScreenHeight <= 820 { return 10 }
        return 12
    }

    private var brandHeaderToQRSpacing: CGFloat {
        if brandScreenHeight <= 700 { return 16 }
        if brandScreenHeight <= 820 { return 18 }
        return 20
    }

    override func setupNavigationBar() {
        title = viewModel.usesNalatiBranding ? nil : "收款详情"
    }

    override func setupUI() {
        let usesBranding = viewModel.usesNalatiBranding
        view.backgroundColor = usesBranding ? .clear : AppColor.pageBackground
        scrollView.showsVerticalScrollIndicator = !usesBranding
        scrollView.isScrollEnabled = !usesBranding
        scrollView.alwaysBounceVertical = false

        contentStack.axis = .vertical
        contentStack.spacing = usesBranding ? brandSectionSpacing : AppSpacing.md

        qrCardView.backgroundColor = usesBranding ? .clear : .white
        qrCardView.layer.cornerRadius = AppRadius.lg

        scenicNameLabel.font = .systemFont(ofSize: 16, weight: .medium)
        scenicNameLabel.textColor = AppColor.textPrimary
        scenicNameLabel.textAlignment = .center

        qrImageView.contentMode = .scaleAspectFit
        qrImageView.isHidden = true
        if usesBranding {
            qrContainerView.backgroundColor = .white
            qrContainerView.layer.cornerRadius = 10
            qrContainerView.clipsToBounds = true
            qrContainerView.isHidden = true
            qrContainerView.addSubview(qrImageView)
        }

        qrPlaceholderView.backgroundColor = AppColor.inputBackground
        qrPlaceholderView.layer.cornerRadius = usesBranding ? 10 : 24
        qrPlaceholderView.isHidden = true

        qrErrorLabel.text = "未选景区或网络问题"
        qrErrorLabel.font = .systemFont(ofSize: 14)
        qrErrorLabel.textColor = AppColor.danger
        qrErrorLabel.textAlignment = .center

        refreshButton.setTitle("点击刷新", for: .normal)
        refreshButton.setTitleColor(AppColor.primary, for: .normal)
        refreshButton.titleLabel?.font = .systemFont(ofSize: 14)

        actionRow.axis = .horizontal
        actionRow.alignment = .center
        actionRow.spacing = usesBranding ? AppSpacing.lg : AppSpacing.xl
        if usesBranding {
            actionRow.backgroundColor = UIColor.white.withAlphaComponent(0.88)
            actionRow.layer.cornerRadius = 24
            actionRow.isLayoutMarginsRelativeArrangement = true
            actionRow.directionalLayoutMargins = NSDirectionalEdgeInsets(
                top: 10,
                leading: 24,
                bottom: 10,
                trailing: 24
            )
        }

        configureLinkButton(setAmountButton, title: "设置金额")
        configureLinkButton(saveQRButton, title: "保存二维码")

        configureCard(infoCardView, branded: usesBranding)

        recordRow.backgroundColor = usesBranding ? .clear : .white
        recordRow.layer.cornerRadius = usesBranding ? 0 : AppRadius.lg

        voiceCardView.backgroundColor = usesBranding ? .clear : .white
        voiceCardView.layer.cornerRadius = usesBranding ? 0 : AppRadius.lg

        voiceTitleLabel.text = "收款到账语音提醒"
        voiceTitleLabel.font = .systemFont(ofSize: 14)
        voiceTitleLabel.textColor = UIColor(hex: 0x4B5563)

        voiceSwitch.onTintColor = AppColor.primary

        if usesBranding {
            configureBrandHeader()
            backgroundImageView.contentMode = .scaleAspectFill
            backgroundImageView.clipsToBounds = true
            backgroundImageView.image = UIImage(named: "payment_nalati_background")
            view.addSubview(backgroundImageView)
        }

        view.addSubview(scrollView)
        scrollView.addSubview(contentContainerView)
        contentContainerView.addSubview(contentStack)

        if usesBranding {
            contentStack.addArrangedSubview(brandHeaderStack)
            contentStack.setCustomSpacing(brandHeaderToQRSpacing, after: brandHeaderStack)
        }
        contentStack.addArrangedSubview(qrCardView)
        contentStack.addArrangedSubview(infoCardView)
        if usesBranding {
            configureCard(settingsCardView, branded: true)
            contentStack.addArrangedSubview(settingsCardView)
        } else {
            contentStack.addArrangedSubview(recordRow)
            contentStack.addArrangedSubview(voiceCardView)
        }

        let qrDisplayView = usesBranding ? qrContainerView : qrImageView
        let qrContentStack = UIStackView(arrangedSubviews: [
            scenicNameLabel,
            qrDisplayView,
            qrPlaceholderView,
            actionRow,
        ])
        qrContentStack.axis = .vertical
        qrContentStack.alignment = .center
        qrContentStack.spacing = usesBranding ? brandSectionSpacing : AppSpacing.lg
        qrCardView.addSubview(qrContentStack)

        qrPlaceholderView.addSubview(qrErrorLabel)
        qrPlaceholderView.addSubview(refreshButton)

        actionRow.addArrangedSubview(setAmountButton)
        if usesBranding {
            let divider = UIView()
            divider.backgroundColor = UIColor(hex: 0xD6E1EE)
            actionRow.addArrangedSubview(divider)
            divider.snp.makeConstraints { make in
                make.width.equalTo(1)
                make.height.equalTo(24)
            }
        }
        actionRow.addArrangedSubview(saveQRButton)

        let infoRows = usesBranding
            ? [photographerRow, storeRow]
            : [scenicRow, merchantRow, staffRow]
        let infoStack = UIStackView(arrangedSubviews: infoRows)
        infoStack.axis = .vertical
        infoCardView.addSubview(infoStack)

        voiceCardView.addSubview(voiceTitleLabel)
        voiceCardView.addSubview(voiceSwitch)

        if usesBranding {
            let settingsStack = UIStackView(arrangedSubviews: [recordRow, voiceCardView])
            settingsStack.axis = .vertical
            settingsCardView.addSubview(settingsStack)
            settingsStack.snp.makeConstraints { make in
                make.edges.equalToSuperview()
            }

            let divider = UIView()
            divider.backgroundColor = UIColor(hex: 0xD9E2EA).withAlphaComponent(0.75)
            settingsCardView.addSubview(divider)
            divider.snp.makeConstraints { make in
                make.leading.trailing.equalToSuperview().inset(AppSpacing.md)
                make.centerY.equalToSuperview()
                make.height.equalTo(0.5)
            }
        }

        qrContentStack.snp.makeConstraints { make in
            let verticalInset: CGFloat = usesBranding ? 0 : 32
            make.edges.equalToSuperview().inset(
                UIEdgeInsets(top: verticalInset, left: 16, bottom: verticalInset, right: 16)
            )
        }
        scenicNameLabel.isHidden = usesBranding
        scenicNameLabel.snp.makeConstraints { make in
            make.leading.trailing.equalToSuperview()
        }
        if usesBranding {
            qrContainerView.snp.makeConstraints { make in
                make.width.height.equalTo(brandQRContainerSize)
            }
            qrImageView.snp.makeConstraints { make in
                make.center.equalToSuperview()
                make.width.height.equalTo(brandQRImageSize)
            }
        } else {
            qrImageView.snp.makeConstraints { make in
                make.width.height.equalTo(182)
            }
        }
        qrPlaceholderView.snp.makeConstraints { make in
            make.width.height.equalTo(usesBranding ? brandQRContainerSize : 182)
        }
        qrErrorLabel.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(56)
            make.leading.trailing.equalToSuperview().inset(AppSpacing.sm)
        }
        refreshButton.snp.makeConstraints { make in
            make.top.equalTo(qrErrorLabel.snp.bottom).offset(AppSpacing.xs)
            make.centerX.equalToSuperview()
        }
        infoStack.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        voiceTitleLabel.snp.makeConstraints { make in
            make.leading.equalToSuperview().inset(AppSpacing.md)
            make.centerY.equalToSuperview()
        }
        voiceSwitch.snp.makeConstraints { make in
            make.trailing.equalToSuperview().inset(AppSpacing.md)
            make.centerY.equalToSuperview()
        }
        voiceCardView.snp.makeConstraints { make in
            make.height.equalTo(AppSpacing.formRowHeight)
        }
    }

    override func setupConstraints() {
        if viewModel.usesNalatiBranding {
            backgroundImageView.snp.makeConstraints { make in
                make.edges.equalToSuperview()
            }
        }
        scrollView.snp.makeConstraints { make in
            if viewModel.usesNalatiBranding {
                make.leading.trailing.equalToSuperview()
                make.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(-44)
                make.bottom.equalTo(view.safeAreaLayoutGuide)
            } else {
                make.edges.equalTo(view.safeAreaLayoutGuide)
            }
        }
        contentContainerView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
            make.width.equalTo(scrollView.snp.width)
            if viewModel.usesNalatiBranding {
                make.height.equalTo(scrollView.snp.height)
            }
        }
        contentStack.snp.makeConstraints { make in
            make.width.equalTo(scrollView.snp.width).offset(-AppSpacing.screenHorizontalInset * 2)
            if viewModel.usesNalatiBranding {
                make.centerX.centerY.equalToSuperview()
                make.top.greaterThanOrEqualToSuperview()
                make.bottom.lessThanOrEqualToSuperview()
            } else {
                make.edges.equalToSuperview().inset(AppSpacing.screenHorizontalInset)
            }
        }
    }

    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) }
        }

        setAmountButton.addTarget(self, action: #selector(setAmountTapped), for: .touchUpInside)
        saveQRButton.addTarget(self, action: #selector(saveQRTapped), for: .touchUpInside)
        refreshButton.addTarget(self, action: #selector(refreshTapped), for: .touchUpInside)
        recordRow.addTarget(self, action: #selector(recordTapped), for: .touchUpInside)
        voiceSwitch.addTarget(self, action: #selector(voiceSwitchChanged), for: .valueChanged)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        applyViewModel()
        Task { await loadData() }
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        applyBrandNavigationAppearanceIfNeeded()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        restoreNavigationAppearanceIfNeeded()
    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        viewModel.usesNalatiBranding ? .darkContent : .default
    }

    private func loadData() async {
        async let pageConfig: Void = viewModel.loadPayPageConfig(api: paymentAPI)
        showLoading()
        await viewModel.loadPayCode(api: paymentAPI)
        hideLoading()
        await pageConfig
    }

    @MainActor
    private func applyViewModel() {
        scenicNameLabel.text = viewModel.displayScenicName
        scenicRow.setValue(viewModel.displayScenicName)
        merchantRow.setValue(viewModel.merchantInfo.company)
        staffRow.setValue(viewModel.staffId.isEmpty ? "-" : viewModel.staffId)
        photographerRow.setValue(viewModel.displayPhotographerName)
        storeRow.setValue(viewModel.displayStoreNames)
        voiceSwitch.isOn = viewModel.isVoiceBroadcastOpen
        applyBrandConfigIfNeeded()

        if let image = viewModel.qrImage {
            qrImageView.image = image
            qrImageView.isHidden = false
            qrContainerView.isHidden = !viewModel.usesNalatiBranding
            qrPlaceholderView.isHidden = true
            actionRow.isHidden = false
        } else {
            qrImageView.isHidden = true
            qrContainerView.isHidden = true
            qrPlaceholderView.isHidden = false
            actionRow.isHidden = true
        }

        if viewModel.showAmountDialog {
            presentAmountDialogIfNeeded()
        } else {
            amountDialog?.dismiss()
            amountDialog = nil
        }
    }

    private func presentAmountDialogIfNeeded() {
        guard amountDialog == nil else {
            amountDialog?.apply(amount: viewModel.amount, remark: viewModel.remark)
            return
        }

        let dialog = PaymentSetAmountDialogView()
        dialog.onAmountChange = { [weak self] value in
            self?.viewModel.updateAmount(value)
        }
        dialog.onRemarkChange = { [weak self] value in
            self?.viewModel.updateRemark(value)
        }
        dialog.onConfirm = { [weak self] in
            self?.viewModel.confirmAmount()
        }
        dialog.onCancel = { [weak self] in
            self?.viewModel.hideAmountDialog()
        }
        dialog.apply(amount: viewModel.amount, remark: viewModel.remark)
        dialog.show(in: view)
        amountDialog = dialog
    }

    private func configureLinkButton(_ button: UIButton, title: String) {
        button.setTitle(title, for: .normal)
        button.setTitleColor(AppColor.primary, for: .normal)
        button.titleLabel?.font = .systemFont(ofSize: 14)
    }

    private func configureCard(_ view: UIView, branded: Bool) {
        view.backgroundColor = branded ? UIColor.white.withAlphaComponent(0.9) : .white
        view.layer.cornerRadius = branded ? 18 : AppRadius.lg
        view.clipsToBounds = true
    }

    private func configureBrandHeader() {
        brandHeaderStack.axis = .vertical
        brandHeaderStack.alignment = .center
        brandHeaderStack.spacing = brandScreenHeight <= 700 ? 6 : 8

        brandLogoImageView.image = UIImage(named: "payment_nalati_logo")
        brandLogoImageView.contentMode = .scaleAspectFit
        brandLogoImageView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)

        brandTitleLabel.font = .systemFont(
            ofSize: brandScreenHeight <= 700 ? 21 : 23,
            weight: .bold
        )
        brandTitleLabel.textColor = UIColor(hex: 0x102D54)
        brandTitleLabel.textAlignment = .center
        brandTitleLabel.numberOfLines = 1
        brandTitleLabel.adjustsFontSizeToFitWidth = true
        brandTitleLabel.minimumScaleFactor = 0.8

        brandSubtitleLabel.font = .systemFont(
            ofSize: brandScreenHeight <= 700 ? 15 : 16,
            weight: .medium
        )
        brandSubtitleLabel.textColor = UIColor(hex: 0x183A61)
        brandSubtitleLabel.textAlignment = .center

        let subtitleRow = UIStackView()
        subtitleRow.axis = .horizontal
        subtitleRow.alignment = .center
        subtitleRow.spacing = 9

        let leftLine = makeBrandLine()
        let leftDiamond = makeBrandDiamond()
        let rightDiamond = makeBrandDiamond()
        let rightLine = makeBrandLine()
        [leftLine, leftDiamond, brandSubtitleLabel, rightDiamond, rightLine].forEach(
            subtitleRow.addArrangedSubview
        )

        brandHeaderStack.addArrangedSubview(brandLogoImageView)
        brandHeaderStack.addArrangedSubview(brandTitleLabel)
        brandHeaderStack.addArrangedSubview(subtitleRow)
        brandHeaderStack.setCustomSpacing(
            brandScreenHeight <= 700 ? 8 : 10,
            after: brandLogoImageView
        )

        brandLogoImageView.snp.makeConstraints { make in
            make.width.equalToSuperview().inset(8)
            make.height.equalTo(brandLogoHeight)
        }
        brandTitleLabel.snp.makeConstraints { make in
            make.leading.trailing.equalToSuperview().inset(8)
        }
        [leftLine, rightLine].forEach { line in
            line.snp.makeConstraints { make in
                make.width.equalTo(42)
                make.height.equalTo(1)
            }
        }
        [leftDiamond, rightDiamond].forEach { diamond in
            diamond.snp.makeConstraints { make in
                make.width.height.equalTo(6)
            }
        }
    }

    private func makeBrandLine() -> UIView {
        let view = UIView()
        view.backgroundColor = UIColor(hex: 0x27496D).withAlphaComponent(0.75)
        return view
    }

    private func makeBrandDiamond() -> UIView {
        let view = UIView()
        view.backgroundColor = UIColor(hex: 0x27496D)
        view.transform = CGAffineTransform(rotationAngle: .pi / 4)
        return view
    }

    @MainActor
    private func applyBrandConfigIfNeeded() {
        guard viewModel.usesNalatiBranding else { return }
        let config = viewModel.payPageConfig
        brandTitleLabel.text = config.title
        brandSubtitleLabel.text = config.subtitle

        let versionChanged = appliedBrandingRefreshVersion != viewModel.brandingRefreshVersion
        guard appliedBrandConfig != config || versionChanged else { return }
        let forceRefresh = appliedBrandingRefreshVersion >= 0 && versionChanged
        setBrandImage(
            backgroundImageView,
            urlString: config.background,
            fallbackName: "payment_nalati_background",
            forceRefresh: forceRefresh
        )
        setBrandImage(
            brandLogoImageView,
            urlString: config.logo,
            fallbackName: "payment_nalati_logo",
            forceRefresh: forceRefresh
        )
        appliedBrandConfig = config
        appliedBrandingRefreshVersion = viewModel.brandingRefreshVersion
    }

    private func setBrandImage(
        _ imageView: UIImageView,
        urlString: String,
        fallbackName: String,
        forceRefresh: Bool
    ) {
        let fallback = UIImage(named: fallbackName)
        let trimmed = urlString.trimmingCharacters(in: .whitespacesAndNewlines)
        guard let url = URL(string: trimmed),
              url.scheme?.lowercased() == "https",
              url.host != nil else {
            imageView.image = fallback
            return
        }

        var options: KingfisherOptionsInfo = [
            .keepCurrentImageWhileLoading,
            .cacheOriginalImage,
            .transition(.fade(0.2)),
        ]
        if forceRefresh {
            options.append(.forceRefresh)
        }
        imageView.kf.setImage(with: url, placeholder: fallback, options: options)
    }

    private func applyBrandNavigationAppearanceIfNeeded() {
        guard viewModel.usesNalatiBranding, let navigationBar = navigationController?.navigationBar else { return }
        previousStandardAppearance = navigationBar.standardAppearance
        previousScrollEdgeAppearance = navigationBar.scrollEdgeAppearance
        previousCompactAppearance = navigationBar.compactAppearance
        previousNavigationTintColor = navigationBar.tintColor
        previousNavigationTranslucency = navigationBar.isTranslucent

        let appearance = UINavigationBarAppearance()
        appearance.configureWithTransparentBackground()
        appearance.shadowColor = .clear
        appearance.titleTextAttributes = [
            .foregroundColor: UIColor(hex: 0x111827),
            .font: UIFont.app(.title),
        ]
        navigationBar.standardAppearance = appearance
        navigationBar.scrollEdgeAppearance = appearance
        navigationBar.compactAppearance = appearance
        navigationBar.tintColor = UIColor(hex: 0x111827)
        navigationBar.isTranslucent = true
    }

    private func restoreNavigationAppearanceIfNeeded() {
        guard viewModel.usesNalatiBranding, let navigationBar = navigationController?.navigationBar else { return }
        if let previousStandardAppearance {
            navigationBar.standardAppearance = previousStandardAppearance
        }
        navigationBar.scrollEdgeAppearance = previousScrollEdgeAppearance
        navigationBar.compactAppearance = previousCompactAppearance
        navigationBar.tintColor = previousNavigationTintColor
        navigationBar.isTranslucent = previousNavigationTranslucency
        previousStandardAppearance = nil
        previousScrollEdgeAppearance = nil
        previousCompactAppearance = nil
        previousNavigationTintColor = nil
    }

    @objc private func setAmountTapped() {
        viewModel.showSetAmountDialog()
    }

    @objc private func saveQRTapped() {
        Task {
            await viewModel.saveQRCode()
        }
    }

    @objc private func refreshTapped() {
        Task {
            showLoading()
            await viewModel.refresh(api: paymentAPI)
            hideLoading()
        }
    }

    @objc private func recordTapped() {
        navigationController?.pushViewController(PaymentCollectionRecordViewController(), animated: true)
    }

    @objc private func voiceSwitchChanged() {
        viewModel.toggleReceiveVoice()
    }
}

/// 收款详情信息行。
private final class PaymentInfoRowView: UIView {

    private let titleLabel = UILabel()
    private let valueLabel = UILabel()
    private let divider = UIView()

    init(title: String) {
        super.init(frame: .zero)
        titleLabel.text = title
        setupUI()
    }

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

    func setValue(_ value: String) {
        valueLabel.text = value
    }

    private func setupUI() {
        titleLabel.font = .systemFont(ofSize: 14)
        titleLabel.textColor = UIColor(hex: 0x4B5563)

        valueLabel.font = .systemFont(ofSize: 14)
        valueLabel.textColor = AppColor.textPrimary
        valueLabel.textAlignment = .right
        valueLabel.numberOfLines = 0

        divider.backgroundColor = UIColor(hex: 0xE5E7EB)

        addSubview(titleLabel)
        addSubview(valueLabel)
        addSubview(divider)

        snp.makeConstraints { make in
            make.height.greaterThanOrEqualTo(AppSpacing.formRowHeight)
        }
        titleLabel.snp.makeConstraints { make in
            make.leading.equalToSuperview().inset(AppSpacing.md)
            make.centerY.equalToSuperview()
            make.width.equalTo(102)
        }
        valueLabel.snp.makeConstraints { make in
            make.leading.equalTo(titleLabel.snp.trailing).offset(AppSpacing.xs)
            make.trailing.equalToSuperview().inset(AppSpacing.md)
            make.top.bottom.equalToSuperview().inset(AppSpacing.sm)
        }
        divider.snp.makeConstraints { make in
            make.leading.trailing.bottom.equalToSuperview()
            make.height.equalTo(0.5)
        }
    }
}

/// 可点击导航行。
private final class PaymentNavigationRowView: UIControl {

    private let titleLabel = UILabel()
    private let chevronView = UIImageView()

    init(title: String) {
        super.init(frame: .zero)
        titleLabel.text = title
        setupUI()
    }

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

    private func setupUI() {
        titleLabel.font = .systemFont(ofSize: 14)
        titleLabel.textColor = UIColor(hex: 0x4B5563)

        chevronView.image = UIImage(systemName: "chevron.right")
        chevronView.tintColor = AppColor.textSecondary
        chevronView.contentMode = .scaleAspectFit

        addSubview(titleLabel)
        addSubview(chevronView)

        snp.makeConstraints { make in
            make.height.equalTo(AppSpacing.formRowHeight)
        }
        titleLabel.snp.makeConstraints { make in
            make.leading.equalToSuperview().inset(AppSpacing.md)
            make.centerY.equalToSuperview()
        }
        chevronView.snp.makeConstraints { make in
            make.trailing.equalToSuperview().inset(AppSpacing.md)
            make.centerY.equalToSuperview()
            make.width.height.equalTo(16)
        }
    }
}
