//
//  SettingExtensions.swift
//  MpAccDemo
//

import UIKit
import MpAccSDK

extension SettingViewController {
    
    func createSettingItemViews() -> [UIView] {
        let settting = ConfigSetting.shared
        return createLogSettingsViews(setting: settting) +
        createRegisterSettingsViews(setting: settting) +
        createNetworkConditionsViews(setting: settting) +
        createSocks5ConfigViews(setting: settting) +
        createAccConfigViews(setting: settting) +
        createMeasureConfigItemViews(setting: settting)
    }
    func confirmSettingAction() -> Void {
        // 将大部分参数同步进config，或者VPNSettingData中
        self.configItemBtnsStackView.arrangedSubviews.flatMap { view -> [ConfigItemViewProtocol] in
            if let itemView = view as? ConfigItemViewProtocol {
                return [itemView]
            }
            if let sv = view as? UIStackView {
                return sv.arrangedSubviews.compactMap { $0 as? ConfigItemViewProtocol }
            }
            return []
        }.forEach { itemView in
            itemView.updateConfig()
        }
        ConfigSetting.save()
    }
}

extension SettingViewController {
    func createLogSettingsViews(setting: ConfigSetting) -> [UIView] {
        session(title: "日志设置") {
            menuItemView(title: "是否显示滚动日志(Demo)") {
                MenuSwitch.newItem {
                    MpItem(title: "", on: setting.displayRollingLog)
                }.save { item in
                    setting.displayRollingLog = item.on
                }
            }
            menuItemView(title: "是否使用日志插件") {
                MenuSwitch.newItem {
                    MpItem(title: "", on: setting.useLogPlugin)
                }.save { item in
                    setting.useLogPlugin = item.on
                }
            }
            menuItemView(title: "日志等级", addEndView: true) {
                MenuButton.newItem {
                    MpItem(title: "DEBUG", obj: LogLevel.DEBUG, on: setting.logLevel == .DEBUG)
                    MpItem(title: "INFO", obj: LogLevel.INFO, on: setting.logLevel == .INFO)
                    MpItem(title: "WARN", obj: LogLevel.WARN, on: setting.logLevel == .WARN)
                    MpItem(title: "FATAL", obj: LogLevel.FATAL, on: setting.logLevel == .FATAL)
                    MpItem(title: "PANIC", obj: LogLevel.PANIC, on: setting.logLevel == .PANIC)
                }.save { item in
                    setting.logLevel = item.getObj()
                }
            }
        }
    }
}

// MARK: 注册参数配置
extension SettingViewController {
    func createRegisterSettingsViews(setting: ConfigSetting) -> [UIView] {
        session(title: "公有云 or 私有云") {
            menuItemView(title: "公有云模式") {
                MenuSwitch.newItem {
                    MpItem(title: "", on: setting.publicMode)
                }.save { item in
                    setting.publicMode = item.on
                }
            }
            
            menuItemView(title: "dataKey") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.registerSetting.dataKey), on: true)
                }.save { item in
                    setting.registerSetting.dataKey = item.title
                }
            }
            menuItemView(title: "deviceId") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.registerSetting.deviceId), on: true)
                }.save { item in
                    setting.registerSetting.deviceId = item.title
                }
            }
        }
    }
}

extension SettingViewController {
    func createNetworkConditionsViews(setting: ConfigSetting) -> [UIView] {
        return session(title: "加速网络条件设置") {
            menuItemView(title: "是否启用加速网络条件") {
                MenuSwitch.newItem {
                    MpItem(title: "", on: setting.needNetworkConditions)
                }.save { item in
                    setting.needNetworkConditions = item.on
                }
            }
            menuItemView(title: "WiFi必须可用") {
                MenuSwitch.newItem {
                    MpItem(title: "", on: setting.needWiFiAvailable)
                }.save { item in
                    setting.needWiFiAvailable = item.on
                }
            }
            menuItemView(title: "SIM必须可用") {
                MenuSwitch.newItem {
                    MpItem(title: "", on: setting.needSIMAvailable)
                }.save { item in
                    setting.needSIMAvailable = item.on
                }
            }
            menuItemView(title: "蜂窝是否必须可用") {
                MenuSwitch.newItem {
                    MpItem(title: "", on: setting.needMobileDataAvailable)
                }.save { item in
                    setting.needMobileDataAvailable = item.on
                }
            }
        }
    }
}

// MARK: socks 设置
extension SettingViewController {
    func createSocks5ConfigViews(setting: ConfigSetting) -> [UIView] {
        return session(title: "socks5设置") {
            menuItemView(title: "socket端口") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.socksProxyPort), on: true)
                }.save { item in
                    if let port = Int(item.title), port > 0 {
                        setting.socksProxyPort = port
                    } else {
                        assertionFailure("端口不合理， toast")
                    }
                }
            }
            menuItemView(title: "Username") {
                MenuTextField.newItem {
                    MpItem(title: setting.socksUsername ?? "", on: true)
                }.save { item in
                    if item.title.count > 0 {
                        setting.socksUsername = item.title
                    } else {
                        setting.socksUsername = nil
                    }
                }
            }
            menuItemView(title: "Password") {
                MenuTextField.newItem {
                    MpItem(title: setting.socksPassword ?? "", on: true)
                }.save { item in
                    if item.title.count > 0 {
                        setting.socksPassword = item.title
                    } else {
                        setting.socksPassword = nil
                    }
                }
            }
        }
    }
}

// MARK: 加速Config设置
extension SettingViewController {
    func createAccConfigViews(setting: ConfigSetting) -> [UIView] {
        return session(title: "加速设置") {
            menuItemView(title: "加速模式") {
                MenuButton.newItem {
                    MpItem(title: "聚合", obj: 1, on: setting.accMode == 1)
                    MpItem(title: "双发", obj: 2, on: setting.accMode == 2)
                    MpItem(title: "实时", obj: 3, on: setting.accMode == 3)
                }.save { item in
                    setting.accMode = item.getObj()
                }
            }
            menuItemView(title: "最大重试次数") {
                MenuButton.newItem {
                    MpItem(title: "invalid", obj: -1, on: setting.maxRetryTimes == -1)
                    MpItem(title: "0", obj: 0, on: setting.maxRetryTimes == 0)
                    MpItem(title: "1", obj: 1, on: setting.maxRetryTimes == 1)
                    MpItem(title: "3", obj: 3, on: setting.maxRetryTimes == 3)
                    MpItem(title: "5", obj: 5, on: setting.maxRetryTimes == 5)
                    MpItem(title: "10", obj: 10, on: setting.maxRetryTimes == 10)
                }.save { item in
                    setting.maxRetryTimes = item.getObj()
                }
            }
            menuItemView {
                UILabel(text: "节点选择:")
                MenuButton.newItem {
                    MpItem(title: "手动", obj: false, on: setting.autoNode == false)
                    MpItem(title: "自动", obj: true, on: setting.autoNode)
                }.changed { item in
                    setting.autoNode = item.getObj()
                }.setting { itemView in
                    itemView.setContentHuggingPriority(UILayoutPriority.required, for: .horizontal)
                }
                UILabel(text: "端口:")
                MenuTextField.newItem {
                    MpItem(title: String(setting.port), on: true)
                }.save { item in
                    if let port = Int(item.title), port > 0 {
                        setting.port = port
                    } else {
                        assertionFailure("端口不合理， toast")
                    }
                }
            }
            menuItemView(title: "节点列表") {
                MenuTextField.newItem {
                    MpItem(title: setting.ipv4sStr, on: true)
                }.save { item in
                    setting.ipv4sStr = item.title
                }
            }
            menuItemView(title: "report频率") {
                MenuButton.newItem {
                    MpItem(title: "1", obj: 1, on: setting.pingInterval == 1)
                    MpItem(title: "3", obj: 3, on: setting.pingInterval == 3)
                    MpItem(title: "5", obj: 5, on: setting.pingInterval == 5)
                    MpItem(title: "10", obj: 10, on: setting.pingInterval == 10)
                }.save { item in
                    setting.pingInterval = item.getObj()
                }
            }
            menuItemView(title: "优先级 wifi") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.wifiPriority), on: true)
                }.save { item in
                    guard let priority = Int(item.title) else { 
                        assertionFailure("错误")
                        return
                    }
                    setting.wifiPriority = priority
                }
            }
            menuItemView(title: "优先级 mobile") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.mobilePriority), on: true)
                }.save { item in
                    guard let priority = Int(item.title) else {
                        assertionFailure("错误")
                        return
                    }
                    setting.mobilePriority = priority
                }
            }

//            menuItemView(title: "keepAlive") {
//                MenuSwitch.newItem {
//                    MpItem(title: "", on: setting.keepAlive)
//                }.save { item in
//                    setting.keepAlive = item.on
//                }
//            }
//            menuItemView(addEndView: true) {
//                UILabel(text: "tcp直连:")
//                MenuSwitch.newItem {
//                    MpItem(title: "", on: setting.tcpDirect)
//                }.save { item in
//                    setting.tcpDirect = item.on
//                }
//                UILabel(text: "udp直连:")
//                MenuSwitch.newItem {
//                    MpItem(title: "", on: setting.udpDirect)
//                }.save { item in
//                    setting.udpDirect = item.on
//                }
//            }
            menuItemView(addEndView: true) {
                UILabel(text: "拥塞算法:")
                MenuButton.newItem {
                    MpItem(title: "BBR", obj: MpCongrestionMode.BBR, on: setting.congrestionMode == .BBR)
                    MpItem(title: "CUBIC", obj: MpCongrestionMode.CUBIC, on: setting.congrestionMode == .CUBIC)
                    MpItem(title: "BBR_NORMAL", obj: MpCongrestionMode.BBR_NORMAL, on: setting.congrestionMode == .BBR_NORMAL)
                }.save { item in
                    setting.congrestionMode = item.getObj()
                }
                UILabel(text: "加密:")
                MenuSwitch.newItem {
                    MpItem(title: "", on: setting.encryption)
                }.save { item in
                    setting.encryption = item.on
                }
            }
        }
    }
}

extension SettingViewController {
    func createMeasureConfigItemViews(setting: ConfigSetting) -> [UIView] {
        session(title: "测速模块") {
            menuItemView(title: "测速地址") {
                MenuTextField.newItem {
                    MpItem(title: setting.addr, on: true)
                }.save { item in
                    setting.addr = item.title
                }
                MenuSwitch.newItem {
                    MpItem(title: "", on: setting.useAddr)
                }.save { item in
                    setting.useAddr = item.on
                }
            }
            menuItemView(title: "滑动窗口测量时间(ms)") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.time), on: true)
                }.save { item in
                    guard let time = Int(item.title) else { 
                        assertionFailure("错误")
                        return
                    }
                    setting.time = time
                }
            }
            menuItemView(title: "时延阈值") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.rtt), on: true)
                }.save { item in
                    guard let rtt = Int(item.title) else { 
                        assertionFailure("错误")
                        return
                    }
                    setting.rtt = rtt
                }
            }
            
            menuItemView(title: "丢包率阈值") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.loss), on: true)
                }.save { item in
                    guard let loss = Int(item.title) else {
                        assertionFailure("错误")
                        return
                    }
                    setting.loss = loss
                }
            }
            
            menuItemView(title: "抖动阈值") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.jitter), on: true)
                }.save { item in
                    guard let jitter = Int(item.title) else {
                        assertionFailure("错误")
                        return
                    }
                    setting.jitter = jitter
                }
            }
            
            menuItemView(title: "快启动窗口时间") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.quickTime), on: true)
                }.save { item in
                    guard let quickTime = Int(item.title) else { 
                        assertionFailure("错误")
                        return
                    }
                    setting.quickTime = quickTime
                }
            }
            
            menuItemView(title: "快启动时延阈值") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.quickRtt), on: true)
                }.save { item in
                    guard let quickRtt = Int(item.title) else {
                        assertionFailure("错误")
                        return
                    }
                    setting.quickRtt = quickRtt
                }
            }
            
            menuItemView(title: "测量回调频率") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.interval), on: true)
                }.save { item in
                    guard let interval = Int(item.title) else {
                        assertionFailure("错误")
                        return
                    }
                    setting.interval = interval
                }
            }
            
            menuItemView(title: "设置延迟提醒时间(ms)") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.delayRemindTime), on: true)
                }.save { item in
                    guard let delayRemindTime = Int(item.title) else {
                        assertionFailure("错误int值")
                        return
                    }
                    setting.delayRemindTime = delayRemindTime
                }
            }
            
            menuItemView(title: "ping包超时时间(ms)") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.pingTimeout), on: true)
                }.save { item in
                    guard let pingTimeout = Int(item.title) else {
                        assertionFailure("错误int值")
                        return
                    }
                    setting.pingTimeout = pingTimeout
                }
            }
            
            menuItemView(title: "禁用快速检测") {
                MenuSwitch.newItem {
                    MpItem(title: "", on: setting.disableQuickDetect)
                }.save { item in
                    setting.disableQuickDetect = item.on
                }
            }
        } +
        session(title: "加强测速") {
            menuItemView(title: "是否使用加强测速") {
                MenuSwitch.newItem {
                    MpItem(title: "", on: setting.enhanced)
                }.save { item in
                    setting.enhanced = item.on
                }
            }
            
            menuItemView(title: "packetLossEscape") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.packetLossEscape.packetLossCount), on: true)
                }.save { item in
                    guard let packetLossCount = Int(item.title) else {
                        assertionFailure("错误int值")
                        return
                    }
                    setting.packetLossEscape.packetLossCount = packetLossCount
                }
                MenuSwitch.newItem {
                    MpItem(title: "", on: setting.enablePacketLossEscape)
                }.save { item in
                    setting.enablePacketLossEscape = item.on
                }
            }
            
            menuItemView(title: "maxRttEscape") {
                MenuSwitch.newItem {
                    MpItem(title: "", on: setting.enableMaxRttEscape)
                }.save { item in
                    setting.enableMaxRttEscape = item.on
                }
            } setup: { itemView in
                itemView.backgroundColor = .lightGray.withAlphaComponent(0.2)
            }
            
            menuItemView(title: "maxRttCount") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.maxRttEscape.maxRttCount), on: true)
                }.save { item in
                    guard let maxRttCount = Int(item.title) else {
                        assertionFailure("错误int值")
                        return
                    }
                    setting.maxRttEscape.maxRttCount = maxRttCount
                }
            }
            
            menuItemView(title: "maxRttCount") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.maxRttEscape.rttThreshold), on: true)
                }.save { item in
                    guard let rttThreshold = Int(item.title) else {
                        assertionFailure("错误int值")
                        return
                    }
                    setting.maxRttEscape.rttThreshold = rttThreshold
                }
            }
            
            menuItemView(title: "rttExceptionEscape") {
                MenuSwitch.newItem {
                    MpItem(title: "", on: setting.enableRttExceptionEscape)
                }.save { item in
                    setting.enableRttExceptionEscape = item.on
                }
            } setup: { itemView in
                itemView.backgroundColor = .lightGray.withAlphaComponent(0.2)
            }
            
            menuItemView(title: "detectWindowTime") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.rttExceptionEscape.detectWindowTime), on: true)
                }.save { item in
                    guard let detectWindowTime = Int(item.title) else {
                        assertionFailure("错误int值")
                        return
                    }
                    setting.rttExceptionEscape.detectWindowTime = detectWindowTime
                }
            }
            
            menuItemView(title: "accBenchmarkRtt") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.rttExceptionEscape.accBenchmarkRtt), on: true)
                }.save { item in
                    guard let accBenchmarkRtt = Int(item.title) else {
                        assertionFailure("错误int值")
                        return
                    }
                    setting.rttExceptionEscape.accBenchmarkRtt = accBenchmarkRtt
                }
            }
            
            menuItemView(title: "rttDiffThreshold") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.rttExceptionEscape.rttDiffThreshold), on: true)
                }.save { item in
                    guard let rttDiffThreshold = Int(item.title) else {
                        assertionFailure("错误int值")
                        return
                    }
                    setting.rttExceptionEscape.rttDiffThreshold = rttDiffThreshold
                }
            }
            
            menuItemView(title: "stopAccRemind") {
                MenuSwitch.newItem {
                    MpItem(title: "", on: setting.enableStopAccRemind)
                }.save { item in
                    setting.enableStopAccRemind = item.on
                }
            } setup: { itemView in
                itemView.backgroundColor = .lightGray.withAlphaComponent(0.2)
            }
            
            menuItemView(title: "detectWindowTime") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.stopAccRemind.detectWindowTime), on: true)
                }.save { item in
                    guard let detectWindowTime = Int(item.title) else {
                        assertionFailure("错误int值")
                        return
                    }
                    setting.stopAccRemind.detectWindowTime = detectWindowTime
                }
            }
            
            menuItemView(title: "rttDiffRate") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.stopAccRemind.rttDiffRate), on: true)
                }.save { item in
                    guard let rttDiffRate = Int(item.title) else {
                        assertionFailure("错误int值")
                        return
                    }
                    setting.stopAccRemind.rttDiffRate = rttDiffRate
                }
            }
            
            menuItemView(title: "jitterRate") {
                MenuTextField.newItem {
                    MpItem(title: String(setting.stopAccRemind.jitterRate), on: true)
                }.save { item in
                    guard let jitterRate = Int(item.title) else {
                        assertionFailure("错误int值")
                        return
                    }
                    setting.stopAccRemind.jitterRate = jitterRate
                }
            }
        }
    }
}
