//
//  ScenicQueueOverlayViews.swift
//  suixinkan
//

import SnapKit
import UIKit

/// Android 排队模块样式的等宽标签栏。
final class ScenicQueueTabStripView: UIView {
    private let stackView = UIStackView()
    private let indicator = UIView()
    private let divider = UIView()
    private var buttons: [UIButton] = []

    /// 用户选择标签时回传索引。
    var onSelect: ((Int) -> Void)?

    /// 当前选中索引。
    private(set) var selectedIndex = 0

    init(titles: [String]) {
        super.init(frame: .zero)
        backgroundColor = .white
        stackView.axis = .horizontal
        stackView.distribution = .fillEqually
        titles.enumerated().forEach { index, title in
            let button = UIButton(type: .system)
            button.tag = index
            button.setTitle(title, for: .normal)
            button.titleLabel?.font = ScenicQueueTokens.tabFont
            button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
            buttons.append(button)
            stackView.addArrangedSubview(button)
        }
        indicator.backgroundColor = ScenicQueueTokens.bannerBlue
        divider.backgroundColor = ScenicQueueTokens.cardOutline
        addSubview(stackView)
        addSubview(divider)
        addSubview(indicator)
        stackView.snp.makeConstraints { $0.edges.equalToSuperview() }
        divider.snp.makeConstraints { make in
            make.leading.trailing.bottom.equalToSuperview()
            make.height.equalTo(1 / UIScreen.main.scale)
        }
        setSelectedIndex(0, animated: false)
    }

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

    override func layoutSubviews() {
        super.layoutSubviews()
        updateIndicatorFrame()
    }

    /// 更新选中标签并移动 3pt 蓝色指示条。
    func setSelectedIndex(_ index: Int, animated: Bool) {
        guard buttons.indices.contains(index) else { return }
        selectedIndex = index
        buttons.enumerated().forEach { item in
            item.element.setTitleColor(item.offset == index ? ScenicQueueTokens.bannerBlue : AppColor.textSecondary, for: .normal)
            item.element.titleLabel?.font = item.offset == index ? ScenicQueueTokens.tabSelectedFont : ScenicQueueTokens.tabFont
        }
        let changes = { self.updateIndicatorFrame() }
        animated ? UIView.animate(withDuration: 0.22, animations: changes) : changes()
    }

    private func updateIndicatorFrame() {
        guard !buttons.isEmpty, bounds.width > 0 else { return }
        let width = bounds.width / CGFloat(buttons.count)
        indicator.frame = CGRect(x: width * CGFloat(selectedIndex), y: bounds.height - 3, width: width, height: 3)
    }

    @objc private func buttonTapped(_ sender: UIButton) {
        setSelectedIndex(sender.tag, animated: true)
        onSelect?(sender.tag)
    }
}

/// 排队模块确认弹层的固定展示配置。
struct ScenicQueueDialogConfiguration {
    let title: String
    let message: String?
    let emphasizedText: String?
    let dangerText: String?
    let cancelTitle: String
    let confirmTitle: String
    let buttonRadius: CGFloat
    let dismissOnBackdrop: Bool
}

/// Android 排队模块样式的居中确认弹层。
final class ScenicQueueConfirmationDialogViewController: UIViewController, UIGestureRecognizerDelegate {
    private let configuration: ScenicQueueDialogConfiguration
    private let onCancel: () -> Void
    private let onConfirm: () -> Void

    init(configuration: ScenicQueueDialogConfiguration, onCancel: @escaping () -> Void, onConfirm: @escaping () -> Void) {
        self.configuration = configuration
        self.onCancel = onCancel
        self.onConfirm = onConfirm
        super.init(nibName: nil, bundle: nil)
        modalPresentationStyle = .overFullScreen
        modalTransitionStyle = .crossDissolve
    }

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

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.black.withAlphaComponent(0.42)
        if configuration.dismissOnBackdrop {
            let backdropTap = UITapGestureRecognizer(target: self, action: #selector(cancelTapped))
            backdropTap.delegate = self
            view.addGestureRecognizer(backdropTap)
        }

        let card = UIView()
        card.backgroundColor = .white
        card.layer.cornerRadius = ScenicQueueTokens.radiusDialog
        card.layer.shadowColor = UIColor.black.cgColor
        card.layer.shadowOpacity = 0.18
        card.layer.shadowRadius = 8

        let titleLabel = UILabel()
        titleLabel.text = configuration.title
        titleLabel.font = ScenicQueueTokens.dialogTitleFont
        titleLabel.textColor = AppColor.textPrimary
        titleLabel.textAlignment = .center

        let contentStack = UIStackView(arrangedSubviews: [titleLabel])
        contentStack.axis = .vertical
        contentStack.spacing = 10
        if let message = configuration.message {
            let label = makeLabel(message, font: .systemFont(ofSize: 15), color: AppColor.textSecondary)
            contentStack.addArrangedSubview(label)
        }
        if let danger = configuration.dangerText {
            let label = makeLabel(danger, font: .systemFont(ofSize: 13), color: ScenicQueueTokens.dialogDangerLine)
            contentStack.addArrangedSubview(label)
        }
        if let emphasized = configuration.emphasizedText {
            let label = makeLabel(emphasized, font: ScenicQueueTokens.dialogTicketFont, color: AppColor.textPrimary)
            contentStack.addArrangedSubview(label)
            contentStack.setCustomSpacing(20, after: label)
        }

        let cancel = makeButton(configuration.cancelTitle, background: ScenicQueueTokens.dialogCancelBackground, foreground: ScenicQueueTokens.bannerBlue)
        cancel.addTarget(self, action: #selector(cancelTapped), for: .touchUpInside)
        let confirm = makeButton(configuration.confirmTitle, background: ScenicQueueTokens.bannerBlue, foreground: .white)
        confirm.addTarget(self, action: #selector(confirmTapped), for: .touchUpInside)
        cancel.layer.cornerRadius = configuration.buttonRadius
        confirm.layer.cornerRadius = configuration.buttonRadius
        let buttons = UIStackView(arrangedSubviews: [cancel, confirm])
        buttons.axis = .horizontal
        buttons.distribution = .fillEqually
        buttons.spacing = 12
        contentStack.addArrangedSubview(buttons)

        view.addSubview(card)
        card.addSubview(contentStack)
        card.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.leading.trailing.equalToSuperview().inset(32)
        }
        contentStack.snp.makeConstraints { $0.edges.equalToSuperview().inset(22) }
        buttons.snp.makeConstraints { $0.height.equalTo(44) }
    }

    private func makeLabel(_ text: String, font: UIFont, color: UIColor) -> UILabel {
        let label = UILabel()
        label.text = text
        label.font = font
        label.textColor = color
        label.textAlignment = .center
        label.numberOfLines = 0
        return label
    }

    private func makeButton(_ title: String, background: UIColor, foreground: UIColor) -> UIButton {
        let button = UIButton(type: .system)
        button.setTitle(title, for: .normal)
        button.setTitleColor(foreground, for: .normal)
        button.titleLabel?.font = ScenicQueueTokens.dialogButtonFont
        button.backgroundColor = background
        button.clipsToBounds = true
        return button
    }

    @objc private func cancelTapped() {
        dismiss(animated: true, completion: onCancel)
    }

    @objc private func confirmTapped() {
        dismiss(animated: true, completion: onConfirm)
    }

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        touch.view === view
    }
}

/// Android 排队模块样式的拨号底部弹层。
final class ScenicQueueDialSheetViewController: UIViewController, UIGestureRecognizerDelegate {
    private let digits: String

    init(digits: String) {
        self.digits = digits
        super.init(nibName: nil, bundle: nil)
        modalPresentationStyle = .overFullScreen
        modalTransitionStyle = .crossDissolve
    }

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

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.black.withAlphaComponent(0.36)
        let backdropTap = UITapGestureRecognizer(target: self, action: #selector(cancelTapped))
        backdropTap.delegate = self
        view.addGestureRecognizer(backdropTap)
        let panel = UIView()
        panel.backgroundColor = .white
        panel.layer.cornerRadius = 18
        panel.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
        let title = UILabel()
        title.text = "拨打电话"
        title.font = ScenicQueueTokens.dialogTitleFont
        title.textAlignment = .center
        let number = UILabel()
        number.text = digits
        number.font = .systemFont(ofSize: 18, weight: .medium)
        number.textColor = AppColor.textPrimary
        number.textAlignment = .center
        let cancel = pillButton("取消", background: ScenicQueueTokens.dialogCancelBackground, foreground: ScenicQueueTokens.bannerBlue)
        cancel.addTarget(self, action: #selector(cancelTapped), for: .touchUpInside)
        let dial = pillButton("拨打", background: ScenicQueueTokens.bannerBlue, foreground: .white)
        dial.addTarget(self, action: #selector(dialTapped), for: .touchUpInside)
        let buttons = UIStackView(arrangedSubviews: [cancel, dial])
        buttons.axis = .horizontal
        buttons.distribution = .fillEqually
        buttons.spacing = 12
        view.addSubview(panel)
        [title, number, buttons].forEach(panel.addSubview)
        panel.snp.makeConstraints { make in make.leading.trailing.bottom.equalToSuperview() }
        title.snp.makeConstraints { make in make.top.equalToSuperview().offset(18); make.centerX.equalToSuperview() }
        number.snp.makeConstraints { make in make.top.equalTo(title.snp.bottom).offset(18); make.leading.trailing.equalToSuperview().inset(16) }
        buttons.snp.makeConstraints { make in
            make.top.equalTo(number.snp.bottom).offset(18)
            make.leading.trailing.equalToSuperview().inset(16)
            make.height.equalTo(44)
            make.bottom.equalTo(view.safeAreaLayoutGuide).offset(-12)
        }
    }

    private func pillButton(_ title: String, background: UIColor, foreground: UIColor) -> UIButton {
        let button = UIButton(type: .system)
        button.setTitle(title, for: .normal)
        button.setTitleColor(foreground, for: .normal)
        button.titleLabel?.font = ScenicQueueTokens.dialogButtonFont
        button.backgroundColor = background
        button.layer.cornerRadius = 22
        return button
    }

    @objc private func cancelTapped() { dismiss(animated: true) }

    @objc private func dialTapped() {
        dismiss(animated: true) {
            guard let url = URL(string: "tel:\(self.digits)") else { return }
            UIApplication.shared.open(url)
        }
    }

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        touch.view === view
    }
}

/// Android 用户标记弹层，支持打野标记和限制排队天数步进。
final class ScenicQueueMarkDialogViewController: UIViewController {
    private let pending: ScenicQueuePendingMark
    private let onCancel: () -> Void
    private let onConfirm: (Bool, Int) -> Void
    private let markSwitch = UISwitch()
    private let daysLabel = UILabel()
    private var days = 0 { didSet { daysLabel.text = "\(days)" } }

    init(pending: ScenicQueuePendingMark, onCancel: @escaping () -> Void, onConfirm: @escaping (Bool, Int) -> Void) {
        self.pending = pending
        self.onCancel = onCancel
        self.onConfirm = onConfirm
        super.init(nibName: nil, bundle: nil)
        modalPresentationStyle = .overFullScreen
        modalTransitionStyle = .crossDissolve
    }

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

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.black.withAlphaComponent(0.42)
        let card = UIView()
        card.backgroundColor = .white
        card.layer.cornerRadius = ScenicQueueTokens.markDialogRadius
        let title = UILabel()
        title.text = "标记用户"
        title.font = ScenicQueueTokens.dialogTitleFont
        title.textAlignment = .center
        let queue = UILabel()
        queue.text = pending.queueNo
        queue.font = .systemFont(ofSize: 24, weight: .bold)
        queue.textColor = ScenicQueueTokens.bannerBlue
        let phone = UILabel()
        phone.text = pending.phoneMasked
        phone.font = ScenicQueueTokens.phoneMaskedFont
        phone.textColor = AppColor.textSecondary
        let identityTitle = UILabel()
        identityTitle.text = "标记为打野摄影师"
        identityTitle.font = ScenicQueueTokens.settingsRowTitleFont
        markSwitch.isOn = pending.markAsFreelancePhotog == 1
        markSwitch.onTintColor = ScenicQueueTokens.bannerBlue
        let identityRow = UIStackView(arrangedSubviews: [identityTitle, UIView(), markSwitch])
        identityRow.axis = .horizontal
        identityRow.alignment = .center
        let hint = UILabel()
        hint.text = "标记后，该用户扫码时将受排队限制。"
        hint.font = ScenicQueueTokens.settingsHintFont
        hint.textColor = AppColor.textTertiary
        hint.numberOfLines = 0
        let daysTitle = UILabel()
        daysTitle.text = "限制排队天数"
        daysTitle.font = ScenicQueueTokens.settingsRowTitleFont
        let minus = stepButton("−", action: #selector(minusTapped))
        let plus = stepButton("+", action: #selector(plusTapped))
        daysLabel.text = "0"
        daysLabel.font = .systemFont(ofSize: 16, weight: .medium)
        daysLabel.textAlignment = .center
        let stepper = UIStackView(arrangedSubviews: [minus, daysLabel, plus])
        stepper.axis = .horizontal
        stepper.alignment = .center
        stepper.distribution = .fillEqually
        stepper.backgroundColor = ScenicQueueTokens.markDialogStepperBackground
        stepper.layer.cornerRadius = 10
        let cancel = actionButton("取消", background: ScenicQueueTokens.markDialogCancelBackground, foreground: ScenicQueueTokens.bannerBlue)
        cancel.addTarget(self, action: #selector(cancelTapped), for: .touchUpInside)
        let confirm = actionButton("完成", background: ScenicQueueTokens.bannerBlue, foreground: .white)
        confirm.addTarget(self, action: #selector(confirmTapped), for: .touchUpInside)
        let buttons = UIStackView(arrangedSubviews: [cancel, confirm])
        buttons.axis = .horizontal
        buttons.distribution = .fillEqually
        buttons.spacing = 12
        let stack = UIStackView(arrangedSubviews: [title, queue, phone, identityRow, hint, daysTitle, stepper, buttons])
        stack.axis = .vertical
        stack.spacing = 12
        view.addSubview(card)
        card.addSubview(stack)
        card.snp.makeConstraints { make in make.center.equalToSuperview(); make.width.equalToSuperview().multipliedBy(0.88) }
        stack.snp.makeConstraints { $0.edges.equalToSuperview().inset(22) }
        stepper.snp.makeConstraints { $0.height.equalTo(44) }
        buttons.snp.makeConstraints { $0.height.equalTo(44) }
    }

    private func stepButton(_ title: String, action: Selector) -> UIButton {
        let button = UIButton(type: .system)
        button.setTitle(title, for: .normal)
        button.setTitleColor(ScenicQueueTokens.bannerBlue, for: .normal)
        button.titleLabel?.font = .systemFont(ofSize: 22, weight: .medium)
        button.addTarget(self, action: action, for: .touchUpInside)
        return button
    }

    private func actionButton(_ title: String, background: UIColor, foreground: UIColor) -> UIButton {
        let button = UIButton(type: .system)
        button.setTitle(title, for: .normal)
        button.setTitleColor(foreground, for: .normal)
        button.titleLabel?.font = ScenicQueueTokens.dialogButtonFont
        button.backgroundColor = background
        button.layer.cornerRadius = ScenicQueueTokens.markDialogButtonRadius
        return button
    }

    @objc private func minusTapped() { days = max(0, days - 1) }
    @objc private func plusTapped() { days = min(999, days + 1) }
    @objc private func cancelTapped() { dismiss(animated: true, completion: onCancel) }
    @objc private func confirmTapped() {
        let marked = markSwitch.isOn
        dismiss(animated: true) { self.onConfirm(marked, marked ? self.days : 0) }
    }
}
