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

import SwiftUI

struct OpenRockyMCPServerEditorView: View {
    @ObservedObject var store: OpenRockyMCPStore
    let editingServerID: String?

    @Environment(\.dismiss) private var dismiss

    @State private var label: String = ""
    @State private var endpointURL: String = ""
    @State private var bearerToken: String = ""
    @State private var isEnabled: Bool = true
    @State private var refreshing: Bool = false
    @State private var refreshError: String?
    @State private var cachedTools: [OpenRockyMCPServer.CachedTool] = []
    @State private var lastRefreshedAt: Date?
    @State private var loaded: Bool = false

    var body: some View {
        Form {
            Section {
                TextField("Label", text: $label)
                    .autocorrectionDisabled()
                    .textInputAutocapitalization(.never)
                TextField("Endpoint URL", text: $endpointURL)
                    .keyboardType(.URL)
                    .autocorrectionDisabled()
                    .textInputAutocapitalization(.never)
                SecureField("Bearer token (optional)", text: $bearerToken)
                Toggle("Enabled", isOn: $isEnabled)
            } footer: {
                Text("Streamable-HTTP MCP transport. The label is the namespace prefix shown to the model as `mcp-{label}-{tool}`.")
            }

            Section {
                Button {
                    Task { await refreshTools() }
                } label: {
                    HStack {
                        if refreshing {
                            ProgressView()
                        } else {
                            Image(systemName: "arrow.clockwise")
                        }
                        Text(refreshing ? "Refreshing..." : "Refresh tool catalog")
                    }
                }
                .disabled(refreshing || endpointURL.isEmpty)

                if let date = lastRefreshedAt {
                    HStack {
                        Text("Last refresh")
                        Spacer()
                        Text(date.formatted(date: .abbreviated, time: .shortened))
                            .foregroundStyle(.secondary)
                    }
                }
                if let error = refreshError {
                    Text(error)
                        .foregroundStyle(.red)
                        .font(.footnote)
                }
            } header: {
                Text("Tools (\(cachedTools.count))")
            }

            if !cachedTools.isEmpty {
                Section {
                    ForEach(cachedTools, id: \.name) { tool in
                        VStack(alignment: .leading, spacing: 2) {
                            Text(tool.name)
                                .font(.subheadline.weight(.medium))
                            if !tool.description.isEmpty {
                                Text(tool.description)
                                    .font(.caption)
                                    .foregroundStyle(.secondary)
                            }
                        }
                        .padding(.vertical, 2)
                    }
                }
            }
        }
        .navigationTitle(editingServerID == nil ? "New MCP Server" : "Edit MCP Server")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .confirmationAction) {
                Button("Save") { save() }
                    .disabled(label.isEmpty || endpointURL.isEmpty)
            }
            ToolbarItem(placement: .cancellationAction) {
                Button("Cancel") { dismiss() }
            }
        }
        .onAppear { loadIfNeeded() }
    }

    // MARK: - Actions

    private func loadIfNeeded() {
        guard !loaded else { return }
        loaded = true
        if let id = editingServerID, let server = store.server(id: id) {
            label = server.label
            endpointURL = server.endpointURL
            bearerToken = server.bearerToken ?? ""
            isEnabled = server.isEnabled
            cachedTools = server.cachedTools
            lastRefreshedAt = server.lastRefreshedAt
        }
    }

    private func save() {
        let trimmedLabel = label.trimmingCharacters(in: .whitespacesAndNewlines)
        let trimmedURL = endpointURL.trimmingCharacters(in: .whitespacesAndNewlines)
        let trimmedToken = bearerToken.trimmingCharacters(in: .whitespacesAndNewlines)
        if let id = editingServerID, var existing = store.server(id: id) {
            existing.label = trimmedLabel
            existing.endpointURL = trimmedURL
            existing.bearerToken = trimmedToken.isEmpty ? nil : trimmedToken
            existing.isEnabled = isEnabled
            existing.cachedTools = cachedTools
            existing.lastRefreshedAt = lastRefreshedAt
            store.update(existing)
        } else {
            let server = OpenRockyMCPServer(
                label: trimmedLabel,
                endpointURL: trimmedURL,
                bearerToken: trimmedToken.isEmpty ? nil : trimmedToken,
                isEnabled: isEnabled,
                cachedTools: cachedTools,
                lastRefreshedAt: lastRefreshedAt
            )
            store.add(server)
        }
        dismiss()
    }

    private func refreshTools() async {
        // Build a temporary server snapshot from the form state so the user
        // can refresh before saving (otherwise first-time setup would force a
        // save → reload → refresh dance).
        let snapshot = OpenRockyMCPServer(
            label: label.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ? "preview" : label,
            endpointURL: endpointURL.trimmingCharacters(in: .whitespacesAndNewlines),
            bearerToken: bearerToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
                ? nil
                : bearerToken.trimmingCharacters(in: .whitespacesAndNewlines)
        )
        guard !snapshot.endpointURL.isEmpty else { return }
        refreshing = true
        refreshError = nil
        defer { refreshing = false }

        let client = OpenRockyMCPClient(server: snapshot)
        do {
            let tools = try await client.listTools()
            cachedTools = tools
            lastRefreshedAt = Date()
            // If we're editing an existing server, persist the cache
            // immediately so other parts of the app see the new tools without
            // waiting for the user to tap Save.
            if let id = editingServerID {
                store.updateCachedTools(serverID: id, tools: tools)
            }
        } catch {
            refreshError = error.localizedDescription
        }
    }
}
