import AppKit
import SwiftUI

struct LoginView: View {
    @State private var code: String = ""
    @FocusState private var isFocused: Bool
    @State private var isLoading = false
    @State private var errorMessage: String?

    let onSuccess: (AuthSession) -> Void

    private var isComplete: Bool { code.count == 6 && code.allSatisfy(\.isNumber) }

    var body: some View {
        VStack(spacing: 28) {
            Spacer().frame(height: 20)

            VStack(spacing: 14) {
                appIconView
                    .frame(width: 84, height: 84)

                Text("Rebreak Magic")
                    .font(.title.bold())

                VStack(spacing: 4) {
                    Text("Mit der Rebreak-App verbinden")
                        .font(.subheadline)
                        .foregroundStyle(.secondary)
                    Text("Öffne in der App: Einstellungen → Rebreak Magic")
                        .font(.caption)
                        .foregroundStyle(.tertiary)
                }
            }

            // ─── Code-Input ─────────────────────────────────────────────
            // EIN unsichtbares TextField empfängt alle Tasten. Die 6 Boxen
            // sind reine Anzeige → kein Focus-Race, kein System-Focus-Ring.
            VStack(spacing: 14) {
                ZStack {
                    HStack(spacing: 10) {
                        ForEach(0..<6, id: \.self) { index in
                            digitBox(index: index)
                        }
                    }

                    TextField("", text: $code)
                        .textFieldStyle(.plain)
                        .focused($isFocused)
                        .focusEffectDisabled()
                        .frame(width: 380, height: 60)
                        .opacity(0.01)
                        .onChange(of: code) { _, newValue in
                            handleCodeChange(newValue)
                        }
                        .onSubmit { handleSubmit() }
                }
                .contentShape(Rectangle())
                .onTapGesture { isFocused = true }

                if let error = errorMessage {
                    HStack(spacing: 6) {
                        Image(systemName: "exclamationmark.triangle.fill")
                            .foregroundStyle(.red)
                        Text(error)
                            .font(.caption)
                            .foregroundStyle(.red)
                    }
                }

                Button(action: handleSubmit) {
                    HStack(spacing: 8) {
                        if isLoading {
                            ProgressView()
                                .controlSize(.small)
                                .tint(.white)
                        }
                        Text(isLoading ? "Verbinde…" : "Verbinden")
                            .fontWeight(.medium)
                    }
                    .frame(maxWidth: .infinity)
                    .padding(.vertical, 6)
                }
                .buttonStyle(.borderedProminent)
                .keyboardShortcut(.return, modifiers: [])
                .disabled(!isComplete || isLoading)
            }
            .frame(maxWidth: 380)

            Spacer()

            Text("Noch keine Rebreak-App? Lade sie im App Store / Play Store.")
                .font(.caption2)
                .foregroundStyle(.tertiary)
                .padding(.bottom, 18)
        }
        .padding(.horizontal, 32)
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color(nsColor: .windowBackgroundColor))
        .onAppear {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
                isFocused = true
            }
        }
    }

    // MARK: - Components

    @ViewBuilder
    private var appIconView: some View {
        if let icon = NSApplication.shared.applicationIconImage,
           icon.size.width > 2 {
            Image(nsImage: icon)
                .resizable()
                .interpolation(.high)
                .frame(width: 84, height: 84)
        } else {
            RoundedRectangle(cornerRadius: 18, style: .continuous)
                .fill(LinearGradient(colors: [.blue, .purple], startPoint: .topLeading, endPoint: .bottomTrailing))
                .overlay(
                    Image(systemName: "wand.and.stars")
                        .font(.system(size: 40, weight: .semibold))
                        .foregroundStyle(.white)
                )
        }
    }

    @ViewBuilder
    private func digitBox(index: Int) -> some View {
        let chars = Array(code)
        let digit: String = index < chars.count ? String(chars[index]) : ""
        let activeIndex = min(chars.count, 5)
        let isActive = isFocused && index == activeIndex
        let isFilled = !digit.isEmpty

        RoundedRectangle(cornerRadius: 10, style: .continuous)
            .fill(Color(nsColor: .controlBackgroundColor))
            .frame(width: 48, height: 60)
            .overlay(
                RoundedRectangle(cornerRadius: 10, style: .continuous)
                    .strokeBorder(
                        isActive ? Color.accentColor :
                        (isFilled ? Color.gray.opacity(0.4) : Color.gray.opacity(0.25)),
                        lineWidth: isActive ? 2 : 1
                    )
            )
            .overlay(
                Text(digit)
                    .font(.system(size: 28, weight: .semibold, design: .rounded))
                    .foregroundStyle(.primary)
            )
    }

    // MARK: - Logic

    private func handleCodeChange(_ newValue: String) {
        let digits = newValue.filter(\.isNumber)
        let clipped = String(digits.prefix(6))
        if clipped != newValue {
            code = clipped
            return
        }
        if clipped.count == 6 && !isLoading {
            handleSubmit()
        }
    }

    private func handleSubmit() {
        guard isComplete, !isLoading else { return }
        let toSend = code
        Task {
            isLoading = true
            errorMessage = nil
            do {
                let session = try await AuthService.shared.signInWithPairingCode(toSend)
                onSuccess(session)
            } catch {
                errorMessage = error.localizedDescription
                code = ""
                isFocused = true
            }
            isLoading = false
        }
    }
}

#Preview {
    LoginView { session in
        print("Magic-Session: \(session.sessionId)")
    }
    .frame(width: 720, height: 600)
}
