import SwiftUI

// MARK: - Root

struct OnboardingView: View {
    @State private var viewModel = OnboardingViewModel()
    @State private var langManager = LanguageManager.shared

    var body: some View {
        Group {
            if viewModel.isComplete {
                Color.clear
            } else {
                NavigationStack(path: $viewModel.navPath) {
                    LanguageStepView(viewModel: viewModel)
                        .navigationDestination(for: OnboardingViewModel.Step.self) { step in
                            switch step {
                            case .welcome:
                                WelcomeStepView(viewModel: viewModel)
                            case .connect:
                                ConnectStepView(viewModel: viewModel)
                            case .ready:
                                ReadyStepView(onComplete: viewModel.completeOnboarding)
                            case .language:
                                EmptyView()
                            }
                        }
                        .navigationBarHidden(true)
                }
            }
        }
        .environment(langManager)
    }
}

// MARK: - Step 0: Language

struct LanguageStepView: View {
    @Bindable var viewModel: OnboardingViewModel
    @State private var selected: LanguageManager.Language = LanguageManager.shared.current

    var body: some View {
        VStack(spacing: 32) {
            Spacer()

            VStack(spacing: 16) {
                ZStack {
                    Circle()
                        .fill(Color.accentColor.opacity(0.12))
                        .frame(width: 120, height: 120)
                    Image(systemName: "globe")
                        .font(.system(size: 52))
                        .foregroundStyle(Color.accentColor)
                }

                VStack(spacing: 8) {
                    Text(L("onboarding.language.title"))
                        .font(.largeTitle.bold())
                        .multilineTextAlignment(.center)

                    Text(L("onboarding.language.subtitle"))
                        .font(.body)
                        .foregroundStyle(.secondary)
                        .multilineTextAlignment(.center)
                }
            }

            VStack(spacing: 12) {
                ForEach(LanguageManager.Language.allCases) { lang in
                    Button {
                        selected = lang
                        LanguageManager.shared.set(lang)
                    } label: {
                        HStack(spacing: 14) {
                            Text(lang.flag)
                                .font(.title2)
                            Text(lang.displayName)
                                .font(.body.weight(.medium))
                                .foregroundStyle(.primary)
                            Spacer()
                            if selected == lang {
                                Image(systemName: "checkmark.circle.fill")
                                    .foregroundStyle(Color.accentColor)
                            }
                        }
                        .padding()
                        .background(
                            selected == lang
                                ? Color.accentColor.opacity(0.1)
                                : Color(.secondarySystemBackground),
                            in: RoundedRectangle(cornerRadius: 12)
                        )
                        .overlay(
                            RoundedRectangle(cornerRadius: 12)
                                .stroke(selected == lang ? Color.accentColor : Color.clear, lineWidth: 1.5)
                        )
                    }
                    .accessibilityLabel(lang.displayName)
                }
            }
            .padding(.horizontal, 32)

            Spacer()

            Button {
                viewModel.push(.welcome)
            } label: {
                Text(L("onboarding.welcome.cta"))
                    .font(.headline)
                    .frame(maxWidth: .infinity)
                    .padding()
                    .background(Color.accentColor)
                    .foregroundStyle(.white)
                    .clipShape(RoundedRectangle(cornerRadius: 14))
            }
            .padding(.horizontal, 32)
            .padding(.bottom, 48)
        }
        .padding()
    }
}

// MARK: - Step 1: Welcome

struct WelcomeStepView: View {
    @Bindable var viewModel: OnboardingViewModel

    var body: some View {
        VStack(spacing: 32) {
            Spacer()

            VStack(spacing: 16) {
                ZStack {
                    Circle()
                        .fill(Color.accentColor.opacity(0.12))
                        .frame(width: 120, height: 120)
                    Image(systemName: "books.vertical.fill")
                        .font(.system(size: 52))
                        .foregroundStyle(Color.accentColor)
                }

                VStack(spacing: 8) {
                    Text(L("onboarding.welcome.title"))
                        .font(.largeTitle.bold())
                        .multilineTextAlignment(.center)

                    Text(L("onboarding.welcome.subtitle"))
                        .font(.title3)
                        .foregroundStyle(.secondary)
                        .multilineTextAlignment(.center)
                }
            }

            Spacer()

            Button {
                viewModel.push(.connect)
            } label: {
                Text(L("onboarding.welcome.cta"))
                    .font(.headline)
                    .frame(maxWidth: .infinity)
                    .padding()
                    .background(Color.accentColor)
                    .foregroundStyle(.white)
                    .clipShape(RoundedRectangle(cornerRadius: 14))
            }
            .accessibilityLabel(L("onboarding.welcome.cta"))
            .padding(.horizontal, 32)
            .padding(.bottom, 48)
        }
        .padding()
        .navigationBarBackButtonHidden(false)
    }
}

// MARK: - Step 2: Connect (URL + Token + inline verification)

struct ConnectStepView: View {
    @Bindable var viewModel: OnboardingViewModel
    @State private var showTokenId = false
    @State private var showTokenSecret = false
    @State private var showHelp = false
    @State private var verifyTask: Task<Void, Never>? = nil

    var body: some View {
        ScrollView {
            VStack(alignment: .leading, spacing: 24) {

                // Header
                VStack(alignment: .leading, spacing: 8) {
                    Text(L("onboarding.server.title"))
                        .font(.largeTitle.bold())
                    Text(L("onboarding.server.subtitle"))
                        .font(.body)
                        .foregroundStyle(.secondary)
                }

                // Server Name field
                VStack(alignment: .leading, spacing: 6) {
                    Label(L("onboarding.server.name.label"), systemImage: "tag")
                        .font(.subheadline.bold())

                    TextField(L("onboarding.server.name.placeholder"), text: $viewModel.serverNameInput)
                        .autocorrectionDisabled()
                        .textInputAutocapitalization(.words)
                        .padding()
                        .background(Color(.secondarySystemBackground), in: RoundedRectangle(cornerRadius: 12))
                }

                // Server URL field
                VStack(alignment: .leading, spacing: 8) {
                    HStack {
                        Image(systemName: "globe")
                            .foregroundStyle(.secondary)
                        TextField(L("onboarding.server.placeholder"), text: $viewModel.serverURLInput)
                            .keyboardType(.URL)
                            .autocorrectionDisabled()
                            .textInputAutocapitalization(.never)
                            .textContentType(.URL)
                            .onChange(of: viewModel.serverURLInput) {
                                if case .idle = viewModel.verifyPhase { } else {
                                    viewModel.resetVerification()
                                }
                            }
                    }
                    .padding()
                    .background(Color(.secondarySystemBackground), in: RoundedRectangle(cornerRadius: 12))

                    if let error = viewModel.serverURLError {
                        Label(error, systemImage: "exclamationmark.circle.fill")
                            .font(.footnote)
                            .foregroundStyle(.red)
                    }

                    if viewModel.isHTTP {
                        Label(L("onboarding.server.warning.http"), systemImage: "exclamationmark.shield.fill")
                            .font(.footnote)
                            .foregroundStyle(.orange)
                    }
                }

                // Help accordion
                DisclosureGroup(L("onboarding.token.help"), isExpanded: $showHelp) {
                    VStack(alignment: .leading, spacing: 6) {
                        Text(L("onboarding.token.help.steps"))
                            .font(.footnote)
                            .foregroundStyle(.secondary)
                    }
                    .padding(.top, 8)
                }
                .padding()
                .background(Color(.secondarySystemBackground), in: RoundedRectangle(cornerRadius: 12))

                // Token ID field
                VStack(alignment: .leading, spacing: 6) {
                    Label(L("onboarding.token.id.label"), systemImage: "key.fill")
                        .font(.subheadline.bold())

                    HStack {
                        Group {
                            if showTokenId {
                                TextField(L("onboarding.token.id.label"), text: $viewModel.tokenIdInput)
                            } else {
                                SecureField(L("onboarding.token.id.label"), text: $viewModel.tokenIdInput)
                            }
                        }
                        .autocorrectionDisabled()
                        .textInputAutocapitalization(.never)
                        .textContentType(.username)
                        .onChange(of: viewModel.tokenIdInput) {
                            if case .idle = viewModel.verifyPhase { } else {
                                viewModel.resetVerification()
                            }
                        }

                        if UIPasteboard.general.hasStrings {
                            Button {
                                viewModel.tokenIdInput = UIPasteboard.general.string ?? ""
                            } label: {
                                Image(systemName: "clipboard")
                                    .foregroundStyle(.secondary)
                            }
                            .accessibilityLabel(L("onboarding.token.paste"))
                        }

                        Button { showTokenId.toggle() } label: {
                            Image(systemName: showTokenId ? "eye.slash" : "eye")
                                .foregroundStyle(.secondary)
                        }
                    }
                    .padding()
                    .background(Color(.secondarySystemBackground), in: RoundedRectangle(cornerRadius: 12))
                }

                // Token Secret field
                VStack(alignment: .leading, spacing: 6) {
                    Label(L("onboarding.token.secret.label"), systemImage: "lock.fill")
                        .font(.subheadline.bold())

                    HStack {
                        Group {
                            if showTokenSecret {
                                TextField(L("onboarding.token.secret.label"), text: $viewModel.tokenSecretInput)
                            } else {
                                SecureField(L("onboarding.token.secret.label"), text: $viewModel.tokenSecretInput)
                            }
                        }
                        .autocorrectionDisabled()
                        .textInputAutocapitalization(.never)
                        .textContentType(.password)
                        .onChange(of: viewModel.tokenSecretInput) {
                            if case .idle = viewModel.verifyPhase { } else {
                                viewModel.resetVerification()
                            }
                        }

                        if UIPasteboard.general.hasStrings {
                            Button {
                                viewModel.tokenSecretInput = UIPasteboard.general.string ?? ""
                            } label: {
                                Image(systemName: "clipboard")
                                    .foregroundStyle(.secondary)
                            }
                            .accessibilityLabel(L("onboarding.token.paste"))
                        }

                        Button { showTokenSecret.toggle() } label: {
                            Image(systemName: showTokenSecret ? "eye.slash" : "eye")
                                .foregroundStyle(.secondary)
                        }
                    }
                    .padding()
                    .background(Color(.secondarySystemBackground), in: RoundedRectangle(cornerRadius: 12))
                }

                // Inline verification result / connect button
                if case .idle = viewModel.verifyPhase {
                    Button {
                        guard viewModel.validateServerURL() else { return }
                        verifyTask?.cancel()
                        verifyTask = Task { await viewModel.verifyAndSave() }
                    } label: {
                        Text(L("onboarding.token.verify"))
                            .font(.headline)
                            .frame(maxWidth: .infinity)
                            .padding()
                            .background(canConnect ? Color.accentColor : Color(.systemGray3))
                            .foregroundStyle(.white)
                            .clipShape(RoundedRectangle(cornerRadius: 14))
                    }
                    .disabled(!canConnect)
                    .padding(.top, 8)
                } else {
                    InlineVerifyPanel(viewModel: viewModel) {
                        // Reset so the user can edit and try again
                        verifyTask?.cancel()
                        viewModel.resetVerification()
                    }
                    .padding(.top, 8)
                }
            }
            .padding(32)
        }
        .navigationBarBackButtonHidden(false)
        .onDisappear {
            verifyTask?.cancel()
        }
        .onChange(of: viewModel.serverURLInput) { _, _ in
            // Clear name hint when URL changes so it re-auto-fills on next verify
        }
    }

    private var canConnect: Bool {
        !viewModel.serverURLInput.isEmpty &&
        !viewModel.tokenIdInput.isEmpty &&
        !viewModel.tokenSecretInput.isEmpty
    }
}

// MARK: - Inline Verify Panel

struct InlineVerifyPanel: View {
    @Bindable var viewModel: OnboardingViewModel
    let onReset: () -> Void

    var body: some View {
        VStack(spacing: 16) {
            // Phase rows
            VStack(alignment: .leading, spacing: 12) {
                VerifyPhaseRow(
                    label: L("onboarding.verify.phase.server"),
                    state: serverPhaseState
                )
                VerifyPhaseRow(
                    label: L("onboarding.verify.phase.token"),
                    state: tokenPhaseState
                )
            }
            .padding()
            .frame(maxWidth: .infinity, alignment: .leading)
            .background(Color(.secondarySystemBackground), in: RoundedRectangle(cornerRadius: 14))

            // Status message
            HStack(spacing: 10) {
                statusIcon
                Text(statusText)
                    .font(.subheadline)
                    .foregroundStyle(statusColor)
                    .multilineTextAlignment(.leading)
                Spacer()
            }

            // Error detail
            if let msg = errorMessage {
                Text(msg)
                    .font(.footnote)
                    .foregroundStyle(.red)
                    .frame(maxWidth: .infinity, alignment: .leading)
            }

            // Action button shown only on failure
            if case .failed = viewModel.verifyPhase {
                HStack(spacing: 12) {
                    Button {
                        verifyTask?.cancel()
                        verifyTask = Task { await viewModel.verifyAndSave() }
                    } label: {
                        Text(L("onboarding.verify.retry"))
                            .font(.headline)
                            .frame(maxWidth: .infinity)
                            .padding()
                            .background(Color.accentColor)
                            .foregroundStyle(.white)
                            .clipShape(RoundedRectangle(cornerRadius: 14))
                    }

                    Button {
                        onReset()
                    } label: {
                        Text(L("onboarding.verify.goback"))
                            .font(.subheadline)
                            .padding(.vertical, 12)
                            .padding(.horizontal, 16)
                            .background(Color(.secondarySystemBackground), in: RoundedRectangle(cornerRadius: 14))
                    }
                    .foregroundStyle(.secondary)
                }
            }
        }
    }

    // Retry task stored locally in the panel
    @State private var verifyTask: Task<Void, Never>? = nil

    // MARK: Derived state

    private var serverPhaseState: VerifyPhaseRow.RowState {
        switch viewModel.verifyPhase {
        case .idle:                            return .pending
        case .checkingServer:                  return .loading
        case .serverOK, .checkingToken, .done: return .success
        case .failed(let p, _):
            return p == "server" ? .failure : .success
        }
    }

    private var tokenPhaseState: VerifyPhaseRow.RowState {
        switch viewModel.verifyPhase {
        case .idle, .checkingServer, .serverOK: return .pending
        case .checkingToken:                    return .loading
        case .done:                             return .success
        case .failed(let p, _):
            return p == "token" ? .failure : .pending
        }
    }

    private var statusText: String {
        switch viewModel.verifyPhase {
        case .idle:             return L("onboarding.verify.ready")
        case .checkingServer:   return L("onboarding.verify.reaching")
        case .serverOK(let n): return String(format: L("onboarding.verify.found"), n)
        case .checkingToken:    return L("onboarding.verify.checking")
        case .done(let n, _):  return String(format: L("onboarding.verify.connected"), n)
        case .failed(let p, _):
            return p == "server" ? L("onboarding.verify.server.failed") : L("onboarding.verify.token.failed")
        }
    }

    private var statusColor: Color {
        switch viewModel.verifyPhase {
        case .done:   return .green
        case .failed: return .red
        default:      return .primary
        }
    }

    @ViewBuilder
    private var statusIcon: some View {
        switch viewModel.verifyPhase {
        case .checkingServer, .checkingToken:
            ProgressView().controlSize(.small)
        case .done:
            Image(systemName: "checkmark.circle.fill").foregroundStyle(.green)
        case .failed:
            Image(systemName: "xmark.circle.fill").foregroundStyle(.red)
        default:
            Image(systemName: "arrow.trianglehead.2.clockwise").foregroundStyle(.secondary)
        }
    }

    private var errorMessage: String? {
        guard case .failed(_, let error) = viewModel.verifyPhase else { return nil }
        return error.errorDescription
    }
}

// MARK: - Phase Row

struct VerifyPhaseRow: View {
    enum RowState { case pending, loading, success, failure }

    let label: String
    let state: RowState

    var body: some View {
        HStack(spacing: 12) {
            Group {
                switch state {
                case .pending:
                    Image(systemName: "circle")
                        .foregroundStyle(.tertiary)
                case .loading:
                    ProgressView()
                        .controlSize(.small)
                case .success:
                    Image(systemName: "checkmark.circle.fill")
                        .foregroundStyle(.green)
                case .failure:
                    Image(systemName: "xmark.circle.fill")
                        .foregroundStyle(.red)
                }
            }
            .frame(width: 20, height: 20)

            Text(label)
                .font(.subheadline)
                .foregroundStyle(state == .pending ? Color.secondary : Color.primary)
        }
    }
}

// MARK: - Step 3: Ready

struct ReadyStepView: View {
    let onComplete: () -> Void
    @State private var animate = false

    var body: some View {
        VStack(spacing: 32) {
            Spacer()

            VStack(spacing: 16) {
                Image(systemName: "checkmark.circle.fill")
                    .font(.system(size: 80))
                    .foregroundStyle(.green)
                    .scaleEffect(animate ? 1.0 : 0.5)
                    .opacity(animate ? 1.0 : 0.0)
                    .animation(.spring(response: 0.5, dampingFraction: 0.6), value: animate)

                VStack(spacing: 8) {
                    Text(L("onboarding.ready.title"))
                        .font(.largeTitle.bold())

                    Text(L("onboarding.ready.subtitle"))
                        .font(.body)
                        .foregroundStyle(.secondary)
                        .multilineTextAlignment(.center)
                }
            }

            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 16) {
                    FeatureCard(icon: "books.vertical.fill", title: L("onboarding.ready.feature.library"), description: L("onboarding.ready.feature.library.desc"))
                    FeatureCard(icon: "magnifyingglass", title: L("onboarding.ready.feature.search"), description: L("onboarding.ready.feature.search.desc"))
                    FeatureCard(icon: "pencil", title: L("onboarding.ready.feature.create"), description: L("onboarding.ready.feature.create.desc"))
                }
                .padding(.horizontal, 32)
            }

            Spacer()

            Button(action: onComplete) {
                Text(L("onboarding.ready.cta"))
                    .font(.headline)
                    .frame(maxWidth: .infinity)
                    .padding()
                    .background(Color.accentColor)
                    .foregroundStyle(.white)
                    .clipShape(RoundedRectangle(cornerRadius: 14))
            }
            .padding(.horizontal, 32)
            .padding(.bottom, 48)
        }
        .navigationBarBackButtonHidden(true)
        .onAppear { animate = true }
    }
}

struct FeatureCard: View {
    let icon: String
    let title: String
    let description: String

    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            Image(systemName: icon)
                .font(.title2)
                .foregroundStyle(Color.accentColor)
            Text(title)
                .font(.subheadline.bold())
            Text(description)
                .font(.footnote)
                .foregroundStyle(.secondary)
        }
        .padding()
        .frame(width: 160)
        .background(Color(.secondarySystemBackground), in: RoundedRectangle(cornerRadius: 14))
    }
}
