import SwiftUI
import Lottie

struct OnboardingView: View {
    let onStartMessaging: () -> Void

    @State private var currentPage = 0
    @State private var dragProgress: CGFloat = 0
    private let pages = OnboardingPages.all

    var body: some View {
        GeometryReader { geometry in
            ZStack {
                RosettaColors.authBackground.ignoresSafeArea()

                // Pager fills the entire screen — swipe works everywhere
                OnboardingPager(
                    currentIndex: $currentPage,
                    continuousProgress: $dragProgress,
                    count: pages.count
                ) { i in
                    OnboardingPageSlide(
                        page: pages[i],
                        screenWidth: geometry.size.width,
                        screenHeight: geometry.size.height
                    )
                }
                .ignoresSafeArea()

                // Dots positioned relative to content, button at bottom
                VStack(spacing: 0) {
                    // Match slide layout: top spacer + lottie + gap + text
                    let dotsTop = geometry.size.height * 0.12
                        + geometry.size.height * 0.22
                        + 32 + 150 + 20

                    Spacer().frame(height: dotsTop)

                    pageIndicator()

                    Spacer()

                    startButton()
                        .padding(.horizontal, 20)
                        .padding(.bottom, geometry.safeAreaInsets.bottom > 0 ? 20 : 36)
                }
            }
        }
        .statusBarHidden(false)
    }
}

// MARK: - Page Slide

private struct OnboardingPageSlide: View {
    let page: OnboardingPage
    let screenWidth: CGFloat
    let screenHeight: CGFloat

    @State private var isPlaying = false

    var body: some View {
        VStack(spacing: 0) {
            Spacer().frame(height: screenHeight * 0.12)

            LottieView(
                animationName: page.animationName,
                loopMode: .playOnce,
                animationSpeed: 1.5,
                isPlaying: isPlaying
            )
            .frame(width: screenWidth * 0.42, height: screenHeight * 0.22)

            Spacer().frame(height: 32)

            textBlock()
                .frame(height: 150)

            Spacer()
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(RosettaColors.authBackground)
        .onAppear { isPlaying = true }
        .onDisappear { isPlaying = false }
        .accessibilityElement(children: .contain)
        .accessibilityLabel("\(page.title). \(page.description)")
    }

    private func textBlock() -> some View {
        VStack(spacing: 14) {
            Text(page.title)
                .font(.system(size: 32, weight: .bold))
                .foregroundStyle(.white)

            highlightedText()
        }
        .frame(width: screenWidth)
        .multilineTextAlignment(.center)
    }

    private func highlightedText() -> some View {
        let lines = page.description.components(separatedBy: "\n")
        return VStack(spacing: 4) {
            ForEach(lines, id: \.self) { line in
                highlightedLine(line)
            }
        }
    }

    private func highlightedLine(_ line: String) -> some View {
        var attributed = AttributedString(line)
        for word in page.highlightedWords {
            if let range = attributed.range(of: word, options: .caseInsensitive) {
                attributed[range].foregroundColor = Color.white
                attributed[range].font = .system(size: 17, weight: .bold)
            }
        }
        return Text(attributed)
            .font(.system(size: 17))
            .foregroundStyle(Color.white)
    }
}

// MARK: - Bottom Controls

private extension OnboardingView {
    func pageIndicator() -> some View {
        let dotSize: CGFloat = 7
        let spacing: CGFloat = 15

        return HStack(spacing: spacing - dotSize) {
            ForEach(0..<pages.count, id: \.self) { i in
                Circle()
                    .fill(dotColor(for: i))
                    .frame(width: dotSize, height: dotSize)
            }
        }
        .frame(height: dotSize + 4)
        .accessibilityLabel("Page \(currentPage + 2) of \(pages.count)")
    }

    /// Only the nearest dot is active — no blending between two dots.
    func dotColor(for index: Int) -> Color {
        let nearest = Int(dragProgress.rounded())
        return index == nearest
            ? RosettaColors.primaryBlue
            : Color.white.opacity(0.3)
    }

    func startButton() -> some View {
        Button(action: onStartMessaging) {
            Text("Start Messaging")
                .font(.system(size: 17, weight: .semibold))
                .foregroundStyle(.white)
                .frame(maxWidth: .infinity)
                .frame(height: 54)
        }
        .buttonStyle(RosettaPrimaryButtonStyle())
        .shine()
        .accessibilityHint("Opens account setup")
    }
}

// MARK: - Preview

#Preview {
    OnboardingView(onStartMessaging: {})
}
