//
//  WidgetExporter.swift
//  Reflect
//
//  Debug utility to export all widget previews to PNG files.
//  Uses the real widget view layouts from ExportableWidgetViews.swift.
//

#if DEBUG
import SwiftUI
import UIKit

/// Exports widget previews to PNG files for App Store screenshots
@MainActor
class WidgetExporter {

    // MARK: - Widget Sizes (iPhone 15 Pro Max @ 3x)

    enum WidgetSize {
        case small   // 170x170 pt = 510x510 px
        case medium  // 364x170 pt = 1092x510 px
        case large   // 382x382 pt = 1146x1146 px

        var pointSize: CGSize {
            switch self {
            case .small: return CGSize(width: 170, height: 170)
            case .medium: return CGSize(width: 364, height: 170)
            case .large: return CGSize(width: 382, height: 382)
            }
        }

        var name: String {
            switch self {
            case .small: return "small"
            case .medium: return "medium"
            case .large: return "large"
            }
        }
    }

    /// Live Activity lock screen size (iPhone 15 Pro Max)
    static let liveActivitySize = CGSize(width: 370, height: 100)

    // MARK: - Available Theme Combinations

    /// All available tint options for export
    static let allTints: [(name: String, tint: MoodTintable.Type)] = [
        ("Default", DefaultMoodTint.self),
        ("Neon", NeonMoodTint.self),
        ("Pastel", PastelTint.self),
        ("Monochrome", MonoChromeTint.self)
    ]

    /// All available icon options for export
    static let allIcons: [(name: String, images: MoodImagable.Type)] = [
        ("Emoji", EmojiMoodImages.self),
        ("FontAwesome", FontAwesomeMoodImages.self),
        ("Weather", WeatherMoodImages.self),
        ("Garden", GardenMoodImages.self),
        ("Hearts", HeartsMoodImages.self),
        ("Cosmic", CosmicMoodImages.self),
        ("HandEmoji", HandEmojiMoodImages.self)
    ]

    /// Sample mood stats for voted state exports
    static let sampleMoodCounts: [Mood: Int] = [.great: 45, .good: 42, .average: 18, .bad: 8, .horrible: 4]
    static let sampleTotalEntries = 117

    // MARK: - Export All Widgets (All Variations)

    /// Exports all widget variations to disk
    /// - Returns: URL to the export directory, or nil if failed
    static func exportAllWidgets() async -> URL? {
        let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        let exportPath = documentsPath.appendingPathComponent("WidgetExports", isDirectory: true)

        // Clean and create export directory
        try? FileManager.default.removeItem(at: exportPath)
        try? FileManager.default.createDirectory(at: exportPath, withIntermediateDirectories: true)

        var totalExported = 0

        // Export all tint + icon combinations
        for tintOption in allTints {
            for iconOption in allIcons {
                let folderName = "\(tintOption.name)_\(iconOption.name)"
                let variantPath = exportPath.appendingPathComponent(folderName, isDirectory: true)
                try? FileManager.default.createDirectory(at: variantPath, withIntermediateDirectories: true)

                let config = WidgetExportConfig(
                    moodTint: tintOption.tint,
                    moodImages: iconOption.images
                )

                let count = await exportWidgetsForConfig(config: config, to: variantPath)
                totalExported += count
                print("  Exported \(count) images to \(folderName)/")
            }
        }

        print("📸 Total \(totalExported) widgets exported to: \(exportPath.path)")
        return exportPath
    }

    /// Exports widgets for a single tint/icon configuration
    private static func exportWidgetsForConfig(config: WidgetExportConfig, to folder: URL) async -> Int {
        var count = 0

        for colorScheme in [ColorScheme.light, ColorScheme.dark] {
            let schemeName = colorScheme == .light ? "light" : "dark"

            // Vote Widget - Not Voted
            await exportVoteWidget(hasVoted: false, mood: nil, size: .small, config: config, colorScheme: colorScheme, to: folder, name: "vote_\(schemeName)_small_notvoted")
            await exportVoteWidget(hasVoted: false, mood: nil, size: .medium, config: config, colorScheme: colorScheme, to: folder, name: "vote_\(schemeName)_medium_notvoted")
            count += 2

            // Vote Widget - Voted (all moods)
            for mood in Mood.allValues {
                await exportVoteWidget(hasVoted: true, mood: mood, size: .small, config: config, colorScheme: colorScheme, to: folder, name: "vote_\(schemeName)_small_\(mood.strValue.lowercased())")
                await exportVoteWidget(hasVoted: true, mood: mood, size: .medium, config: config, colorScheme: colorScheme, to: folder, name: "vote_\(schemeName)_medium_\(mood.strValue.lowercased())")
                count += 2
            }

            // Timeline Widget - Logged
            await exportTimelineWidget(hasVoted: true, size: .small, config: config, colorScheme: colorScheme, to: folder, name: "timeline_\(schemeName)_small_logged")
            await exportTimelineWidget(hasVoted: true, size: .medium, config: config, colorScheme: colorScheme, to: folder, name: "timeline_\(schemeName)_medium_logged")
            await exportTimelineWidget(hasVoted: true, size: .large, config: config, colorScheme: colorScheme, to: folder, name: "timeline_\(schemeName)_large_logged")
            count += 3

            // Timeline Widget - Voting
            await exportTimelineWidget(hasVoted: false, size: .small, config: config, colorScheme: colorScheme, to: folder, name: "timeline_\(schemeName)_small_voting")
            await exportTimelineWidget(hasVoted: false, size: .medium, config: config, colorScheme: colorScheme, to: folder, name: "timeline_\(schemeName)_medium_voting")
            await exportTimelineWidget(hasVoted: false, size: .large, config: config, colorScheme: colorScheme, to: folder, name: "timeline_\(schemeName)_large_voting")
            count += 3

            // Live Activity - Not Logged
            await exportLiveActivity(hasLogged: false, mood: nil, streak: 213, config: config, colorScheme: colorScheme, to: folder, name: "liveactivity_\(schemeName)_notlogged")
            count += 1

            // Live Activity - All moods
            for mood in Mood.allValues {
                await exportLiveActivity(hasLogged: true, mood: mood, streak: 213, config: config, colorScheme: colorScheme, to: folder, name: "liveactivity_\(schemeName)_\(mood.strValue.lowercased())")
                count += 1
            }
        }

        return count
    }

    // MARK: - Export Single Configuration (Current User Settings)

    /// Exports widgets using the user's current tint/icon settings
    static func exportCurrentConfiguration() async -> URL? {
        let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        let exportPath = documentsPath.appendingPathComponent("WidgetExports_Current", isDirectory: true)

        try? FileManager.default.removeItem(at: exportPath)
        try? FileManager.default.createDirectory(at: exportPath, withIntermediateDirectories: true)

        let config = WidgetExportConfig(
            moodTint: UserDefaultsStore.moodTintable(),
            moodImages: UserDefaultsStore.moodMoodImagable()
        )

        let count = await exportWidgetsForConfig(config: config, to: exportPath)
        print("📸 Exported \(count) widgets (current config) to: \(exportPath.path)")
        return exportPath
    }

    // MARK: - Export All Voting Layouts

    /// Exports all voting layout variations (small, medium, large) in all tint/icon combinations
    /// - Returns: URL to the export directory, or nil if failed
    static func exportAllVotingLayouts() async -> URL? {
        let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        let exportPath = documentsPath.appendingPathComponent("VotingLayoutExports", isDirectory: true)

        // Clean and create export directory
        try? FileManager.default.removeItem(at: exportPath)
        try? FileManager.default.createDirectory(at: exportPath, withIntermediateDirectories: true)

        var totalExported = 0

        // Export all tint + icon combinations
        for tintOption in allTints {
            for iconOption in allIcons {
                let folderName = "\(tintOption.name)_\(iconOption.name)"
                let variantPath = exportPath.appendingPathComponent(folderName, isDirectory: true)
                try? FileManager.default.createDirectory(at: variantPath, withIntermediateDirectories: true)

                let config = WidgetExportConfig(
                    moodTint: tintOption.tint,
                    moodImages: iconOption.images
                )

                let count = await exportVotingLayoutsForConfig(config: config, to: variantPath)
                totalExported += count
                print("  Exported \(count) voting layouts to \(folderName)/")
            }
        }

        print("📸 Total \(totalExported) voting layouts exported to: \(exportPath.path)")
        return exportPath
    }

    /// Exports voting layouts for a single tint/icon configuration
    private static func exportVotingLayoutsForConfig(config: WidgetExportConfig, to folder: URL) async -> Int {
        var count = 0

        for colorScheme in [ColorScheme.light, ColorScheme.dark] {
            let schemeName = colorScheme == .light ? "light" : "dark"

            // Small voting layout
            await exportVotingLayout(size: .small, config: config, colorScheme: colorScheme, to: folder, name: "voting_\(schemeName)_small")
            count += 1

            // Medium voting layout
            await exportVotingLayout(size: .medium, config: config, colorScheme: colorScheme, to: folder, name: "voting_\(schemeName)_medium")
            count += 1

            // Large voting layout
            await exportVotingLayout(size: .large, config: config, colorScheme: colorScheme, to: folder, name: "voting_\(schemeName)_large")
            count += 1
        }

        return count
    }

    /// Exports a single voting layout
    private static func exportVotingLayout(size: WidgetSize, config: WidgetExportConfig, colorScheme: ColorScheme, to folder: URL, name: String) async {
        let votingSize: ExportableVotingView.Size
        switch size {
        case .small: votingSize = .small
        case .medium: votingSize = .medium
        case .large: votingSize = .large
        }

        let content = ExportableVotingView(
            size: votingSize,
            config: config,
            promptText: "How are you feeling today?"
        )

        let view = ExportableWidgetContainer(
            width: size.pointSize.width,
            height: size.pointSize.height,
            colorScheme: colorScheme,
            useSystemBackground: false
        ) {
            content
        }

        await renderAndSave(view: view, size: size, to: folder, name: name)
    }

    // MARK: - Vote Widget Export

    private static func exportVoteWidget(hasVoted: Bool, mood: Mood?, size: WidgetSize, config: WidgetExportConfig, colorScheme: ColorScheme, to folder: URL, name: String) async {
        let content: AnyView

        if hasVoted, let mood = mood {
            content = AnyView(
                ExportableVotedStatsView(
                    size: size == .small ? .small : .medium,
                    config: config,
                    mood: mood,
                    totalEntries: sampleTotalEntries,
                    moodCounts: sampleMoodCounts
                )
            )
        } else {
            content = AnyView(
                ExportableVotingView(
                    size: size == .small ? .small : .medium,
                    config: config,
                    promptText: "How are you feeling today?"
                )
            )
        }

        let view = ExportableWidgetContainer(
            width: size.pointSize.width,
            height: size.pointSize.height,
            colorScheme: colorScheme,
            useSystemBackground: hasVoted
        ) {
            content
        }

        await renderAndSave(view: view, size: size, to: folder, name: name)
    }

    // MARK: - Timeline Widget Export

    private static func exportTimelineWidget(hasVoted: Bool, size: WidgetSize, config: WidgetExportConfig, colorScheme: ColorScheme, to folder: URL, name: String) async {
        let timelineData = config.createTimelineData(count: size == .large ? 10 : (size == .medium ? 5 : 1))
        let promptText = "How are you feeling today?"

        let content: AnyView
        switch size {
        case .small:
            content = AnyView(
                ExportableTimelineSmallView(
                    config: config,
                    timelineData: timelineData.first,
                    hasVoted: hasVoted,
                    promptText: promptText
                )
            )
        case .medium:
            content = AnyView(
                ExportableTimelineMediumView(
                    config: config,
                    timelineData: Array(timelineData.prefix(5)),
                    hasVoted: hasVoted,
                    promptText: promptText
                )
            )
        case .large:
            content = AnyView(
                ExportableTimelineLargeView(
                    config: config,
                    timelineData: timelineData,
                    hasVoted: hasVoted,
                    promptText: promptText
                )
            )
        }

        let view = ExportableWidgetContainer(
            width: size.pointSize.width,
            height: size.pointSize.height,
            colorScheme: colorScheme,
            useSystemBackground: hasVoted
        ) {
            content
        }

        await renderAndSave(view: view, size: size, to: folder, name: name)
    }

    // MARK: - Live Activity Export

    private static func exportLiveActivity(hasLogged: Bool, mood: Mood?, streak: Int, config: WidgetExportConfig, colorScheme: ColorScheme, to folder: URL, name: String) async {
        // Opaque background colors for Live Activity (no transparency)
        let backgroundColor = colorScheme == .dark
            ? Color(red: 0.11, green: 0.11, blue: 0.12)
            : Color(red: 0.95, green: 0.95, blue: 0.97)

        let content = ExportableLiveActivityView(
            config: config,
            streak: streak,
            hasLoggedToday: hasLogged,
            mood: mood
        )

        let view = content
            .environment(\.colorScheme, colorScheme)
            .frame(width: liveActivitySize.width, height: liveActivitySize.height)
            .background(backgroundColor)
            .clipShape(RoundedRectangle(cornerRadius: 20, style: .continuous))

        await renderAndSaveLiveActivity(view: view, to: folder, name: name)
    }

    // MARK: - Render and Save

    private static func renderAndSave<V: View>(view: V, size: WidgetSize, to folder: URL, name: String) async {
        let renderer = ImageRenderer(content: view.frame(width: size.pointSize.width, height: size.pointSize.height))
        renderer.scale = 3.0 // 3x for high res

        if let image = renderer.uiImage {
            let url = folder.appendingPathComponent("\(name).png")
            if let data = image.pngData() {
                try? data.write(to: url)
            }
        }
    }

    private static func renderAndSaveLiveActivity<V: View>(view: V, to folder: URL, name: String) async {
        let renderer = ImageRenderer(content: view.frame(width: liveActivitySize.width, height: liveActivitySize.height))
        renderer.scale = 3.0

        if let image = renderer.uiImage {
            let url = folder.appendingPathComponent("\(name).png")
            if let data = image.pngData() {
                try? data.write(to: url)
            }
        }
    }
}
#endif
