//
//  AddMoodHeaderView.swift
//  Reflect
//
//  Created by Trey Tartt on 1/5/22.
//

import Foundation
import SwiftUI
import SwiftData

struct AddMoodHeaderView: View {
    @AppStorage(UserDefaultsStore.Keys.theme.rawValue, store: GroupUserDefaults.groupDefaults) private var theme: Theme = .system
    @AppStorage(UserDefaultsStore.Keys.moodImages.rawValue, store: GroupUserDefaults.groupDefaults) private var imagePack: MoodImages = .FontAwesome
    @AppStorage(UserDefaultsStore.Keys.moodTint.rawValue, store: GroupUserDefaults.groupDefaults) private var moodTint: MoodTints = .Default
    @AppStorage(UserDefaultsStore.Keys.votingLayoutStyle.rawValue, store: GroupUserDefaults.groupDefaults) private var votingLayoutStyle: Int = 0
    @AppStorage(UserDefaultsStore.Keys.celebrationAnimation.rawValue, store: GroupUserDefaults.groupDefaults) private var celebrationAnimationIndex: Int = 0
    @AppStorage(UserDefaultsStore.Keys.hapticFeedbackEnabled.rawValue, store: GroupUserDefaults.groupDefaults) private var hapticFeedbackEnabled = true

    private var textColor: Color { theme.currentTheme.labelColor }

    @State var onboardingData = OnboardingDataDataManager.shared.savedOnboardingData

    // Celebration animation state
    @State private var showCelebration = false
    @State private var celebrationMood: Mood = .great
    @State private var celebrationAnimation: CelebrationAnimationType = .pulseWave
    @State private var celebrationDate: Date = Date()

    let addItemHeaderClosure: ((Mood, Date) -> Void)

    init(addItemHeaderClosure: @escaping ((Mood, Date) -> Void)) {
        self.addItemHeaderClosure = addItemHeaderClosure
    }

    private var layoutStyle: VotingLayoutStyle {
        VotingLayoutStyle(rawValue: votingLayoutStyle) ?? .horizontal
    }

    var body: some View {
        ZStack {
            // Force re-render when image pack changes
            Text(String(imagePack.rawValue))
                .hidden()

            VStack(spacing: 16) {
                Text(ShowBasedOnVoteLogics.getVotingTitle(onboardingData: onboardingData))
                    .font(.title2.bold())
                    .foregroundColor(textColor)
                    .padding(.top)

                votingLayoutContent
                    .padding(.bottom)
            }
            .padding(.horizontal)
            .opacity(showCelebration ? 0 : 1)

            // Celebration animation overlay
            if showCelebration {
                CelebrationOverlayView(
                    animationType: celebrationAnimation,
                    mood: celebrationMood
                ) {
                    // Animation complete - save the mood (parent will remove this view)
                    addItemHeaderClosure(celebrationMood, celebrationDate)
                }
            }
        }
        .background(theme.currentTheme.secondaryBGColor)
        .cornerRadius(Constants.viewsCornerRaidus, corners: [.topLeft, .topRight, .bottomLeft, .bottomRight])
        .fixedSize(horizontal: false, vertical: true)
        .accessibilityIdentifier(AccessibilityID.DayView.moodHeader)
    }

    @ViewBuilder
    private var votingLayoutContent: some View {
        switch layoutStyle {
        case .horizontal:
            HorizontalVotingView(moodTint: moodTint, onMoodSelected: addItem)
        case .cards:
            CardVotingView(moodTint: moodTint, onMoodSelected: addItem)
        case .stacked:
            StackedVotingView(moodTint: moodTint, onMoodSelected: addItem)
        case .aura:
            AuraVotingView(moodTint: moodTint, onMoodSelected: addItem)
        case .orbit:
            OrbitVotingView(moodTint: moodTint, onMoodSelected: addItem)
        case .neon:
            NeonVotingView(moodTint: moodTint, onMoodSelected: addItem)
        }
    }

    private func addItem(withMood mood: Mood) {
        // Store mood, date, and use saved animation preference
        celebrationMood = mood
        celebrationDate = ShowBasedOnVoteLogics.getCurrentVotingDate(onboardingData: onboardingData)
        celebrationAnimation = CelebrationAnimationType.fromIndex(celebrationAnimationIndex)

        // Play haptic feedback matching the selected animation
        if hapticFeedbackEnabled {
            HapticFeedbackManager.shared.play(for: celebrationAnimation)
        }

        // Show celebration - mood will be saved when animation completes
        withAnimation(.easeInOut(duration: 0.3)) {
            showCelebration = true
        }
    }
}

// MARK: - Layout 1: Horizontal (Polished version of current)
struct HorizontalVotingView: View {
    let moodTint: MoodTints
    let onMoodSelected: (Mood) -> Void

    var body: some View {
        HStack(spacing: 8) {
            ForEach(Mood.allValues) { mood in
                Button(action: { onMoodSelected(mood) }) {
                    mood.icon
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: 55, height: 55)
                        .foregroundColor(moodTint.color(forMood: mood))
                }
                .buttonStyle(MoodButtonStyle())
                .frame(maxWidth: .infinity)
                .accessibilityIdentifier(AccessibilityID.MoodButton.id(for: mood.widgetDisplayName))
                .accessibilityLabel(mood.strValue)
                .accessibilityHint(String(localized: "Select this mood"))
            }
        }
        .accessibilityElement(children: .contain)
        .accessibilityLabel(String(localized: "Mood selection"))
    }
}

// MARK: - Layout 2: Cards Grid
struct CardVotingView: View {
    let moodTint: MoodTints
    let onMoodSelected: (Mood) -> Void

    var body: some View {
        GeometryReader { geo in
            let spacing: CGFloat = 12
            let cardWidth = (geo.size.width - spacing * 2) / 3
            // Offset to center bottom row cards between top row cards
            // Each bottom card should be centered between two top cards
            let bottomOffset = (cardWidth + spacing) / 2

            VStack(spacing: spacing) {
                // Top row: Great, Good, Average
                HStack(spacing: spacing) {
                    ForEach(Array(Mood.allValues.prefix(3))) { mood in
                        cardButton(for: mood, width: cardWidth)
                    }
                }

                // Bottom row: Bad, Horrible - centered between top row items
                HStack(spacing: spacing) {
                    ForEach(Array(Mood.allValues.suffix(2))) { mood in
                        cardButton(for: mood, width: cardWidth)
                    }
                }
                .padding(.leading, bottomOffset)
                .padding(.trailing, bottomOffset)
            }
        }
        .frame(height: 190)
        .accessibilityElement(children: .contain)
        .accessibilityLabel(String(localized: "Mood selection"))
    }

    private func cardButton(for mood: Mood, width: CGFloat) -> some View {
        Button(action: { onMoodSelected(mood) }) {
            mood.icon
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 40, height: 40)
                .foregroundColor(moodTint.color(forMood: mood))
                .frame(width: width)
                .padding(.vertical, 20)
                .background(
                    RoundedRectangle(cornerRadius: 12)
                        .fill(moodTint.color(forMood: mood).opacity(0.15))
                )
                .overlay(
                    RoundedRectangle(cornerRadius: 12)
                        .stroke(moodTint.color(forMood: mood).opacity(0.3), lineWidth: 1)
                )
        }
        .buttonStyle(CardButtonStyle())
        .accessibilityIdentifier(AccessibilityID.MoodButton.id(for: mood.widgetDisplayName))
        .accessibilityLabel(mood.strValue)
        .accessibilityHint(String(localized: "Select this mood"))
    }
}

// MARK: - Layout 3: Stacked Full-width
struct StackedVotingView: View {
    let moodTint: MoodTints
    let onMoodSelected: (Mood) -> Void

    var body: some View {
        VStack(spacing: 10) {
            ForEach(Mood.allValues) { mood in
                Button(action: { onMoodSelected(mood) }) {
                    HStack(spacing: 16) {
                        mood.icon
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                            .frame(width: 36, height: 36)
                            .foregroundColor(moodTint.color(forMood: mood))

                        Text(mood.strValue)
                            .font(.body.weight(.semibold))
                            .foregroundColor(moodTint.color(forMood: mood))

                        Spacer()

                        Image(systemName: "chevron.right")
                            .font(.caption.weight(.semibold))
                            .foregroundColor(moodTint.color(forMood: mood).opacity(0.5))
                    }
                    .padding(.horizontal, 16)
                    .padding(.vertical, 14)
                    .background(
                        RoundedRectangle(cornerRadius: 12)
                            .fill(moodTint.color(forMood: mood).opacity(0.12))
                    )
                }
                .buttonStyle(CardButtonStyle())
                .accessibilityIdentifier(AccessibilityID.MoodButton.id(for: mood.widgetDisplayName))
                .accessibilityLabel(mood.strValue)
                .accessibilityHint(String(localized: "Select this mood"))
            }
        }
        .accessibilityElement(children: .contain)
        .accessibilityLabel(String(localized: "Mood selection"))
    }
}

// MARK: - Layout 5: Aura (Atmospheric glowing orbs)
struct AuraVotingView: View {
    let moodTint: MoodTints
    let onMoodSelected: (Mood) -> Void
    @Environment(\.colorScheme) private var colorScheme

    var body: some View {
        VStack(spacing: 24) {
            // Top row: 3 moods (Horrible, Bad, Average)
            HStack(spacing: 16) {
                ForEach(Array(Mood.allValues.prefix(3))) { mood in
                    auraButton(for: mood)
                }
            }

            // Bottom row: 2 moods (Good, Great) - centered
            HStack(spacing: 24) {
                ForEach(Array(Mood.allValues.suffix(2))) { mood in
                    auraButton(for: mood)
                }
            }
        }
        .padding(.vertical, 8)
    }

    private func auraButton(for mood: Mood) -> some View {
        let color = moodTint.color(forMood: mood)

        return Button(action: { onMoodSelected(mood) }) {
            // Glowing orb
            ZStack {
                // Outer atmospheric glow
                Circle()
                    .fill(
                        RadialGradient(
                            colors: [
                                color.opacity(0.5),
                                color.opacity(0.2),
                                Color.clear
                            ],
                            center: .center,
                            startRadius: 0,
                            endRadius: 45
                        )
                    )
                    .frame(width: 90, height: 90)

                // Middle glow ring
                Circle()
                    .fill(
                        RadialGradient(
                            colors: [
                                color.opacity(0.8),
                                color.opacity(0.4)
                            ],
                            center: .center,
                            startRadius: 10,
                            endRadius: 30
                        )
                    )
                    .frame(width: 60, height: 60)

                // Inner solid core
                Circle()
                    .fill(color)
                    .frame(width: 48, height: 48)
                    .shadow(color: color.opacity(0.8), radius: 12, x: 0, y: 0)

                // Icon
                mood.icon
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 26, height: 26)
                    .foregroundColor(.white)
            }
        }
        .buttonStyle(AuraButtonStyle(color: color))
        .accessibilityIdentifier(AccessibilityID.MoodButton.id(for: mood.widgetDisplayName))
        .accessibilityLabel(mood.strValue)
        .accessibilityHint(String(localized: "Select this mood"))
    }
}

// MARK: - Layout 6: Orbit (Celestial circular arrangement)
struct OrbitVotingView: View {
    let moodTint: MoodTints
    let onMoodSelected: (Mood) -> Void
    @Environment(\.colorScheme) private var colorScheme

    @State private var centerPulse: CGFloat = 1.0

    private var isDark: Bool { colorScheme == .dark }

    var body: some View {
        GeometryReader { geo in
            let size = min(geo.size.width, geo.size.height)
            let centerX = geo.size.width / 2
            let centerY = size / 2
            let orbitRadius = size * 0.38

            ZStack {
                orbitalRing(radius: orbitRadius, centerX: centerX, centerY: centerY)
                centerCore(centerX: centerX, centerY: centerY)
                moodPlanets(radius: orbitRadius, centerX: centerX, centerY: centerY)
            }
        }
        .frame(height: 260)
        .onAppear {
            withAnimation(.easeInOut(duration: 2.0).repeatForever(autoreverses: true)) {
                centerPulse = 1.1
            }
        }
        .onDisappear {
            centerPulse = 1.0
        }
        .accessibilityElement(children: .contain)
        .accessibilityLabel(String(localized: "Mood selection"))
    }

    private func orbitalRing(radius: CGFloat, centerX: CGFloat, centerY: CGFloat) -> some View {
        let ringColor = isDark ? Color.white : Color.black
        return Circle()
            .stroke(ringColor.opacity(0.08), lineWidth: 1)
            .frame(width: radius * 2, height: radius * 2)
            .position(x: centerX, y: centerY)
    }

    private func centerCore(centerX: CGFloat, centerY: CGFloat) -> some View {
        let glowOpacity = isDark ? 0.15 : 0.3
        let coreOpacity = isDark ? 0.9 : 1.0

        return ZStack {
            Circle()
                .fill(Color.white.opacity(glowOpacity))
                .frame(width: 80, height: 80)
                .scaleEffect(centerPulse)

            Circle()
                .fill(Color.white.opacity(coreOpacity))
                .frame(width: 36, height: 36)
                .shadow(color: .white.opacity(0.5), radius: 10)
        }
        .position(x: centerX, y: centerY)
    }

    private func moodPlanets(radius: CGFloat, centerX: CGFloat, centerY: CGFloat) -> some View {
        ForEach(Array(Mood.allValues.enumerated()), id: \.element.id) { index, mood in
            orbitMoodButton(
                for: mood,
                index: index,
                radius: radius,
                centerX: centerX,
                centerY: centerY
            )
        }
    }

    private func orbitMoodButton(for mood: Mood, index: Int, radius: CGFloat, centerX: CGFloat, centerY: CGFloat) -> some View {
        let angle = -Double.pi / 2 + (2 * Double.pi / 5) * Double(index)
        let posX = centerX + cos(angle) * radius
        let posY = centerY + sin(angle) * radius
        let color = moodTint.color(forMood: mood)

        return Button(action: { onMoodSelected(mood) }) {
            OrbitMoodButtonContent(mood: mood, color: color)
        }
        .buttonStyle(OrbitButtonStyle(color: color))
        .position(x: posX, y: posY)
        .accessibilityIdentifier(AccessibilityID.MoodButton.id(for: mood.widgetDisplayName))
        .accessibilityLabel(mood.strValue)
        .accessibilityHint(String(localized: "Select this mood"))
    }
}

struct OrbitMoodButtonContent: View {
    let mood: Mood
    let color: Color

    var body: some View {
        ZStack {
            Circle()
                .fill(color.opacity(0.2))
                .frame(width: 70, height: 70)

            Circle()
                .fill(color)
                .frame(width: 52, height: 52)
                .shadow(color: color.opacity(0.6), radius: 8, x: 0, y: 2)

            mood.icon
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 28, height: 28)
                .foregroundColor(.white)
        }
    }
}

// Button style for orbit moods
struct OrbitButtonStyle: ButtonStyle {
    let color: Color
    @Environment(\.accessibilityReduceMotion) private var reduceMotion

    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .scaleEffect(configuration.isPressed ? 1.15 : 1.0)
            .shadow(
                color: configuration.isPressed ? color.opacity(0.8) : Color.clear,
                radius: configuration.isPressed ? 20 : 0,
                x: 0,
                y: 0
            )
            .animation(reduceMotion ? nil : .spring(response: 0.3, dampingFraction: 0.6), value: configuration.isPressed)
    }
}

// Custom button style for aura with glow effect on press
struct AuraButtonStyle: ButtonStyle {
    let color: Color
    @Environment(\.accessibilityReduceMotion) private var reduceMotion

    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .scaleEffect(configuration.isPressed ? 0.92 : 1.0)
            .brightness(configuration.isPressed ? 0.1 : 0)
            .animation(reduceMotion ? nil : .easeInOut(duration: 0.15), value: configuration.isPressed)
    }
}

// MARK: - Button Styles
struct MoodButtonStyle: ButtonStyle {
    @Environment(\.accessibilityReduceMotion) private var reduceMotion

    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .scaleEffect(configuration.isPressed ? 0.9 : 1.0)
            .animation(reduceMotion ? nil : .easeInOut(duration: 0.15), value: configuration.isPressed)
    }
}

struct CardButtonStyle: ButtonStyle {
    @Environment(\.accessibilityReduceMotion) private var reduceMotion

    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .scaleEffect(configuration.isPressed ? 0.96 : 1.0)
            .opacity(configuration.isPressed ? 0.8 : 1.0)
            .animation(reduceMotion ? nil : .easeInOut(duration: 0.15), value: configuration.isPressed)
    }
}

// MARK: - Previews
struct AddMoodHeaderView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            AddMoodHeaderView(addItemHeaderClosure: { (_,_) in

            }).modelContainer(DataController.shared.container)

            AddMoodHeaderView(addItemHeaderClosure: { (_,_) in

            }).preferredColorScheme(.dark).modelContainer(DataController.shared.container)
        }
    }
}

// MARK: - Layout 7: Neon (Synthwave Arcade Equalizer)

struct NeonVotingView: View {
    let moodTint: MoodTints
    let onMoodSelected: (Mood) -> Void

    @State private var pulsePhase = false
    @State private var hoveredMood: Mood?

    // Synthwave color palette
    private let neonCyan = Color(red: 0.0, green: 1.0, blue: 0.82)
    private let neonMagenta = Color(red: 1.0, green: 0.0, blue: 0.8)
    private let neonYellow = Color(red: 1.0, green: 0.9, blue: 0.0)
    private let deepBlack = Color(red: 0.02, green: 0.02, blue: 0.04)

    var body: some View {
        ZStack {
            // Grid background
            neonGridBackground

            // Equalizer bars
            HStack(spacing: 8) {
                ForEach(Mood.allValues, id: \.self) { mood in
                    NeonEqualizerBar(
                        mood: mood,
                        moodTint: moodTint,
                        isHovered: hoveredMood == mood,
                        pulsePhase: pulsePhase,
                        neonCyan: neonCyan,
                        neonMagenta: neonMagenta,
                        onTap: { onMoodSelected(mood) }
                    )
                }
            }
            .padding(.horizontal, 16)
            .padding(.vertical, 20)
        }
        .frame(height: 200)
        .clipShape(RoundedRectangle(cornerRadius: 16))
        .overlay(
            RoundedRectangle(cornerRadius: 16)
                .stroke(
                    LinearGradient(
                        colors: [neonCyan.opacity(0.6), neonMagenta.opacity(0.6)],
                        startPoint: .topLeading,
                        endPoint: .bottomTrailing
                    ),
                    lineWidth: 1
                )
        )
        .shadow(color: neonCyan.opacity(0.2), radius: 20, x: 0, y: 0)
        .shadow(color: neonMagenta.opacity(0.15), radius: 30, x: 0, y: 10)
        .onAppear {
            withAnimation(.easeInOut(duration: 1.5).repeatForever(autoreverses: true)) {
                pulsePhase = true
            }
        }
        .onDisappear {
            pulsePhase = false
        }
    }

    private var neonGridBackground: some View {
        ZStack {
            // Deep black base
            deepBlack

            // Grid
            Canvas { context, size in
                let gridSpacing: CGFloat = 20
                let cyanColor = Color(red: 0.0, green: 0.8, blue: 0.7)

                // Horizontal lines
                for y in stride(from: 0, to: size.height, by: gridSpacing) {
                    var path = Path()
                    path.move(to: CGPoint(x: 0, y: y))
                    path.addLine(to: CGPoint(x: size.width, y: y))
                    context.stroke(path, with: .color(cyanColor.opacity(0.08)), lineWidth: 0.5)
                }

                // Vertical lines
                for x in stride(from: 0, to: size.width, by: gridSpacing) {
                    var path = Path()
                    path.move(to: CGPoint(x: x, y: 0))
                    path.addLine(to: CGPoint(x: x, y: size.height))
                    context.stroke(path, with: .color(cyanColor.opacity(0.08)), lineWidth: 0.5)
                }
            }

            // Ambient glow at bottom
            LinearGradient(
                colors: [
                    neonMagenta.opacity(0.15),
                    Color.clear
                ],
                startPoint: .bottom,
                endPoint: .top
            )
            .blur(radius: 30)
        }
    }
}

struct NeonEqualizerBar: View {
    let mood: Mood
    let moodTint: MoodTints
    let isHovered: Bool
    let pulsePhase: Bool
    let neonCyan: Color
    let neonMagenta: Color
    let onTap: () -> Void

    @State private var isPressed = false

    private var barHeight: CGFloat {
        switch mood {
        case .great: return 140
        case .good: return 115
        case .average: return 90
        case .bad: return 65
        case .horrible: return 45
        default: return 90
        }
    }

    private var barColor: Color {
        switch mood {
        case .great: return neonCyan
        case .good: return Color(red: 0.2, green: 1.0, blue: 0.6)
        case .average: return Color(red: 1.0, green: 0.9, blue: 0.0)
        case .bad: return Color(red: 1.0, green: 0.5, blue: 0.0)
        case .horrible: return neonMagenta
        default: return Color(red: 1.0, green: 0.9, blue: 0.0)
        }
    }

    var body: some View {
        Button(action: onTap) {
            // The equalizer bar
            ZStack(alignment: .bottom) {
                // Glow background
                RoundedRectangle(cornerRadius: 6)
                    .fill(barColor.opacity(pulsePhase ? 0.15 : 0.08))
                    .frame(height: barHeight + 20)
                    .blur(radius: 15)

                // Main bar
                RoundedRectangle(cornerRadius: 6)
                    .fill(
                        LinearGradient(
                            colors: [
                                barColor,
                                barColor.opacity(0.7)
                            ],
                            startPoint: .top,
                            endPoint: .bottom
                        )
                    )
                    .frame(height: isPressed ? barHeight * 0.9 : barHeight)
                    .shadow(color: barColor.opacity(0.8), radius: pulsePhase ? 12 : 8, x: 0, y: 0)
                    .shadow(color: barColor.opacity(0.4), radius: pulsePhase ? 20 : 15, x: 0, y: 5)

                // Top highlight
                RoundedRectangle(cornerRadius: 6)
                    .fill(
                        LinearGradient(
                            colors: [Color.white.opacity(0.5), Color.clear],
                            startPoint: .top,
                            endPoint: .center
                        )
                    )
                    .frame(height: isPressed ? barHeight * 0.9 : barHeight)

                // Level indicators (horizontal lines)
                VStack(spacing: 8) {
                    ForEach(0..<Int(barHeight / 15), id: \.self) { _ in
                        Rectangle()
                            .fill(Color.black.opacity(0.3))
                            .frame(height: 2)
                    }
                }
                .frame(height: isPressed ? barHeight * 0.9 - 10 : barHeight - 10)
                .clipShape(RoundedRectangle(cornerRadius: 4))
                .padding(.horizontal, 4)
                .padding(.bottom, 5)
            }
            .frame(maxHeight: 180, alignment: .bottom)
        }
        .buttonStyle(NeonBarButtonStyle(isPressed: $isPressed))
        .frame(maxWidth: .infinity)
        .accessibilityIdentifier(AccessibilityID.MoodButton.id(for: mood.widgetDisplayName))
        .accessibilityLabel(mood.strValue)
        .accessibilityHint(String(localized: "Select this mood"))
    }
}

struct NeonBarButtonStyle: ButtonStyle {
    @Binding var isPressed: Bool

    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .scaleEffect(configuration.isPressed ? 0.95 : 1.0)
            .animation(.easeInOut(duration: 0.1), value: configuration.isPressed)
            .onChange(of: configuration.isPressed) { _, newValue in
                isPressed = newValue
            }
    }
}

