import SwiftUI

enum LoadingAnimationType {
    case keys
    case drums
    case lyrics
    case harmonize
}

/// Animated loading indicator with animated icon and shimmering text
struct LoadingIndicator: View {
    let message: String
    let animationType: LoadingAnimationType
    let accentColor: Color

    @State private var animationPhase: Int = 0
    @State private var shimmerOffset: CGFloat = -200

    init(message: String = "Crafting melodies...", animationType: LoadingAnimationType = .keys) {
        self.message = message
        self.animationType = animationType
        // Set accent color based on animation type
        switch animationType {
        case .keys:
            self.accentColor = Constants.Colors.Accent.purple
        case .drums:
            self.accentColor = Constants.Colors.Accent.brand
        case .lyrics:
            self.accentColor = Constants.Colors.Accent.orange
        case .harmonize:
            self.accentColor = Constants.Colors.Background.Fog.dense
        }
    }

    var body: some View {
        HStack(spacing: 4) {
            // Animated Icon
            switch animationType {
            case .keys:
                keysIcon
            case .drums:
                drumsIcon
            case .lyrics:
                lyricsIcon
            case .harmonize:
                harmonizeIcon
            }

            // Shimmering Text
            Text(message)
                .font(Constants.Typography.smallTitle)
                .tracking(0.28)
                .foregroundColor(accentColor)
                .overlay(
                    GeometryReader { geometry in
                        Rectangle()
                            .fill(
                                LinearGradient(
                                    colors: [
                                        Color.clear,
                                        Color.white.opacity(0.8),
                                        Color.clear
                                    ],
                                    startPoint: .leading,
                                    endPoint: .trailing
                                )
                            )
                            .frame(width: geometry.size.width * 1.2)
                            .offset(x: shimmerOffset)
                    }
                )
                .mask(
                    Text(message)
                        .font(Constants.Typography.smallTitle)
                        .tracking(0.28)
                )
        }
        .onAppear {
            startAnimation()
            startShimmer()
        }
    }

    private var keysIcon: some View {
        ZStack {
            // Key 1 - White when active, purple 30% when not
            Rectangle()
                .fill(animationPhase == 0 ? Color.white : accentColor)
                .frame(width: 4, height: 16)
                .cornerRadius(1)
                .offset(x: -6)
                .opacity(animationPhase == 0 ? 1.0 : 0.3)

            // Key 2 - White when active, purple 30% when not
            Rectangle()
                .fill(animationPhase == 1 ? Color.white : accentColor)
                .frame(width: 4, height: 16)
                .cornerRadius(1)
                .offset(x: 0)
                .opacity(animationPhase == 1 ? 1.0 : 0.3)

            // Key 3 - White when active, purple 30% when not
            Rectangle()
                .fill(animationPhase == 2 ? Color.white : accentColor)
                .frame(width: 4, height: 16)
                .cornerRadius(1)
                .offset(x: 6)
                .opacity(animationPhase == 2 ? 1.0 : 0.3)
        }
        .frame(width: 24, height: 24)
    }

    private var drumsIcon: some View {
        ZStack {
            // Top-left drum pad (position 0)
            RoundedRectangle(cornerRadius: 1)
                .fill(animationPhase == 0 ? Color.white : accentColor)
                .frame(width: 7, height: 7)
                .offset(x: -4.5, y: -4.5)
                .opacity(animationPhase == 0 ? 1.0 : 0.3)

            // Top-right drum pad (position 1)
            RoundedRectangle(cornerRadius: 1)
                .fill(animationPhase == 1 ? Color.white : accentColor)
                .frame(width: 7, height: 7)
                .offset(x: 4.5, y: -4.5)
                .opacity(animationPhase == 1 ? 1.0 : 0.3)

            // Bottom-left drum pad (position 2)
            RoundedRectangle(cornerRadius: 1)
                .fill(animationPhase == 2 ? Color.white : accentColor)
                .frame(width: 7, height: 7)
                .offset(x: -4.5, y: 4.5)
                .opacity(animationPhase == 2 ? 1.0 : 0.3)

            // Bottom-right drum pad (position 3)
            RoundedRectangle(cornerRadius: 1)
                .fill(animationPhase == 3 ? Color.white : accentColor)
                .frame(width: 7, height: 7)
                .offset(x: 4.5, y: 4.5)
                .opacity(animationPhase == 3 ? 1.0 : 0.3)
        }
        .frame(width: 24, height: 24)
    }

    private var lyricsIcon: some View {
        ZStack {
            // Line 1 (top) - White when active, orange 30% when not
            RoundedRectangle(cornerRadius: 0.5)
                .fill(animationPhase == 0 ? Color.white : accentColor)
                .frame(width: 10, height: 2)
                .offset(x: -2, y: -6)
                .opacity(animationPhase == 0 ? 1.0 : 0.3)

            // Line 2 - White when active, orange 30% when not
            RoundedRectangle(cornerRadius: 0.5)
                .fill(animationPhase == 1 ? Color.white : accentColor)
                .frame(width: 12, height: 2)
                .offset(x: -1, y: -2)
                .opacity(animationPhase == 1 ? 1.0 : 0.3)

            // Line 3 - White when active, orange 30% when not
            RoundedRectangle(cornerRadius: 0.5)
                .fill(animationPhase == 2 ? Color.white : accentColor)
                .frame(width: 8, height: 2)
                .offset(x: -3, y: 2)
                .opacity(animationPhase == 2 ? 1.0 : 0.3)

            // Line 4 (bottom) - White when active, orange 30% when not
            RoundedRectangle(cornerRadius: 0.5)
                .fill(animationPhase == 3 ? Color.white : accentColor)
                .frame(width: 14, height: 2)
                .offset(x: 0, y: 6)
                .opacity(animationPhase == 3 ? 1.0 : 0.3)
        }
        .frame(width: 24, height: 24)
    }

    private var harmonizeIcon: some View {
        HStack(spacing: 2) {
            // Bar 1 - animated height
            RoundedRectangle(cornerRadius: 1)
                .fill(Color.white)
                .frame(width: 2, height: barHeight(for: 0))
                .opacity(barOpacity(for: 0))

            // Bar 2 - animated height
            RoundedRectangle(cornerRadius: 1)
                .fill(Color.white)
                .frame(width: 2, height: barHeight(for: 1))
                .opacity(barOpacity(for: 1))

            // Bar 3 - animated height
            RoundedRectangle(cornerRadius: 1)
                .fill(Color.white)
                .frame(width: 2, height: barHeight(for: 2))
                .opacity(barOpacity(for: 2))

            // Bar 4 - animated height
            RoundedRectangle(cornerRadius: 1)
                .fill(Color.white)
                .frame(width: 2, height: barHeight(for: 3))
                .opacity(barOpacity(for: 3))

            // Bar 5 - animated height
            RoundedRectangle(cornerRadius: 1)
                .fill(Color.white)
                .frame(width: 2, height: barHeight(for: 4))
                .opacity(barOpacity(for: 4))
        }
        .frame(width: 24, height: 24)
    }

    private func barHeight(for bar: Int) -> CGFloat {
        // Create a wave pattern that moves across the bars
        let phase = (animationPhase + bar) % 5

        switch phase {
        case 0: return 4.0  // shortest
        case 1: return 8.0
        case 2: return 16.0 // tallest
        case 3: return 12.0
        case 4: return 6.0
        default: return 4.0
        }
    }

    private func barOpacity(for bar: Int) -> Double {
        // Bars near the peak are brighter
        let phase = (animationPhase + bar) % 5

        switch phase {
        case 2: return 1.0   // peak - full brightness
        case 1, 3: return 0.7 // near peak
        default: return 0.4   // far from peak
        }
    }

    private func startAnimation() {
        let maxPhases: Int
        switch animationType {
        case .keys:
            maxPhases = 3
        case .drums:
            maxPhases = 4
        case .lyrics:
            maxPhases = 4
        case .harmonize:
            maxPhases = 5
        }
        Timer.scheduledTimer(withTimeInterval: 0.4, repeats: true) { _ in
            withAnimation(.easeInOut(duration: 0.3)) {
                animationPhase = (animationPhase + 1) % maxPhases
            }
        }
    }

    private func startShimmer() {
        withAnimation(.linear(duration: 1.0).repeatForever(autoreverses: false)) {
            shimmerOffset = 100
        }
    }
}

#Preview {
    VStack(spacing: 20) {
        LoadingIndicator(message: "Crafting melodies...", animationType: .keys)

        LoadingIndicator(message: "Drumming up...", animationType: .drums)

        LoadingIndicator(message: "Writing lyrics...", animationType: .lyrics)

        LoadingIndicator(message: "Harmonizing...", animationType: .harmonize)
    }
    .padding()
    .background(Constants.Colors.Background.primary)
}
