//
// OpenRocky — Voice-first AI Agent
// https://github.com/openrocky
//
// Developed by everettjf with the assistance of Claude Code and Codex.
// Date: 2026-04-25
// Copyright (c) 2026 everettjf. All rights reserved.
//

import SwiftUI

/// Per-Instance advanced tuning controls for the OpenAI Realtime voice session.
///
/// Lives behind a DisclosureGroup in the editor so first-time users see a clean form.
/// Each control rewrites a single field on the bound `OpenRockyRealtimeAdvancedSettings`.
struct OpenRockyRealtimeAdvancedSettingsSection: View {
    @Binding var settings: OpenRockyRealtimeAdvancedSettings
    @State private var isExpanded: Bool = false

    var body: some View {
        Section {
            DisclosureGroup(isExpanded: $isExpanded) {
                modelRow
                reasoningEffortRow
                transcriptionRow
                inputLanguageRow
                turnDetectionRow
                maxOutputTokensRow
                speedRow
                modalitiesRow
                bargeInRow
                resetRow
            } label: {
                HStack(spacing: 8) {
                    Image(systemName: "slider.horizontal.3")
                        .foregroundStyle(.secondary)
                    Text("Advanced")
                        .font(.system(size: 14, weight: .semibold))
                }
            }
        } footer: {
            if isExpanded {
                Text("These knobs shape every Realtime turn. Defaults are tuned for `gpt-realtime-2` with semantic VAD and low reasoning effort; only change them if you know what you're tuning.")
            }
        }
    }

    // MARK: - Rows

    private var modelRow: some View {
        VStack(alignment: .leading, spacing: 4) {
            Text("Realtime Model").font(.subheadline.weight(.medium))
            TextField("gpt-realtime-2", text: $settings.realtimeModel)
                .textInputAutocapitalization(.never)
                .autocorrectionDisabled()
                .font(.system(.subheadline, design: .monospaced))
            ForEach(OpenRockyRealtimeProviderKind.openAI.suggestedModels, id: \.self) { suggested in
                Button(suggested) { settings.realtimeModel = suggested }
                    .font(.caption)
            }
        }
        .padding(.vertical, 4)
    }

    private var reasoningEffortRow: some View {
        VStack(alignment: .leading, spacing: 4) {
            Picker("Reasoning Effort", selection: $settings.reasoningEffort) {
                ForEach(OpenRockyRealtimeAdvancedSettings.ReasoningEffort.allCases) { effort in
                    Text(effort.displayName).tag(effort)
                }
            }
            Text(settings.reasoningEffort.summary)
                .font(.caption2)
                .foregroundStyle(.secondary)
        }
        .padding(.vertical, 4)
    }

    private var transcriptionRow: some View {
        Picker("Transcription", selection: $settings.transcriptionModel) {
            ForEach(OpenRockyRealtimeAdvancedSettings.TranscriptionModel.allCases) { model in
                Text(model.displayName).tag(model)
            }
        }
    }

    private var inputLanguageRow: some View {
        VStack(alignment: .leading, spacing: 4) {
            Text("Input Language Hint").font(.subheadline.weight(.medium))
            TextField("auto-detect", text: Binding(
                get: { settings.inputLanguage ?? "" },
                set: { newValue in
                    let trimmed = newValue.trimmingCharacters(in: .whitespacesAndNewlines)
                    settings.inputLanguage = trimmed.isEmpty ? nil : trimmed
                }
            ))
            .textInputAutocapitalization(.never)
            .autocorrectionDisabled()
            .font(.system(.subheadline, design: .monospaced))
            Text("ISO-639-1 (e.g. zh, en, ja). Empty = auto-detect.")
                .font(.caption2)
                .foregroundStyle(.secondary)
        }
        .padding(.vertical, 4)
    }

    private var turnDetectionRow: some View {
        VStack(alignment: .leading, spacing: 8) {
            Picker("Turn Detection", selection: turnDetectionModeBinding) {
                ForEach(OpenRockyRealtimeAdvancedSettings.TurnDetectionConfig.Mode.allCases) { mode in
                    Text(mode.displayName).tag(mode)
                }
            }
            switch settings.turnDetection {
            case .semanticVAD(let eagerness):
                Picker("Eagerness", selection: Binding(
                    get: { eagerness },
                    set: { settings.turnDetection = .semanticVAD(eagerness: $0) }
                )) {
                    ForEach(OpenRockyRealtimeAdvancedSettings.SemanticVADEagerness.allCases) { value in
                        Text(value.displayName).tag(value)
                    }
                }
            case .serverVAD(let prefix, let silence, let threshold):
                serverVADSlider(
                    label: "Prefix Padding",
                    valueLabel: "\(prefix) ms",
                    value: Double(prefix),
                    range: 100...1000,
                    step: 50
                ) { newValue in
                    settings.turnDetection = .serverVAD(
                        prefixPaddingMs: Int(newValue),
                        silenceDurationMs: silence,
                        threshold: threshold
                    )
                }
                serverVADSlider(
                    label: "Silence Duration",
                    valueLabel: "\(silence) ms",
                    value: Double(silence),
                    range: 200...2000,
                    step: 100
                ) { newValue in
                    settings.turnDetection = .serverVAD(
                        prefixPaddingMs: prefix,
                        silenceDurationMs: Int(newValue),
                        threshold: threshold
                    )
                }
                serverVADSlider(
                    label: "Threshold",
                    valueLabel: String(format: "%.2f", threshold),
                    value: threshold,
                    range: 0.1...1.0,
                    step: 0.05
                ) { newValue in
                    settings.turnDetection = .serverVAD(
                        prefixPaddingMs: prefix,
                        silenceDurationMs: silence,
                        threshold: newValue
                    )
                }
            }
        }
        .padding(.vertical, 4)
    }

    private var maxOutputTokensRow: some View {
        Stepper(
            "Max Output Tokens: \(settings.maxOutputTokens)",
            value: $settings.maxOutputTokens,
            in: 64...4096,
            step: 64
        )
    }

    private var speedRow: some View {
        VStack(alignment: .leading, spacing: 4) {
            HStack {
                Text("Audio Speed").font(.subheadline.weight(.medium))
                Spacer()
                Text(String(format: "%.2fx", settings.speed))
                    .font(.system(.caption, design: .monospaced))
                    .foregroundStyle(.secondary)
            }
            Slider(value: $settings.speed, in: 0.25...4.0, step: 0.05)
        }
        .padding(.vertical, 4)
    }

    private var modalitiesRow: some View {
        Toggle("Allow Text-only Replies", isOn: $settings.allowTextOnly)
    }

    private var bargeInRow: some View {
        VStack(alignment: .leading, spacing: 4) {
            HStack {
                Text("Barge-in Sensitivity").font(.subheadline.weight(.medium))
                Spacer()
                Text("RMS \(Int(settings.bargeInRMSThreshold))")
                    .font(.system(.caption, design: .monospaced))
                    .foregroundStyle(.secondary)
            }
            Slider(value: $settings.bargeInRMSThreshold, in: 1000...10000, step: 100)
            Text("Lower = more sensitive (you can interrupt more easily). Only used when 'Voice Interruption' is on in Preferences.")
                .font(.caption2)
                .foregroundStyle(.secondary)
        }
        .padding(.vertical, 4)
    }

    private var resetRow: some View {
        Button(role: .destructive) {
            settings = .default
        } label: {
            HStack {
                Image(systemName: "arrow.counterclockwise")
                Text("Reset to Defaults")
            }
        }
    }

    // MARK: - Helpers

    private var turnDetectionModeBinding: Binding<OpenRockyRealtimeAdvancedSettings.TurnDetectionConfig.Mode> {
        Binding(
            get: { settings.turnDetection.mode },
            set: { newMode in
                switch newMode {
                case .semantic:
                    settings.turnDetection = .semanticVAD(eagerness: .medium)
                case .server:
                    settings.turnDetection = .serverVAD(prefixPaddingMs: 400, silenceDurationMs: 900, threshold: 0.8)
                }
            }
        )
    }

    private func serverVADSlider(
        label: String,
        valueLabel: String,
        value: Double,
        range: ClosedRange<Double>,
        step: Double,
        onChange: @escaping (Double) -> Void
    ) -> some View {
        VStack(alignment: .leading, spacing: 4) {
            HStack {
                Text(label).font(.caption.weight(.medium))
                Spacer()
                Text(valueLabel)
                    .font(.system(.caption2, design: .monospaced))
                    .foregroundStyle(.secondary)
            }
            Slider(
                value: Binding(get: { value }, set: { onChange($0) }),
                in: range,
                step: step
            )
        }
    }
}
