import SwiftUI
import SwiftData
import VNCCore

public struct AddConnectionPrefill: Equatable, Sendable {
    public let displayName: String
    public let host: String
    public let port: Int

    public init(displayName: String = "", host: String = "", port: Int = 5900) {
        self.displayName = displayName
        self.host = host
        self.port = port
    }
}

public struct AddConnectionView: View {
    @Environment(\.modelContext) private var context
    @Environment(\.dismiss) private var dismiss

    let prefill: AddConnectionPrefill?
    let editing: SavedConnection?

    @State private var displayName = ""
    @State private var host = ""
    @State private var port = "5900"
    @State private var username = ""
    @State private var password = ""
    @State private var revealPassword = false
    @State private var colorTag: ColorTag = .blue
    @State private var quality: QualityPreset = .adaptive
    @State private var inputMode: InputModePreference = .touch
    @State private var clipboardSync = true
    @State private var viewOnly = false
    @State private var notes = ""
    @State private var hasLoadedExisting = false

    public init(prefill: AddConnectionPrefill? = nil, editing: SavedConnection? = nil) {
        self.prefill = prefill
        self.editing = editing
    }

    private var isEditing: Bool { editing != nil }
    private var canSave: Bool {
        !displayName.trimmingCharacters(in: .whitespaces).isEmpty &&
        !host.trimmingCharacters(in: .whitespaces).isEmpty
    }

    private var authFooterText: String {
        if isEditing {
            return "Leave password blank to keep the current one. Stored in iOS Keychain (this device only)."
        }
        return """
        Two Mac paths:
        • User account (ARD) — enter your macOS short name + full account password. No length limit. Enabled in System Settings → Sharing → Screen Sharing → Allow access for…
        • VNC-only password — leave the username blank; macOS truncates to 8 characters. Enabled via Screen Sharing → ⓘ → "VNC viewers may control screen with password".
        """
    }

    public var body: some View {
        NavigationStack {
            Form {
                Section {
                    TextField("Display name", text: $displayName)
                        .font(.headline)
                    TextField("Host or IP", text: $host)
                        #if os(iOS)
                        .textInputAutocapitalization(.never)
                        #endif
                        .autocorrectionDisabled()
                        .font(.body.monospacedDigit())
                    HStack {
                        Text("Port")
                        Spacer()
                        TextField("5900", text: $port)
                            #if os(iOS)
                            .keyboardType(.numberPad)
                            #endif
                            .multilineTextAlignment(.trailing)
                            .font(.body.monospacedDigit())
                            .frame(maxWidth: 100)
                    }
                } header: {
                    Text("Connection")
                } footer: {
                    Text("Tailscale IPs and MagicDNS names work as long as the Tailscale app is connected.")
                }

                Section {
                    TextField("Username (optional)", text: $username)
                        #if os(iOS)
                        .textInputAutocapitalization(.never)
                        #endif
                        .autocorrectionDisabled()
                    HStack {
                        Group {
                            if revealPassword {
                                TextField("Password", text: $password)
                            } else {
                                SecureField(isEditing ? "Replace password" : "Password",
                                            text: $password)
                            }
                        }
                        .font(.body)
                        Button {
                            revealPassword.toggle()
                        } label: {
                            Image(systemName: revealPassword ? "eye.slash" : "eye")
                                .foregroundStyle(.secondary)
                        }
                        .buttonStyle(.plain)
                    }
                } header: {
                    Text("Authentication")
                } footer: {
                    Text(authFooterText)
                }

                Section {
                    colorTagPicker
                        .listRowInsets(EdgeInsets(top: 4, leading: 16, bottom: 8, trailing: 16))
                } header: {
                    Text("Tag")
                }

                Section {
                    Picker("Default input", selection: $inputMode) {
                        ForEach(InputModePreference.allCases, id: \.self) { mode in
                            Text(mode == .touch ? "Touch" : "Trackpad").tag(mode)
                        }
                    }
                    Picker("Quality", selection: $quality) {
                        Text("Adaptive").tag(QualityPreset.adaptive)
                        Text("High").tag(QualityPreset.high)
                        Text("Low (slow links)").tag(QualityPreset.low)
                    }
                    Toggle("Sync clipboard", isOn: $clipboardSync)
                    Toggle("View only", isOn: $viewOnly)
                } header: {
                    Text("Defaults")
                } footer: {
                    Text("View-only sends no input to the remote computer — useful as a watchdog screen.")
                }

                Section("Notes") {
                    TextField("Optional", text: $notes, axis: .vertical)
                        .lineLimit(2...6)
                }
            }
            #if os(iOS)
            .scrollContentBackground(.hidden)
            #endif
            .background(formBackground.ignoresSafeArea())
            .navigationTitle(isEditing ? "Edit Connection" : "New Connection")
            #if os(iOS)
            .navigationBarTitleDisplayMode(.inline)
            #endif
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Cancel") { dismiss() }
                }
                ToolbarItem(placement: .confirmationAction) {
                    Button(isEditing ? "Save" : "Add") { save() }
                        .disabled(!canSave)
                }
            }
            .onAppear { loadExistingIfNeeded() }
        }
    }

    private var formBackground: some View {
        LinearGradient(
            colors: [
                Color(red: 0.04, green: 0.05, blue: 0.10),
                Color(red: 0.02, green: 0.02, blue: 0.05)
            ],
            startPoint: .top,
            endPoint: .bottom
        )
    }

    private var colorTagPicker: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: 12) {
                ForEach(ColorTag.allCases, id: \.self) { tag in
                    Button {
                        colorTag = tag
                    } label: {
                        ZStack {
                            Circle()
                                .fill(tag.color)
                                .frame(width: 28, height: 28)
                            if tag == colorTag {
                                Circle()
                                    .stroke(Color.primary, lineWidth: 2)
                                    .frame(width: 36, height: 36)
                            }
                        }
                        .frame(width: 40, height: 40)
                        .accessibilityLabel(tag.rawValue.capitalized)
                        .accessibilityAddTraits(tag == colorTag ? .isSelected : [])
                    }
                    .buttonStyle(.plain)
                }
            }
            .padding(.vertical, 4)
        }
    }

    private func loadExistingIfNeeded() {
        guard !hasLoadedExisting else { return }
        hasLoadedExisting = true
        if let existing = editing {
            displayName = existing.displayName
            host = existing.host
            port = String(existing.port)
            username = existing.username
            colorTag = existing.colorTag
            quality = existing.quality
            inputMode = existing.inputMode
            clipboardSync = existing.clipboardSyncEnabled
            viewOnly = existing.viewOnly
            notes = existing.notes
        } else if let prefill, displayName.isEmpty, host.isEmpty {
            displayName = prefill.displayName
            host = prefill.host
            port = String(prefill.port)
        }
    }

    private func save() {
        let portInt = Int(port) ?? 5900
        let trimmedUsername = username.trimmingCharacters(in: .whitespaces)
        if let existing = editing {
            existing.displayName = displayName
            existing.host = host
            existing.port = portInt
            existing.username = trimmedUsername
            existing.colorTag = colorTag
            existing.quality = quality
            existing.inputMode = inputMode
            existing.clipboardSyncEnabled = clipboardSync
            existing.viewOnly = viewOnly
            existing.notes = notes
            if !password.isEmpty {
                try? KeychainService().storePassword(password, account: existing.keychainTag)
            }
        } else {
            let connection = SavedConnection(
                displayName: displayName,
                host: host,
                port: portInt,
                username: trimmedUsername,
                colorTag: colorTag,
                quality: quality,
                inputMode: inputMode,
                viewOnly: viewOnly,
                curtainMode: false,
                clipboardSyncEnabled: clipboardSync,
                notes: notes
            )
            context.insert(connection)
            if !password.isEmpty {
                try? KeychainService().storePassword(password, account: connection.keychainTag)
            }
        }
        try? context.save()
        dismiss()
    }
}
