//
//  ScenicQueueSettingsViewController.swift
//  suixinkan
//

import SnapKit
import UIKit

/// 排队设置页，对齐 Android `ScenicQueueSettingsScreen` 的三 Tab 表单。
final class ScenicQueueSettingsViewController: BaseViewController {
    private let viewModel = ScenicQueueSettingsViewModel()
    private let api: ScenicQueueAPIProtocol

    private let segmentedControl = UISegmentedControl(items: ScenicQueueSettingsTab.allCases.map(\.title))
    private let scrollView = UIScrollView()
    private let stackView = UIStackView()
    private let saveBar = UIView()
    private let saveButton = UIButton(type: .system)

    private var fieldRows: [String: ScenicQueueSettingFieldRow] = [:]
    private var switchRows: [String: ScenicQueueSwitchRow] = [:]

    @MainActor
    init(api: ScenicQueueAPIProtocol? = nil) {
        self.api = api ?? NetworkServices.shared.scenicQueueAPI
        super.init(nibName: nil, bundle: nil)
    }

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

    override func setupNavigationBar() {
        title = "设置"
        navigationItem.rightBarButtonItem = UIBarButtonItem(
            title: "配置日志",
            style: .plain,
            target: self,
            action: #selector(logTapped)
        )
    }

    override func setupUI() {
        view.backgroundColor = ScenicQueueTokens.pageBackground
        segmentedControl.selectedSegmentIndex = viewModel.settingsTab.rawValue
        segmentedControl.selectedSegmentTintColor = .white
        segmentedControl.setTitleTextAttributes([
            .font: ScenicQueueTokens.settingsRowTitleFont,
            .foregroundColor: AppColor.textSecondary,
        ], for: .normal)
        segmentedControl.setTitleTextAttributes([
            .font: UIFont.systemFont(ofSize: 14, weight: .semibold),
            .foregroundColor: ScenicQueueTokens.bannerBlue,
        ], for: .selected)

        stackView.axis = .vertical
        stackView.spacing = 14
        scrollView.keyboardDismissMode = .onDrag
        scrollView.alwaysBounceVertical = true

        saveBar.backgroundColor = .white
        saveButton.setTitle("保存", for: .normal)
        saveButton.setTitleColor(.white, for: .normal)
        saveButton.titleLabel?.font = ScenicQueueTokens.settingsSaveButtonFont
        saveButton.backgroundColor = ScenicQueueTokens.bannerBlue
        saveButton.layer.cornerRadius = ScenicQueueTokens.bottomSaveButtonRadius
        saveButton.clipsToBounds = true

        view.addSubview(segmentedControl)
        view.addSubview(scrollView)
        scrollView.addSubview(stackView)
        view.addSubview(saveBar)
        saveBar.addSubview(saveButton)
        rebuildForm()
    }

    override func setupConstraints() {
        segmentedControl.snp.makeConstraints { make in
            make.top.equalTo(view.safeAreaLayoutGuide).offset(8)
            make.leading.trailing.equalToSuperview().inset(16)
            make.height.equalTo(40)
        }
        saveBar.snp.makeConstraints { make in
            make.leading.trailing.bottom.equalToSuperview()
        }
        saveButton.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(16)
            make.leading.trailing.equalToSuperview().inset(31)
            make.bottom.equalTo(view.safeAreaLayoutGuide).offset(-16)
            make.height.equalTo(48)
        }
        scrollView.snp.makeConstraints { make in
            make.top.equalTo(segmentedControl.snp.bottom).offset(10)
            make.leading.trailing.equalToSuperview()
            make.bottom.equalTo(saveBar.snp.top)
        }
        stackView.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(UIEdgeInsets(top: 12, left: 16, bottom: 16, right: 16))
            make.width.equalToSuperview().offset(-32)
        }
    }

    override func bindActions() {
        segmentedControl.addTarget(self, action: #selector(tabChanged), for: .valueChanged)
        saveButton.addTarget(self, action: #selector(saveTapped), for: .touchUpInside)
        viewModel.onStateChange = { [weak self] in
            Task { @MainActor in self?.applyState() }
        }
        viewModel.onShowMessage = { [weak self] message in
            Task { @MainActor in self?.showToast(message) }
        }
        viewModel.onNavigateBack = { [weak self] in
            Task { @MainActor in self?.navigationController?.popViewController(animated: true) }
        }
        viewModel.onNavigateLog = { [weak self] in
            Task { @MainActor in self?.navigationController?.pushViewController(ScenicQueueSettingChangeLogViewController(), animated: true) }
        }
    }

    private func applyState() {
        segmentedControl.selectedSegmentIndex = viewModel.settingsTab.rawValue
        rebuildForm()
    }

    private func rebuildForm() {
        stackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
        fieldRows.removeAll()
        switchRows.removeAll()
        switch viewModel.settingsTab {
        case .basic:
            buildBasicForm()
        case .notify:
            buildNotifyForm()
        case .voice:
            buildVoiceForm()
        }
    }

    private func buildBasicForm() {
        stackView.addArrangedSubview(tipCard())
        stackView.addArrangedSubview(actionCard(title: "打卡点", value: viewModel.selectedPunchSpotDisplayText, primary: "选择打卡点", secondary: "保存小程序码", primaryAction: #selector(punchSpotTapped), secondaryAction: #selector(saveQRTapped), invalid: viewModel.highlightedInvalidFieldKeys.contains("punchSpot")))
        addSwitchRow(key: "businessOpen", title: "营业状态", isOn: viewModel.businessOpen, action: #selector(businessOpenChanged(_:)))
        addTextRow(key: "businessStart", title: "营业开始时间", value: viewModel.businessStartTime, suffix: "HH:mm", keyboard: .numbersAndPunctuation, action: #selector(businessStartChanged(_:)))
        addTextRow(key: "businessEnd", title: "营业结束时间", value: viewModel.businessEndTime, suffix: "HH:mm", keyboard: .numbersAndPunctuation, action: #selector(businessEndChanged(_:)))
        addTextRow(key: "queueDistance", title: "允许排队距离", value: "\(viewModel.queueDistanceMeter)", suffix: "米", keyboard: .numberPad, action: #selector(queueDistanceChanged(_:)))
        addTextRow(key: "shootMinute", title: "拍摄时长（分钟）", value: "\(viewModel.shootMinute)", suffix: "分", keyboard: .numberPad, action: #selector(shootMinuteChanged(_:)))
        addTextRow(key: "shootSecond", title: "拍摄时长（秒）", value: "\(viewModel.shootSecond)", suffix: "秒", keyboard: .numberPad, action: #selector(shootSecondChanged(_:)))
        addTextRow(key: "queueTakeLimit", title: "单人取号次数", value: "\(viewModel.queueTakeLimit)", suffix: "次", keyboard: .numberPad, action: #selector(queueTakeLimitChanged(_:)))
        addTextRow(key: "missOffset", title: "过号重排顺延位数", value: "\(viewModel.missCallRequeueOffset)", suffix: "位", keyboard: .numberPad, action: #selector(missOffsetChanged(_:)))
        addSwitchRow(key: "showShoot", title: "展示开始拍摄按钮", isOn: viewModel.showStartShootingButton, action: #selector(showShootChanged(_:)))
        addTextRow(key: "autoCall", title: "自动提前叫号数量", value: "\(viewModel.autoCallAheadCount)", suffix: "人", keyboard: .numberPad, action: #selector(autoCallChanged(_:)))
        addSwitchRow(key: "quickCall", title: "底部快速叫号", isOn: viewModel.quickCallButtonEnabled, action: #selector(quickCallChanged(_:)))
        addSwitchRow(key: "prepareCall", title: "底部准备叫号", isOn: viewModel.prepareCallButtonEnabled, action: #selector(prepareCallChanged(_:)))
    }

    private func buildNotifyForm() {
        addTextRow(key: "firstAhead", title: "第一次提前通知阈值", value: "\(viewModel.firstAheadCount)", suffix: "位", keyboard: .numberPad, action: #selector(firstAheadChanged(_:)))
        addSwitchRow(key: "firstSms", title: "第一次短信通知", isOn: viewModel.firstSms, action: #selector(firstSmsChanged(_:)))
        addSwitchRow(key: "firstPhone", title: "第一次电话通知", isOn: viewModel.firstPhone, action: #selector(firstPhoneChanged(_:)))
        addTextRow(key: "secondAhead", title: "第二次提前通知阈值", value: "\(viewModel.secondAheadCount)", suffix: "位", keyboard: .numberPad, action: #selector(secondAheadChanged(_:)))
        addSwitchRow(key: "secondSms", title: "第二次短信通知", isOn: viewModel.secondSms, action: #selector(secondSmsChanged(_:)))
        addSwitchRow(key: "secondPhone", title: "第二次电话通知", isOn: viewModel.secondPhone, action: #selector(secondPhoneChanged(_:)))
    }

    private func buildVoiceForm() {
        addTextRow(key: "broadcastInterval", title: "播报间隔时间", value: "\(viewModel.broadcastIntervalSec)", suffix: "秒", keyboard: .numberPad, action: #selector(broadcastChanged(_:)))
        addTextRow(key: "countdown", title: "进入读秒倒计时阈值", value: "\(viewModel.countdownThresholdSec)", suffix: "秒", keyboard: .numberPad, action: #selector(countdownChanged(_:)))
        addSwitchRow(key: "offlineTTS", title: "离线语音合成", isOn: viewModel.useOfflineTTS, action: #selector(offlineTTSChanged(_:)))
        stackView.addArrangedSubview(actionCard(title: "蓝牙音响测试", value: "请确认外放音量是否合适", primary: "播放测试音", secondary: nil, primaryAction: #selector(testSoundTapped), secondaryAction: nil))
        addTextRow(key: "customTTS", title: "自定义播报文案", value: viewModel.customTTSText, suffix: "", keyboard: .default, action: #selector(customTTSChanged(_:)))
        stackView.addArrangedSubview(actionCard(title: "播报文案", value: "最多保存5个语音", primary: "播放文本", secondary: "保存到预设", primaryAction: #selector(playCustomTapped), secondaryAction: #selector(savePresetTapped)))
        for (index, phrase) in viewModel.presetVoices.enumerated() {
            stackView.addArrangedSubview(presetVoiceCard(index: index, phrase: phrase))
        }
    }

    private func addTextRow(key: String, title: String, value: String, suffix: String, keyboard: UIKeyboardType, action: Selector) {
        let row = ScenicQueueSettingFieldRow(title: title, value: value, suffix: suffix, keyboard: keyboard)
        row.textField.addTarget(self, action: action, for: .editingChanged)
        fieldRows[key] = row
        stackView.addArrangedSubview(row)
    }

    private func addSwitchRow(key: String, title: String, isOn: Bool, action: Selector) {
        let row = ScenicQueueSwitchRow(title: title, isOn: isOn)
        row.toggle.addTarget(self, action: action, for: .valueChanged)
        switchRows[key] = row
        stackView.addArrangedSubview(row)
    }

    private func tipCard() -> UIView {
        let card = ScenicQueueSettingCard()
        card.backgroundColor = ScenicQueueTokens.bannerBlue
        let title = UILabel()
        title.text = "排队基础参数"
        title.textColor = .white
        title.font = ScenicQueueTokens.settingsSectionTitleFont
        let body = UILabel()
        body.text = "选择打卡点后保存配置，顾客即可扫码取号排队。"
        body.textColor = UIColor.white.withAlphaComponent(0.86)
        body.font = ScenicQueueTokens.settingsHintFont
        body.numberOfLines = 0
        let stack = UIStackView(arrangedSubviews: [title, body])
        stack.axis = .vertical
        stack.spacing = 6
        card.addSubview(stack)
        stack.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(14)
        }
        return card
    }

    private func actionCard(title: String, value: String, primary: String, secondary: String?, primaryAction: Selector, secondaryAction: Selector?, invalid: Bool = false) -> UIView {
        let card = ScenicQueueSettingCard()
        card.layer.borderColor = invalid ? AppColor.danger.cgColor : ScenicQueueTokens.cardOutline.cgColor
        let titleLabel = UILabel()
        titleLabel.text = title
        titleLabel.font = ScenicQueueTokens.settingsFieldLabelFont
        titleLabel.textColor = AppColor.textPrimary
        let valueLabel = UILabel()
        valueLabel.text = value
        valueLabel.font = ScenicQueueTokens.settingsHintFont
        valueLabel.textColor = AppColor.textSecondary
        valueLabel.numberOfLines = 0
        let primaryButton = UIButton(type: .system)
        primaryButton.setTitle(primary, for: .normal)
        primaryButton.titleLabel?.font = ScenicQueueTokens.buttonSecondaryFont
        primaryButton.addTarget(self, action: primaryAction, for: .touchUpInside)
        let buttons = UIStackView(arrangedSubviews: [primaryButton])
        buttons.axis = .horizontal
        buttons.spacing = 12
        if let secondary, let secondaryAction {
            let secondaryButton = UIButton(type: .system)
            secondaryButton.setTitle(secondary, for: .normal)
            secondaryButton.titleLabel?.font = ScenicQueueTokens.buttonSecondaryFont
            secondaryButton.addTarget(self, action: secondaryAction, for: .touchUpInside)
            buttons.addArrangedSubview(secondaryButton)
        }
        let stack = UIStackView(arrangedSubviews: [titleLabel, valueLabel, buttons])
        stack.axis = .vertical
        stack.spacing = 8
        card.addSubview(stack)
        stack.snp.makeConstraints { make in
            make.edges.equalToSuperview().inset(14)
        }
        return card
    }

    private func presetVoiceCard(index: Int, phrase: String) -> UIView {
        let card = ScenicQueueSettingCard()
        let label = UILabel()
        label.text = phrase
        label.font = ScenicQueueTokens.settingsRowTitleFont
        label.textColor = AppColor.textPrimary
        label.numberOfLines = 0
        let delete = UIButton(type: .system)
        delete.setImage(UIImage(systemName: "trash"), for: .normal)
        delete.tintColor = AppColor.danger
        delete.tag = index
        delete.addTarget(self, action: #selector(deletePresetTapped(_:)), for: .touchUpInside)
        card.addSubview(label)
        card.addSubview(delete)
        label.snp.makeConstraints { make in
            make.leading.top.bottom.equalToSuperview().inset(14)
            make.trailing.equalTo(delete.snp.leading).offset(-12)
        }
        delete.snp.makeConstraints { make in
            make.trailing.equalToSuperview().offset(-14)
            make.centerY.equalToSuperview()
            make.size.equalTo(44)
        }
        return card
    }

    @objc private func tabChanged() {
        viewModel.setSettingsTab(ScenicQueueSettingsTab(rawValue: segmentedControl.selectedSegmentIndex) ?? .basic)
    }

    @objc private func logTapped() { viewModel.openSettingChangeLog() }

    @objc private func saveTapped() {
        view.endEditing(true)
        Task { await viewModel.save(api: api) }
    }

    @objc private func punchSpotTapped() {
        Task {
            await viewModel.loadPunchSpotOptions(api: api)
            await MainActor.run { presentPunchSpotPicker() }
        }
    }

    private func presentPunchSpotPicker() {
        let alert = UIAlertController(title: "选择打卡点", message: nil, preferredStyle: .actionSheet)
        viewModel.punchSpotOptions.forEach { option in
            alert.addAction(UIAlertAction(title: option.label, style: .default) { [weak self] _ in
                guard let self else { return }
                Task { await self.viewModel.setPunchSpot(option, api: self.api) }
            })
        }
        alert.addAction(UIAlertAction(title: "取消", style: .cancel))
        present(alert, animated: true)
    }

    @objc private func saveQRTapped() { Task { await viewModel.saveShootQueueQRCode(api: api) } }
    @objc private func testSoundTapped() { viewModel.playBluetoothTestSound() }
    @objc private func playCustomTapped() { viewModel.toggleCustomTTSPlayback() }
    @objc private func savePresetTapped() { viewModel.saveCurrentTextAsPresetVoiceLocal() }
    @objc private func deletePresetTapped(_ sender: UIButton) { viewModel.deletePresetVoice(at: sender.tag) }

    @objc private func businessOpenChanged(_ sender: UISwitch) { viewModel.toggleBusinessOpen() }
    @objc private func showShootChanged(_ sender: UISwitch) { viewModel.toggleShowStartShootingButton() }
    @objc private func quickCallChanged(_ sender: UISwitch) { viewModel.toggleQuickCallButtonEnabled() }
    @objc private func prepareCallChanged(_ sender: UISwitch) { viewModel.togglePrepareCallButtonEnabled() }
    @objc private func firstSmsChanged(_ sender: UISwitch) { viewModel.toggleFirstSms() }
    @objc private func firstPhoneChanged(_ sender: UISwitch) { viewModel.toggleFirstPhone() }
    @objc private func secondSmsChanged(_ sender: UISwitch) { viewModel.toggleSecondSms() }
    @objc private func secondPhoneChanged(_ sender: UISwitch) { viewModel.toggleSecondPhone() }

    @objc private func businessStartChanged(_ sender: UITextField) { viewModel.setBusinessStartTime(sender.text ?? "") }
    @objc private func businessEndChanged(_ sender: UITextField) { viewModel.setBusinessEndTime(sender.text ?? "") }
    @objc private func queueDistanceChanged(_ sender: UITextField) { viewModel.setQueueDistanceMeter(Int(sender.text ?? "") ?? 0) }
    @objc private func shootMinuteChanged(_ sender: UITextField) { viewModel.setShootMinute(Int(sender.text ?? "") ?? 0) }
    @objc private func shootSecondChanged(_ sender: UITextField) { viewModel.setShootSecond(Int(sender.text ?? "") ?? 0) }
    @objc private func queueTakeLimitChanged(_ sender: UITextField) { viewModel.setQueueTakeLimit(Int(sender.text ?? "") ?? 0) }
    @objc private func missOffsetChanged(_ sender: UITextField) { viewModel.setMissCallRequeueOffset(Int(sender.text ?? "") ?? 1) }
    @objc private func autoCallChanged(_ sender: UITextField) { viewModel.setAutoCallAheadCount(Int(sender.text ?? "") ?? 0) }
    @objc private func firstAheadChanged(_ sender: UITextField) { viewModel.setFirstAheadCount(Int(sender.text ?? "") ?? 0) }
    @objc private func secondAheadChanged(_ sender: UITextField) { viewModel.setSecondAheadCount(Int(sender.text ?? "") ?? 0) }
    @objc private func broadcastChanged(_ sender: UITextField) { viewModel.setBroadcastIntervalSec(Int(sender.text ?? "") ?? 50) }
    @objc private func countdownChanged(_ sender: UITextField) { viewModel.setCountdownThresholdSec(Int(sender.text ?? "") ?? 15) }
    @objc private func offlineTTSChanged(_ sender: UISwitch) { viewModel.setUseOfflineTTS(sender.isOn) }
    @objc private func customTTSChanged(_ sender: UITextField) { viewModel.setCustomTTSText(sender.text ?? "") }
}

/// 设置页卡片容器。
class ScenicQueueSettingCard: UIView {
    init() {
        super.init(frame: .zero)
        backgroundColor = .white
        layer.cornerRadius = ScenicQueueTokens.radiusCard
        layer.borderWidth = 1
        layer.borderColor = ScenicQueueTokens.cardOutline.cgColor
        clipsToBounds = true
    }

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

/// 设置页文本字段行。
final class ScenicQueueSettingFieldRow: ScenicQueueSettingCard {
    let textField = UITextField()

    init(title: String, value: String, suffix: String, keyboard: UIKeyboardType) {
        super.init()
        let label = UILabel()
        label.text = title
        label.font = ScenicQueueTokens.settingsFieldLabelFont
        label.textColor = AppColor.textPrimary
        textField.text = value
        textField.keyboardType = keyboard
        textField.textAlignment = .right
        textField.font = ScenicQueueTokens.settingsRowTitleFont
        textField.textColor = AppColor.textPrimary
        let suffixLabel = UILabel()
        suffixLabel.text = suffix
        suffixLabel.font = ScenicQueueTokens.settingsHintFont
        suffixLabel.textColor = AppColor.textSecondary
        addSubview(label)
        addSubview(textField)
        addSubview(suffixLabel)
        label.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(14)
            make.centerY.equalToSuperview()
        }
        suffixLabel.snp.makeConstraints { make in
            make.trailing.equalToSuperview().offset(-14)
            make.centerY.equalToSuperview()
        }
        textField.snp.makeConstraints { make in
            make.leading.greaterThanOrEqualTo(label.snp.trailing).offset(12)
            make.trailing.equalTo(suffixLabel.snp.leading).offset(-6)
            make.top.bottom.equalToSuperview().inset(8)
            make.height.equalTo(38)
            make.width.greaterThanOrEqualTo(90)
        }
    }

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

/// 设置页开关行。
final class ScenicQueueSwitchRow: ScenicQueueSettingCard {
    let toggle = UISwitch()

    init(title: String, isOn: Bool) {
        super.init()
        let label = UILabel()
        label.text = title
        label.font = ScenicQueueTokens.settingsFieldLabelFont
        label.textColor = AppColor.textPrimary
        toggle.isOn = isOn
        toggle.onTintColor = ScenicQueueTokens.bannerBlue
        addSubview(label)
        addSubview(toggle)
        label.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(14)
            make.centerY.equalToSuperview()
            make.top.bottom.equalToSuperview().inset(14)
        }
        toggle.snp.makeConstraints { make in
            make.trailing.equalToSuperview().offset(-14)
            make.centerY.equalToSuperview()
            make.leading.greaterThanOrEqualTo(label.snp.trailing).offset(12)
        }
    }

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