//
//  HomeViewTwo.swift
//  Reflect (iOS)
//
//  Created by Trey Tartt on 2/18/22.
//

import SwiftUI

struct MonthView: View {
    @AppStorage(UserDefaultsStore.Keys.needsOnboarding.rawValue, store: GroupUserDefaults.groupDefaults) private var needsOnboarding = true

    @AppStorage(UserDefaultsStore.Keys.theme.rawValue, store: GroupUserDefaults.groupDefaults) private var theme: Theme = .system

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

    @AppStorage(UserDefaultsStore.Keys.moodTint.rawValue, store: GroupUserDefaults.groupDefaults) private var moodTint: MoodTints = .Default
    @AppStorage(UserDefaultsStore.Keys.moodImages.rawValue, store: GroupUserDefaults.groupDefaults) private var imagePack: MoodImages = .FontAwesome

    @AppStorage(UserDefaultsStore.Keys.shape.rawValue, store: GroupUserDefaults.groupDefaults) private var shape: BGShape = .circle

    @StateObject private var shareImage = ShareImageStateViewModel()
    @State private var sharePickerData: SharePickerData? = nil

    @EnvironmentObject var iapManager: IAPManager
    @StateObject private var selectedDetail = DetailViewStateViewModel()
    @State private var showingSheet = false
    @StateObject private var onboardingData = OnboardingDataDataManager.shared
    @StateObject private var filteredDays = DaysFilterClass.shared

    class DetailViewStateViewModel: ObservableObject {
        @Published var selectedItem: MonthDetailView? = nil
        @Published var showSheet = false
    }

    // Heatmap-style grid with tight spacing
    private let heatmapColumns = Array(repeating: GridItem(.flexible(), spacing: 2), count: 7)

    private let weekdayLabels = ["S", "M", "T", "W", "T", "F", "S"]

    @ObservedObject var viewModel: DayViewViewModel
    @State private var trialWarningHidden = false
    @State private var showSubscriptionStore = false

    /// Cached sorted year/month data to avoid recalculating in ForEach
    @State private var cachedSortedData: [(year: Int, months: [(month: Int, entries: [MoodEntryModel])])] = []
    @State private var cachedDemoSortedData: [(year: Int, months: [(month: Int, entries: [MoodEntryModel])])] = []

    // MARK: - Demo Animation
    @StateObject private var demoManager = DemoAnimationManager.shared

    /// Generate fake demo data for the past 12 months
    private func computeDemoSortedData() -> [(year: Int, months: [(month: Int, entries: [MoodEntryModel])])] {
        var result: [(year: Int, months: [(month: Int, entries: [MoodEntryModel])])] = []
        let calendar = Calendar.current
        let now = Date()

        // Group months by year
        var yearDict: [Int: [(month: Int, entries: [MoodEntryModel])]] = [:]

        for monthOffset in 0..<12 {
            guard let monthDate = calendar.date(byAdding: .month, value: -monthOffset, to: now) else { continue }
            let year = calendar.component(.year, from: monthDate)
            let month = calendar.component(.month, from: monthDate)

            let entries = generateDemoMonthEntries(year: year, month: month)
            if yearDict[year] == nil {
                yearDict[year] = []
            }
            yearDict[year]?.append((month: month, entries: entries))
        }

        // Sort years descending, months descending within each year
        for year in yearDict.keys.sorted(by: >) {
            if let months = yearDict[year] {
                result.append((year: year, months: months.sorted { $0.month > $1.month }))
            }
        }

        return result
    }

    /// Generate fake entries for a demo month
    private func generateDemoMonthEntries(year: Int, month: Int) -> [MoodEntryModel] {
        let calendar = Calendar.current
        var entries: [MoodEntryModel] = []

        // Get first day of month
        var components = DateComponents()
        components.year = year
        components.month = month
        components.day = 1
        guard let firstOfMonth = calendar.date(from: components) else { return entries }

        // Get the weekday of first day (1 = Sunday, 7 = Saturday)
        let firstWeekday = calendar.component(.weekday, from: firstOfMonth)

        // Add placeholder entries for days before the first
        for i in 1..<firstWeekday {
            // Create a date before the month starts for placeholder
            if let placeholderDate = calendar.date(byAdding: .day, value: -(firstWeekday - i), to: firstOfMonth) {
                let entry = MoodEntryModel(
                    forDate: placeholderDate,
                    mood: .placeholder,
                    entryType: .listView,
                    canEdit: false,
                    canDelete: false
                )
                entries.append(entry)
            }
        }

        // Get number of days in month
        guard let range = calendar.range(of: .day, in: .month, for: firstOfMonth) else { return entries }

        // Add entries for each day
        for day in 1...range.count {
            components.day = day
            if let date = calendar.date(from: components) {
                // Create a fake entry with random positive mood for demo
                let entry = MoodEntryModel(
                    forDate: date,
                    mood: DemoAnimationManager.randomPositiveMood(),
                    entryType: .listView,
                    canEdit: false,
                    canDelete: false
                )
                entries.append(entry)
            }
        }

        return entries
    }

    /// Filters month data to only current month when subscription/trial expired
    private func computeFilteredMonthData() -> [Int: [Int: [MoodEntryModel]]] {
        guard iapManager.shouldShowPaywall else {
            return viewModel.grouped
        }

        // Only show current month when paywall should show
        let currentMonth = Calendar.current.component(.month, from: Date())
        let currentYear = Calendar.current.component(.year, from: Date())

        var filtered: [Int: [Int: [MoodEntryModel]]] = [:]
        if let yearData = viewModel.grouped[currentYear],
           let monthData = yearData[currentMonth] {
            filtered[currentYear] = [currentMonth: monthData]
        }
        return filtered
    }

    /// Sorts the filtered month data - called only when source data changes
    private func computeSortedYearMonthData() -> [(year: Int, months: [(month: Int, entries: [MoodEntryModel])])] {
        computeFilteredMonthData()
            .sorted { $0.key > $1.key }
            .map { (year: $0.key, months: $0.value.sorted { $0.key > $1.key }.map { (month: $0.key, entries: $0.value) }) }
    }

    /// Data to display - uses demo data when in demo mode, otherwise cached real data
    private var displayData: [(year: Int, months: [(month: Int, entries: [MoodEntryModel])])] {
        demoManager.isDemoMode ? cachedDemoSortedData : cachedSortedData
    }

    var body: some View {
        ZStack {
            if viewModel.hasNoData && !demoManager.isDemoMode {
                EmptyHomeView(showVote: false, viewModel: nil)
                    .padding()
            } else {
                ScrollViewReader { scrollProxy in
                    ScrollView {
                        VStack(spacing: 16) {
                            let allMonths = displayData.flatMap { yearData in
                                yearData.months.map { (year: yearData.year, month: $0.month, entries: $0.entries) }
                            }
                            ForEach(Array(allMonths.enumerated()), id: \.element.month) { monthIndex, monthData in
                                MonthCard(
                                    month: monthData.month,
                                    year: monthData.year,
                                    entries: monthData.entries,
                                    moodTint: moodTint,
                                    imagePack: imagePack,
                                    theme: theme,
                                    filteredDays: filteredDays.currentFilters,
                                    monthIndex: monthIndex,
                                    onTap: {
                                        let detailView = MonthDetailView(
                                            monthInt: monthData.month,
                                            yearInt: monthData.year,
                                            entries: monthData.entries,
                                            parentViewModel: viewModel
                                        )
                                        selectedDetail.selectedItem = detailView
                                        selectedDetail.showSheet = true
                                    },
                                    onShare: { metrics, entries, month in
                                        sharePickerData = SharePickerData(
                                            title: Random.monthName(fromMonthInt: month),
                                            designs: [
                                                SharingDesign(
                                                    name: "Clean Calendar",
                                                    shareView: AnyView(MonthTotalV1(moodMetrics: metrics, moodEntries: entries, month: month)),
                                                    image: { MonthTotalV1(moodMetrics: metrics, moodEntries: entries, month: month).image }
                                                ),
                                                SharingDesign(
                                                    name: "Stacked Bars",
                                                    shareView: AnyView(MonthTotalV5(moodMetrics: metrics, moodEntries: entries, month: month)),
                                                    image: { MonthTotalV5(moodMetrics: metrics, moodEntries: entries, month: month).image }
                                                ),
                                            ]
                                        )
                                    }
                                )
                                .id("month-\(monthIndex)")
                            }

                            // Scroll anchor at the very bottom
                            Color.clear.frame(height: 1).id("scroll-end")
                        }
                        .padding(.horizontal)
                        .padding(.bottom, 100)
                        .id(moodTint) // Force complete refresh when mood tint changes
                        .background(
                            GeometryReader { proxy in
                                let offset = proxy.frame(in: .named("scroll")).minY
                                Color.clear.preference(key: ViewOffsetKey.self, value: offset)
                            }
                        )
                    }
                    .onChange(of: demoManager.animationProgress) { _, progress in
                        guard demoManager.isDemoMode && demoManager.animationStarted else { return }

                        // Start slow scroll once first month is 50% done
                        let halfwayPoint = demoManager.monthAnimationDuration * 0.5
                        if progress >= halfwayPoint && progress < halfwayPoint + 0.1 {
                            // Trigger once: scroll to bottom with long duration for smooth constant speed
                            let totalMonths = displayData.flatMap { $0.months }.count
                            let totalDuration = Double(totalMonths) * demoManager.monthAnimationDuration
                            withAnimation(.linear(duration: totalDuration)) {
                                scrollProxy.scrollTo("scroll-end", anchor: .bottom)
                            }
                        }
                    }
                }
                .scrollDisabled(iapManager.shouldShowPaywall && !demoManager.isDemoMode)
                .mask(
                    // Fade effect when paywall should show: 100% at top, 0% halfway down (disabled in demo mode)
                    (iapManager.shouldShowPaywall && !demoManager.isDemoMode) ?
                    AnyView(
                        LinearGradient(
                            gradient: Gradient(stops: [
                                .init(color: .black, location: 0),
                                .init(color: .black, location: 0.3),
                                .init(color: .clear, location: 0.5)
                            ]),
                            startPoint: .top,
                            endPoint: .bottom
                        )
                    ) : AnyView(Color.black)
                )
            }

            if iapManager.shouldShowPaywall && !demoManager.isDemoMode {
                // Premium month history prompt - bottom half (hidden in demo mode)
                VStack(spacing: 20) {
                    // Icon
                    ZStack {
                        Circle()
                            .fill(
                                LinearGradient(
                                    colors: [.purple.opacity(0.2), .pink.opacity(0.2)],
                                    startPoint: .topLeading,
                                    endPoint: .bottomTrailing
                                )
                            )
                            .frame(width: 80, height: 80)

                        Image(systemName: "calendar.badge.clock")
                            .font(.title)
                            .foregroundStyle(
                                LinearGradient(
                                    colors: [.purple, .pink],
                                    startPoint: .topLeading,
                                    endPoint: .bottomTrailing
                                )
                            )
                    }

                    // Text
                    VStack(spacing: 10) {
                        Text("Explore Your Mood History")
                            .font(.title3.weight(.bold))
                            .foregroundColor(labelColor)
                            .multilineTextAlignment(.center)

                        Text("See your complete monthly journey. Track patterns and understand what shapes your days.")
                            .font(.subheadline)
                            .foregroundColor(labelColor.opacity(0.7))
                            .multilineTextAlignment(.center)
                            .padding(.horizontal, 24)
                    }

                    // Subscribe button
                    Button {
                        showSubscriptionStore = true
                    } label: {
                        HStack {
                            Image(systemName: "calendar")
                            Text("Unlock Full History")
                        }
                        .font(.headline.weight(.bold))
                        .foregroundColor(.white)
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 14)
                        .background(
                            LinearGradient(
                                colors: [.purple, .pink],
                                startPoint: .leading,
                                endPoint: .trailing
                            )
                        )
                        .clipShape(RoundedRectangle(cornerRadius: 14))
                    }
                    .padding(.horizontal, 24)
                }
                .padding(.vertical, 24)
                .frame(maxWidth: .infinity)
                .background(theme.currentTheme.bg)
                .frame(maxHeight: .infinity, alignment: .bottom)
                .accessibilityIdentifier(AccessibilityID.Paywall.monthOverlay)
            } else if iapManager.shouldShowTrialWarning && !demoManager.isDemoMode {
                VStack {
                    Spacer()
                    if !trialWarningHidden {
                        IAPWarningView(iapManager: iapManager)
                    }
                }
            }
        }
        .sheet(isPresented: $showSubscriptionStore) {
            ReflectSubscriptionStoreView(source: "month_gate")
        }
        .onAppear(perform: {
            AnalyticsManager.shared.trackScreen(.month)
        })
        .padding([.top])
        .background(
            theme.currentTheme.bg
                .edgesIgnoringSafeArea(.all)
        )
        .sheet(isPresented: $selectedDetail.showSheet,
                onDismiss: didDismiss) {
            selectedDetail.selectedItem
        }
        .sheet(item: $sharePickerData) { data in
            SharingStylePickerView(title: data.title, designs: data.designs)
        }
        .onPreferenceChange(ViewOffsetKey.self) { value in
            withAnimation {
                trialWarningHidden = value < 0
            }
        }
        .onAppear {
            cachedSortedData = computeSortedYearMonthData()
            cachedDemoSortedData = computeDemoSortedData()
        }
        .onChange(of: viewModel.numberOfItems) { _, _ in
            // Use numberOfItems as a lightweight proxy for data changes
            // instead of comparing the entire grouped dictionary
            cachedSortedData = computeSortedYearMonthData()
        }
        .onChange(of: iapManager.shouldShowPaywall) { _, _ in
            cachedSortedData = computeSortedYearMonthData()
        }
        .preferredColorScheme(theme.preferredColorScheme)
        #if DEBUG
        // Triple-tap to toggle demo mode for video recording
        .onTapGesture(count: 3) {
            if demoManager.isDemoMode {
                demoManager.stopDemoMode()
            } else {
                demoManager.startDemoMode()
            }
        }
        #endif
    }


    func didDismiss() {
        selectedDetail.showSheet = false
        selectedDetail.selectedItem = nil
    }
}

// MARK: - Month Card Component
struct MonthCard: View, Equatable {
    let month: Int
    let year: Int
    let entries: [MoodEntryModel]
    let moodTint: MoodTints
    let imagePack: MoodImages
    let theme: Theme
    let filteredDays: [Int]
    let monthIndex: Int  // Index for demo animation sequencing
    let onTap: () -> Void
    let onShare: ([MoodMetrics], [MoodEntryModel], Int) -> Void

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

    // Demo animation support
    @ObservedObject private var demoManager = DemoAnimationManager.shared

    // Equatable conformance to prevent unnecessary re-renders
    static func == (lhs: MonthCard, rhs: MonthCard) -> Bool {
        lhs.month == rhs.month &&
        lhs.year == rhs.year &&
        lhs.entries.count == rhs.entries.count &&
        lhs.moodTint == rhs.moodTint &&
        lhs.imagePack == rhs.imagePack &&
        lhs.filteredDays == rhs.filteredDays &&
        lhs.theme == rhs.theme &&
        lhs.monthIndex == rhs.monthIndex
    }

    @State private var showStats = true
    @State private var cachedMetrics: [MoodMetrics] = []

    private let weekdayLabels = ["S", "M", "T", "W", "T", "F", "S"]
    private let heatmapColumns = Array(repeating: GridItem(.flexible(), spacing: 2), count: 7)

    // Animated metrics for demo mode - scales based on visible percentage
    private var animatedMetrics: [MoodMetrics] {
        guard demoManager.isDemoMode else { return cachedMetrics }

        let totalCells = entries.filter { $0.mood != .placeholder }.count
        let visiblePercentage = demoManager.visiblePercentageForMonth(totalCells: totalCells, monthIndex: monthIndex)

        // Scale metrics by visible percentage
        return cachedMetrics.map { metric in
            let animatedTotal = Int(Double(metric.total) * visiblePercentage)
            let animatedPercent = metric.percent * Float(visiblePercentage)
            return MoodMetrics(mood: metric.mood, total: animatedTotal, percent: animatedPercent)
        }
    }

    // Cached filtered/sorted metrics to avoid recalculating in ForEach
    private var displayMetrics: [MoodMetrics] {
        animatedMetrics.filter { $0.total > 0 }.sorted { $0.mood.rawValue > $1.mood.rawValue }
    }

    // All 5 moods for share view (shows 0% for moods with no entries)
    private var allMoodMetrics: [MoodMetrics] {
        animatedMetrics.sorted { $0.mood.rawValue > $1.mood.rawValue }
    }

    private var topMood: Mood? {
        displayMetrics.max(by: { $0.total < $1.total })?.mood
    }

    private var totalTrackedDays: Int {
        entries.filter { ![.missing, .placeholder].contains($0.mood) }.count
    }

    private var shareableView: some View {
        VStack(spacing: 0) {
            // Header with month/year
            Text("\(Random.monthName(fromMonthInt: month).uppercased()) \(String(year))")
                .font(.title.weight(.heavy))
                .foregroundColor(labelColor)
                .padding(.top, 40)
                .padding(.bottom, 8)

            Text("Monthly Mood Wrap")
                .font(.body.weight(.medium))
                .foregroundColor(labelColor.opacity(0.6))
                .padding(.bottom, 30)

            // Top mood highlight
            if let topMood = topMood {
                VStack(spacing: 12) {
                    Circle()
                        .fill(moodTint.color(forMood: topMood))
                        .frame(width: 100, height: 100)
                        .overlay(
                            imagePack.icon(forMood: topMood)
                                .resizable()
                                .aspectRatio(contentMode: .fit)
                                .foregroundColor(.white)
                                .padding(24)
                                .accessibilityLabel(topMood.strValue)
                        )
                        .shadow(color: moodTint.color(forMood: topMood).opacity(0.5), radius: 20, x: 0, y: 10)

                    Text("Top Mood")
                        .font(.subheadline.weight(.medium))
                        .foregroundColor(labelColor.opacity(0.5))

                    Text(topMood.strValue.uppercased())
                        .font(.title3.weight(.bold))
                        .foregroundColor(moodTint.color(forMood: topMood))
                }
                .padding(.bottom, 30)
            }

            // Stats row
            HStack(spacing: 0) {
                VStack(spacing: 4) {
                    Text("\(totalTrackedDays)")
                        .font(.largeTitle.weight(.bold))
                        .foregroundColor(labelColor)
                    Text("Days Tracked")
                        .font(.caption.weight(.medium))
                        .foregroundColor(labelColor.opacity(0.5))
                }
                .frame(maxWidth: .infinity)
            }
            .padding(.bottom, 30)

            // Mood breakdown with bars (all 5 moods)
            VStack(spacing: 12) {
                ForEach(allMoodMetrics) { metric in
                    HStack(spacing: 12) {
                        Circle()
                            .fill(moodTint.color(forMood: metric.mood))
                            .frame(width: 32, height: 32)
                            .overlay(
                                imagePack.icon(forMood: metric.mood)
                                    .resizable()
                                    .aspectRatio(contentMode: .fit)
                                    .foregroundColor(.white)
                                    .padding(7)
                                    .accessibilityLabel(metric.mood.strValue)
                            )

                        GeometryReader { geo in
                            ZStack(alignment: .leading) {
                                RoundedRectangle(cornerRadius: 6)
                                    .fill(Color.gray.opacity(0.2))

                                if metric.percent > 0 {
                                    RoundedRectangle(cornerRadius: 6)
                                        .fill(moodTint.color(forMood: metric.mood))
                                        .frame(width: max(8, geo.size.width * CGFloat(metric.percent / 100)))
                                }
                            }
                        }
                        .frame(height: 12)

                        Text("\(Int(metric.percent))%")
                            .font(.subheadline.weight(.semibold))
                            .foregroundColor(labelColor)
                            .frame(width: 40, alignment: .trailing)
                    }
                }
            }
            .padding(.horizontal, 32)
            .padding(.bottom, 40)

            // App branding
            Text("ifeel")
                .font(.subheadline.weight(.medium))
                .foregroundColor(labelColor.opacity(0.3))
                .padding(.bottom, 20)
        }
        .frame(width: 400)
        .background(theme.currentTheme.secondaryBGColor)
    }

    var body: some View {
        VStack(spacing: 0) {
            // Month Header
            HStack {
                Button(action: {
                if UIAccessibility.isReduceMotionEnabled {
                    showStats.toggle()
                } else {
                    withAnimation(.easeInOut(duration: 0.2)) { showStats.toggle() }
                }
            }) {
                    HStack {
                        Text("\(Random.monthName(fromMonthInt: month)) \(String(year))")
                            .font(.title3.bold())
                            .foregroundColor(labelColor)

                        Image(systemName: showStats ? "chevron.up" : "chevron.down")
                            .font(.caption.weight(.semibold))
                            .foregroundColor(labelColor.opacity(0.5))
                    }
                }
                .buttonStyle(.plain)
                .accessibilityLabel("\(Random.monthName(fromMonthInt: month)) \(String(year)), \(showStats ? "expanded" : "collapsed")")
                .accessibilityHint("Double tap to toggle statistics")

                Spacer()

                Button(action: {
                    onShare(cachedMetrics, entries, month)
                }) {
                    Image(systemName: "square.and.arrow.up")
                        .font(.subheadline.weight(.medium))
                        .foregroundColor(labelColor.opacity(0.6))
                }
                .buttonStyle(.plain)
                .accessibilityLabel("Share \(Random.monthName(fromMonthInt: month)) \(String(year)) mood data")
                .accessibilityIdentifier(AccessibilityID.MonthView.shareButton)
            }
            .padding(.horizontal, 16)
            .padding(.vertical, 12)

            // Weekday Labels
            HStack(spacing: 2) {
                ForEach(weekdayLabels.indices, id: \.self) { index in
                    Text(weekdayLabels[index])
                        .font(.caption2.weight(.medium))
                        .foregroundColor(labelColor.opacity(0.5))
                        .frame(maxWidth: .infinity)
                }
            }
            .padding(.horizontal, 16)
            .padding(.bottom, 6)

            // Heatmap Grid
            LazyVGrid(columns: heatmapColumns, spacing: 2) {
                ForEach(Array(entries.enumerated()), id: \.element) { index, entry in
                    let row = index / 7
                    let column = index % 7
                    let totalRows = (entries.count + 6) / 7

                    DemoHeatmapCell(
                        entry: entry,
                        moodTint: moodTint,
                        isFiltered: filteredDays.contains(Int(entry.weekDay)),
                        row: row,
                        column: column,
                        totalRows: totalRows,
                        totalColumns: 7,
                        monthIndex: monthIndex,
                        demoManager: demoManager
                    )
                }
            }
            .padding(.horizontal, 16)
            .padding(.bottom, 12)

            // Bar Chart Stats (collapsible)
            if showStats {
                Divider()
                    .padding(.horizontal, 16)

                MoodBarChart(metrics: animatedMetrics, moodTint: moodTint, imagePack: imagePack)
                    .padding(.horizontal, 16)
                    .padding(.vertical, 12)
                    .transition(.opacity.combined(with: .move(edge: .top)))
            }
        }
        .background(
            RoundedRectangle(cornerRadius: 16)
                .fill(theme.currentTheme.secondaryBGColor)
        )
        .contentShape(Rectangle())
        .onTapGesture {
            onTap()
        }
        .onAppear {
            // Cache metrics calculation on first appearance
            if cachedMetrics.isEmpty {
                cachedMetrics = Random.createTotalPerc(fromEntries: entries)
            }
        }
    }
}

// MARK: - Heatmap Cell
struct HeatmapCell: View {
    let entry: MoodEntryModel
    let moodTint: MoodTints
    let isFiltered: Bool

    var body: some View {
        RoundedRectangle(cornerRadius: 4)
            .fill(cellColor)
            .aspectRatio(1, contentMode: .fit)
            .accessibilityLabel(accessibilityDescription)
            .accessibilityHint(entry.mood != .placeholder && entry.mood != .missing ? "Double tap to edit" : "")
    }

    private var accessibilityDescription: String {
        if entry.mood == .placeholder {
            return "Empty day"
        } else if entry.mood == .missing {
            return "No mood logged for \(formattedDate)"
        } else if !isFiltered {
            return "\(formattedDate): \(entry.mood.strValue) (filtered out)"
        } else {
            return "\(formattedDate): \(entry.mood.strValue)"
        }
    }

    private var formattedDate: String {
        DateFormattingCache.shared.string(for: entry.forDate, format: .dateMedium)
    }

    private var cellColor: Color {
        if entry.mood == .placeholder {
            return Color.gray.opacity(0.1)
        } else if entry.mood == .missing {
            return Color.gray.opacity(0.25)
        } else if !isFiltered {
            return Color.gray.opacity(0.1)
        } else {
            return moodTint.color(forMood: entry.mood)
        }
    }
}

// MARK: - Demo Heatmap Cell (with animation support)
struct DemoHeatmapCell: View {
    let entry: MoodEntryModel
    let moodTint: MoodTints
    let isFiltered: Bool
    let row: Int
    let column: Int
    let totalRows: Int
    let totalColumns: Int
    let monthIndex: Int  // Which month this is (0 = first/most recent)
    @ObservedObject var demoManager: DemoAnimationManager

    /// Random mood for this cell (computed once and cached)
    @State private var randomMood: Mood = .great

    var body: some View {
        ZStack {
            // Background: Gray grid cell always visible at 1x scale
            RoundedRectangle(cornerRadius: 4)
                .fill(Color.gray.opacity(0.3))
                .aspectRatio(1, contentMode: .fit)

            // Foreground: Animated mood color that scales 2x -> 1x
            if demoManager.isDemoMode {
                // Skip placeholder cells (first row offset cells)
                if entry.mood != .placeholder {
                    RoundedRectangle(cornerRadius: 4)
                        .fill(moodTint.color(forMood: randomMood))
                        .aspectRatio(1, contentMode: .fit)
                        .scaleEffect(isAnimated ? 1.0 : 2.0)
                        .opacity(isAnimated ? 1.0 : 0.0)
                        .animation(.spring(response: 0.3, dampingFraction: 0.7), value: isAnimated)
                }
            } else {
                // Normal mode - just show the actual color
                RoundedRectangle(cornerRadius: 4)
                    .fill(normalCellColor)
                    .aspectRatio(1, contentMode: .fit)
            }
        }
        .onAppear {
            // Generate random mood once when cell appears
            randomMood = DemoAnimationManager.randomPositiveMood()
        }
        .accessibilityLabel(accessibilityDescription)
    }

    /// Whether this cell has been animated (filled with color)
    private var isAnimated: Bool {
        if !demoManager.isDemoMode {
            return true // Normal mode - always show
        }
        if !demoManager.animationStarted {
            return false // Demo mode but animation hasn't started
        }
        return demoManager.isCellVisible(
            row: row,
            column: column,
            totalRows: totalRows,
            totalColumns: totalColumns,
            monthIndex: monthIndex
        )
    }

    /// Color for normal (non-demo) mode
    private var normalCellColor: Color {
        if entry.mood == .placeholder {
            return Color.gray.opacity(0.1)
        } else if entry.mood == .missing {
            return Color.gray.opacity(0.25)
        } else if !isFiltered {
            return Color.gray.opacity(0.1)
        } else {
            return moodTint.color(forMood: entry.mood)
        }
    }

    private var accessibilityDescription: String {
        if entry.mood == .placeholder {
            return "Empty day"
        } else if entry.mood == .missing {
            return "No mood logged for \(DateFormattingCache.shared.string(for: entry.forDate, format: .dateMedium))"
        } else if !isFiltered {
            return "\(DateFormattingCache.shared.string(for: entry.forDate, format: .dateMedium)): \(entry.mood.strValue) (filtered out)"
        } else {
            return "\(DateFormattingCache.shared.string(for: entry.forDate, format: .dateMedium)): \(entry.mood.strValue)"
        }
    }
}

// MARK: - Mini Bar Chart
struct MoodBarChart: View {
    let metrics: [MoodMetrics]
    let moodTint: MoodTints
    let imagePack: MoodImages

    var body: some View {
        VStack(spacing: 8) {
            ForEach(metrics) { metric in
                HStack(spacing: 10) {
                    // Mood icon
                    imagePack.icon(forMood: metric.mood)
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: 18, height: 18)
                        .foregroundColor(moodTint.color(forMood: metric.mood))
                        .accessibilityLabel(metric.mood.strValue)

                    // Bar
                    GeometryReader { geo in
                        ZStack(alignment: .leading) {
                            // Background track
                            RoundedRectangle(cornerRadius: 4)
                                .fill(Color.gray.opacity(0.15))

                            // Filled bar
                            RoundedRectangle(cornerRadius: 4)
                                .fill(moodTint.color(forMood: metric.mood))
                                .frame(width: max(4, geo.size.width * CGFloat(metric.percent / 100)))
                        }
                    }
                    .frame(height: 10)

                    // Count and percentage
                    Text("\(metric.total)")
                        .font(.caption.weight(.semibold))
                        .foregroundColor(moodTint.color(forMood: metric.mood))
                        .frame(width: 28, alignment: .trailing)
                }
            }
        }
    }
}

// MARK: - Legacy support for settings button
extension MonthView {
    private var settingsButtonView: some View {
        HStack {
            Spacer()
            VStack {
                Button(action: {
                    showingSheet.toggle()
                }, label: {
                    Image(systemName: "gear")
                        .foregroundColor(Color(UIColor.darkGray))
                        .font(.title3)
                }).sheet(isPresented: $showingSheet) {
                    SettingsView()
                }
                .padding(.top, 60)
                .padding(.trailing)
                Spacer()
            }
        }
    }
}

struct MonthView_Previews: PreviewProvider {
    static var previews: some View {
        MonthView(viewModel: DayViewViewModel(addMonthStartWeekdayPadding: true))
    }
}
