import SwiftUI

struct OnboardingInfoView: View {
    struct Configuration {
        let title: LocalizedStringKey
        let subtitle: LocalizedStringKey
        let primaryActionTitle: LocalizedStringKey
        let primaryActionIcon: String
        let secondaryActionTitle: LocalizedStringKey?
        let secondaryActionIcon: String?
        let imageNames: [String]
    }

    @State private var carouselStep = 0
    private let configuration: Configuration
    private let onPrimaryAction: () -> Void
    private let onSecondaryAction: () -> Void

    private let timer = Timer.publish(every: 8, on: .main, in: .common).autoconnect()
    private let animationDuration = 0.8

    private var loopingImages: [String] {
        guard let first = configuration.imageNames.first else { return [] }
        return configuration.imageNames + [first]
    }

    init(configuration: Configuration, onPrimaryAction: @escaping () -> Void, onSecondaryAction: @escaping () -> Void = {}) {
        self.configuration = configuration
        self.onPrimaryAction = onPrimaryAction
        self.onSecondaryAction = onSecondaryAction
    }

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

            if !loopingImages.isEmpty {
                OnboardingCarouselView(images: loopingImages, step: carouselStep)
                    .frame(minHeight: 80, maxHeight: 220)
                    .padding(.horizontal, 0)
            }

            VStack(spacing: 12) {
                Text(configuration.title)
                    .font(.title2.weight(.semibold))
                    .multilineTextAlignment(.center)

                Text(configuration.subtitle)
                    .font(.body)
                    .foregroundStyle(Color.secondary)
                    .multilineTextAlignment(.center)
                    .frame(minHeight: 72)
                    .padding(.horizontal, 12)
            }
            .padding(.horizontal, 24)

            Spacer()

            VStack(spacing: 12) {
                Spacer()
                Button(action: onPrimaryAction) {
                    Label(configuration.primaryActionTitle, systemImage: configuration.primaryActionIcon)
                        .frame(maxWidth: .infinity)
                }
                .accessibilityIdentifier("create-component-button")
                .buttonStyle(.borderedProminent)
                .controlSize(.large)

                if let secondaryTitle = configuration.secondaryActionTitle,
                   let secondaryIcon = configuration.secondaryActionIcon {
                    Button(action: onSecondaryAction) {
                        Label(secondaryTitle, systemImage: secondaryIcon)
                            .frame(maxWidth: .infinity)
                    }
                    .accessibilityIdentifier("select-component-button")
                    .buttonStyle(.bordered)
                    .tint(.accentColor)
                    .controlSize(.large)
                }
            }
            .padding(.horizontal, 24)
            .frame(minHeight: 140)
        }
        .padding(.vertical, 24)
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color(.systemGroupedBackground))
        .onAppear(perform: resetState)
        .onReceive(timer) { _ in advanceCarousel() }
    }

    private func resetState() {
        carouselStep = 0
    }

    private func advanceCarousel() {
        guard configuration.imageNames.count > 1 else { return }
        let next = carouselStep + 1

        withAnimation(.easeInOut(duration: animationDuration)) {
            carouselStep = next
        }

        if next == configuration.imageNames.count {
            DispatchQueue.main.asyncAfter(deadline: .now() + animationDuration) {
                withAnimation(.none) {
                    carouselStep = 0
                }
            }
        }
    }
}

#Preview {
    OnboardingInfoView(
        configuration: .loads(),
        onPrimaryAction: {},
        onSecondaryAction: {}
    )
}

extension OnboardingInfoView.Configuration {
    static func loads() -> Self {
        Self(
            title: LocalizedStringKey("loads.onboarding.title"),
            subtitle: LocalizedStringKey("loads.onboarding.subtitle"),
            primaryActionTitle: LocalizedStringKey("loads.overview.empty.create"),
            primaryActionIcon: "plus",
            secondaryActionTitle: LocalizedStringKey("loads.overview.empty.library"),
            secondaryActionIcon: "books.vertical",
            imageNames: [
                "coffee-onboarding",
                "router-onboarding",
                "charger-onboarding"
            ]
        )
    }

    static func battery() -> Self {
        Self(
            title: LocalizedStringKey("battery.onboarding.title"),
            subtitle: LocalizedStringKey("battery.onboarding.subtitle"),
            primaryActionTitle: LocalizedStringKey("battery.overview.empty.create"),
            primaryActionIcon: "plus",
            secondaryActionTitle: nil,
            secondaryActionIcon: nil,
            imageNames: [
                "battery-onboarding"
            ]
        )
    }

    static func charger() -> Self {
        Self(
            title: LocalizedStringKey("chargers.onboarding.title"),
            subtitle: LocalizedStringKey("chargers.onboarding.subtitle"),
            primaryActionTitle: LocalizedStringKey("chargers.onboarding.primary"),
            primaryActionIcon: "plus",
            secondaryActionTitle: nil,
            secondaryActionIcon: nil,
            imageNames: [
                "charger-onboarding"
            ]
        )
    }
}
