//
//  OnboardingContainerView.swift
//  lichunWebsocket
//
//  Main container for the onboarding flow
//

import SwiftUI

struct OnboardingContainerView: View {
    @EnvironmentObject var appViewModel: AppViewModel
    @EnvironmentObject var webSocketService: WebSocketService
    @State private var currentStep = 0
    @State private var name = ""
    @State private var age = 18
    @State private var sex = "Male"
    @State private var showCharacterConfirmation = false

    var body: some View {
        ZStack {
            // Step-based content with smooth, cozy transitions
            Group {
                switch currentStep {
                case 0:
                    // Step 1: Welcome screen
                    OnboardingStep1_WelcomeView {
                        advanceToStep(1)
                    }
                    .transition(.asymmetric(
                        insertion: .scale(scale: 0.95, anchor: .center).combined(with: .opacity),
                        removal: .scale(scale: 1.05, anchor: .center).combined(with: .opacity)
                    ))

                case 1:
                    // Step 2: Character creation
                    CharacterCreationFlow(
                        name: $name,
                        age: $age,
                        sex: $sex,
                        showConfirmation: $showCharacterConfirmation,
                        onComplete: {
                            advanceToStep(2)
                        }
                    )
                    .transition(.asymmetric(
                        insertion: .scale(scale: 0.95, anchor: .center).combined(with: .opacity),
                        removal: .scale(scale: 1.05, anchor: .center).combined(with: .opacity)
                    ))

                case 2:
                    // Step 3: UI Tour
                    OnboardingStep3_UITourView {
                        advanceToStep(3)
                    }
                    .transition(.asymmetric(
                        insertion: .scale(scale: 0.95, anchor: .center).combined(with: .opacity),
                        removal: .scale(scale: 1.05, anchor: .center).combined(with: .opacity)
                    ))

                case 3:
                    // Step 4: Guided actions
                    OnboardingStep4_GuidedActionsView {
                        advanceToStep(4)
                    }
                    .transition(.asymmetric(
                        insertion: .scale(scale: 0.95, anchor: .center).combined(with: .opacity),
                        removal: .scale(scale: 1.05, anchor: .center).combined(with: .opacity)
                    ))

                case 4:
                    // Step 5: Completion with celebration entrance
                    OnboardingStep5_CompletionView {
                        // Onboarding complete - appViewModel.onboardingComplete is already set
                        // The parent view (ContentView) will handle showing the main game
                    }
                    .transition(.asymmetric(
                        insertion: .scale(scale: 0.9, anchor: .center).combined(with: .opacity),
                        removal: .scale(scale: 1.1, anchor: .center).combined(with: .opacity)
                    ))

                default:
                    EmptyView()
                }
            }
        }
        .onAppear {
            // Initialize if needed
            appViewModel.onboardingStep = currentStep
        }
    }

    // MARK: - Helper Functions
    private func advanceToStep(_ newStep: Int) {
        // Haptic feedback for progression
        let impact = UIImpactFeedbackGenerator(style: .light)
        impact.impactOccurred()

        withAnimation(.spring(response: 0.6, dampingFraction: 0.75)) {
            currentStep = newStep
            appViewModel.onboardingStep = newStep

            // Send tutorial step update to server
            webSocketService.sendMessage(message: WebSocketCommands.tutorialStepComplete(step: newStep))
        }
    }
}

// MARK: - Character Creation Flow Wrapper
struct CharacterCreationFlow: View {
    @EnvironmentObject var webSocketService: WebSocketService
    @Binding var name: String
    @Binding var age: Int
    @Binding var sex: String
    @Binding var showConfirmation: Bool
    let onComplete: () -> Void

    /// Set true once the user submits the confirmation screen; while true we wait
    /// for the server to confirm the character before advancing.
    @State private var isBuildingWorld = false
    /// Guards against advancing more than once (state signal + timeout fallback).
    @State private var hasAdvanced = false

    /// The server has confirmed a created character once it has a real id and is
    /// no longer in the "creating" placeholder state.
    private var characterIsReady: Bool {
        !webSocketService.person.id.isEmpty && webSocketService.person.status != "creating"
    }

    var body: some View {
        ZStack {
            if !showConfirmation {
                // Character setup form
                CharacterSetupView(
                    showConfirmation: $showConfirmation,
                    name: $name,
                    age: $age,
                    sex: $sex
                )
            } else {
                // Confirmation view - using the existing one
                ConfirmationView(
                    name: name,
                    age: age,
                    sex: sex
                )

                // Brief loading overlay while the server builds the world.
                if isBuildingWorld {
                    BuildingWorldOverlay()
                        .transition(.opacity)
                }
            }
        }
        .transition(.opacity)
        // Drive the handoff from real server state instead of a fixed timer.
        // ConfirmationView sends "characterSetup" when the user taps "Start";
        // we begin waiting and advance once person state confirms the character.
        .onChange(of: showConfirmation) { confirmed in
            if confirmed {
                beginWaitingForCharacter()
            }
        }
        // Advance as soon as the server confirms the character exists.
        .onChange(of: characterIsReady) { ready in
            if ready { advance() }
        }
        .onAppear {
            // Handles the case where the confirmation screen is already showing
            // (e.g. returning to this step) so we still wait on real state.
            if showConfirmation {
                beginWaitingForCharacter()
            }
        }
    }

    private func beginWaitingForCharacter() {
        guard !hasAdvanced else { return }
        withAnimation(.easeInOut(duration: 0.25)) {
            isBuildingWorld = true
        }

        // If the character is somehow already ready, advance immediately.
        if characterIsReady {
            advance()
            return
        }

        // Timeout fallback: never hang forever on a slow/failed connection.
        DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) {
            advance()
        }
    }

    private func advance() {
        guard !hasAdvanced else { return }
        hasAdvanced = true
        onComplete()
    }
}

// MARK: - Building World Loading Overlay
private struct BuildingWorldOverlay: View {
    var body: some View {
        ZStack {
            Color.black.opacity(0.35)
                .edgesIgnoringSafeArea(.all)

            VStack(spacing: AppSpacing.md) {
                ProgressView()
                    .progressViewStyle(.circular)
                    .scaleEffect(1.4)
                    .tint(.white)

                Text("Building your world...")
                    .font(.appHeadline)
                    .fontWeight(.semibold)
                    .foregroundColor(.white)
            }
            .padding(AppSpacing.xl)
            .background(
                RoundedRectangle(cornerRadius: AppSpacing.cornerRadius)
                    .fill(Color.black.opacity(0.55))
            )
        }
    }
}

// MARK: - Preview
#if DEBUG
struct OnboardingContainerView_Previews: PreviewProvider {
    static var previews: some View {
        OnboardingContainerView()
            .environmentObject(AppViewModel())
            .environmentObject(WebSocketService(
                urlSession: URLSession.shared,
                delegateQueue: OperationQueue()
            ))
    }
}
#endif
