import AppKit
import SwiftUI

@MainActor
struct PairingView: View {
    @ObservedObject private var session: AppSession
    @StateObject private var viewModel: PairingViewModel
    private let onConnected: () -> Void

    init(
        session: AppSession,
        onConnected: @escaping () -> Void = {}
    ) {
        self.session = session
        self.onConnected = onConnected
        _viewModel = StateObject(wrappedValue: PairingViewModel(session: session))
    }

    init(onConnected: @escaping () -> Void = {}) {
        self.init(session: AppSession.shared, onConnected: onConnected)
    }

    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            Picker("Pairing mode", selection: $viewModel.mode) {
                ForEach(PairingMode.allCases) { mode in
                    Text(mode.rawValue).tag(mode)
                }
            }
            .pickerStyle(.segmented)

            switch viewModel.mode {
            case .create:
                createCodeContent
            case .join:
                enterCodeContent
            }

            if let errorMessage = viewModel.errorMessage {
                Label(errorMessage, systemImage: "exclamationmark.triangle.fill")
                    .font(.callout)
                    .foregroundStyle(.red)
            }

            Spacer(minLength: 0)
        }
        .padding()
        .onChange(of: session.state) { _, newState in
            if case .connected = newState {
                onConnected()
            }
        }
    }

    private var createCodeContent: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text("Pair a new device")
                .font(.title3.weight(.semibold))

            TextField("Your display name", text: $viewModel.displayName)
                .textFieldStyle(.roundedBorder)

            if let generatedCode = viewModel.generatedCode {
                VStack(alignment: .leading, spacing: 8) {
                    Text("Share this code")
                        .font(.headline)

                    HStack {
                        Text(generatedCode)
                            .font(.system(.title2, design: .monospaced).weight(.semibold))
                            .textSelection(.enabled)

                        Spacer()

                        Button("Copy") {
                            copy(generatedCode)
                        }
                    }

                    Text("Code expires in 5 minutes")
                        .font(.footnote)
                        .foregroundStyle(.secondary)
                }
                .padding()
                .background(.quaternary, in: RoundedRectangle(cornerRadius: 10))
            } else {
                Button("Create Code") {
                    Task {
                        await viewModel.createCode()
                    }
                }
                .buttonStyle(.borderedProminent)
                .disabled(!viewModel.canSubmit || viewModel.isSubmitting)
            }

            if viewModel.isSubmitting || viewModel.isWaitingForPeer {
                HStack(spacing: 8) {
                    ProgressView()
                        .controlSize(.small)
                    Text(viewModel.isWaitingForPeer ? "Waiting for the other person..." : "Creating code...")
                        .foregroundStyle(.secondary)
                }
            }
        }
    }

    private var enterCodeContent: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text("Join a pairing")
                .font(.title3.weight(.semibold))

            TextField("Your display name", text: $viewModel.displayName)
                .textFieldStyle(.roundedBorder)

            TextField("Pairing code", text: $viewModel.code)
                .textFieldStyle(.roundedBorder)

            Button("Connect") {
                Task {
                    await viewModel.joinCode()
                }
            }
            .buttonStyle(.borderedProminent)
            .disabled(!viewModel.canSubmit || viewModel.isSubmitting)

            if viewModel.isSubmitting {
                HStack(spacing: 8) {
                    ProgressView()
                        .controlSize(.small)
                    Text("Connecting...")
                        .foregroundStyle(.secondary)
                }
            }
        }
    }

    private func copy(_ code: String) {
        NSPasteboard.general.clearContents()
        NSPasteboard.general.setString(code, forType: .string)
    }
}
