import UIKit

// MARK: - UI Configuration
public struct ImageEditorUIConfig {

    // MARK: - Feature Toggles
    public var enableAdjustments: Bool = true
    public var enableFilters: Bool = true
    public var enableTransforms: Bool = true
    public var enableLayers: Bool = true
    public var enableDrawing: Bool = true
    public var enableText: Bool = true
    public var enableStickers: Bool = true
    public var enableLUT: Bool = true

    // MARK: - UI Toggles
    public var showTopToolbar: Bool = true
    public var showBottomToolbar: Bool = true
    public var enableUndo: Bool = true
    public var enableRedo: Bool = true
    public var enableReset: Bool = true
    public var enableExport: Bool = true
    public var showCloseButton: Bool = true
    public var showLoadButton: Bool = false
    public var showShareButton: Bool = false
    public var showInfoButton: Bool = false

    // MARK: - Export Options
    public var allowedExportFormats: [String] = ["jpeg", "png", "heic"]
    public var defaultExportFormat: String = "jpeg"
    public var defaultExportQuality: Float = 0.9
    public var maxExportDimension: Int? = nil

    // MARK: - Filter Configuration
    public var availableFilters: [String]? = nil // nil = all filters
    public var defaultFilterIntensity: Float = 1.0
    public var showFilterIntensitySlider: Bool = true
    public var filterIntensityRange: (min: Float, max: Float) = (0.0, 1.0)
    public var showFilterPreviews: Bool = true
    public var filterPreviewSize: CGFloat = 100
    public var enableFilterComparison: Bool = true // Before/after comparison
    public var allowMultipleFilters: Bool = false

    // MARK: - Adjustment Configuration
    public var availableAdjustments: [String]? = nil // nil = all adjustments
    public var adjustmentRanges: [String: (min: Float, max: Float)] = [
        "brightness": (-1.0, 1.0),
        "contrast": (0.5, 1.5),
        "saturation": (0.0, 2.0),
        "exposure": (-2.0, 2.0),
        "temperature": (-1.0, 1.0),
        "tint": (-1.0, 1.0),
        "highlights": (-1.0, 1.0),
        "shadows": (-1.0, 1.0),
        "sharpness": (0.0, 2.0),
        "vignette": (0.0, 2.0)
    ]
    public var adjustmentSteps: [String: Float] = [:] // Slider step increments
    public var adjustmentDefaults: [String: Float] = [:] // Default values
    public var showAdjustmentValues: Bool = true
    public var showAdjustmentReset: Bool = true
    public var adjustmentLivePreview: Bool = true

    // MARK: - Transform Configuration
    public var enableCrop: Bool = true
    public var enableRotate: Bool = true
    public var enableFlip: Bool = true
    public var enableResize: Bool = true
    public var rotationStep: Float = 90 // degrees
    public var cropAspectRatios: [(String, Float?)] = [("Free", nil), ("1:1", 1.0), ("4:3", 4.0/3.0), ("16:9", 16.0/9.0)]
    public var enableFreeformCrop: Bool = true
    public var showCropGrid: Bool = true
    public var cropGridLines: Int = 2
    public var allowRotationBeyondStep: Bool = true
    public var rotationGestureEnabled: Bool = true

    // MARK: - Drawing Configuration
    public var defaultBrushSize: Float = 5.0
    public var defaultBrushColor: UIColor = .black
    public var defaultBrushOpacity: Float = 1.0
    public var enableEraser: Bool = true
    public var minBrushSize: Float = 1.0
    public var maxBrushSize: Float = 50.0
    public var brushSizeStep: Float = 1.0
    public var availableBrushColors: [UIColor]? = nil // nil = color picker
    public var enableBrushOpacity: Bool = true
    public var enableBrushBlending: Bool = true
    public var showBrushPreview: Bool = true
    public var enablePressureSensitivity: Bool = true
    public var drawingSmoothing: Float = 0.5 // 0.0 - 1.0

    // MARK: - Layer Configuration
    public var maxLayers: Int = 10
    public var defaultLayerOpacity: Float = 1.0
    public var availableBlendModes: [String]? = nil // nil = all blend modes

    // MARK: - Text Configuration
    public var defaultTextColor: UIColor = .black
    public var defaultTextSize: Float = 24.0
    public var availableFonts: [String]? = nil // nil = system fonts
    public var enableTextShadow: Bool = true
    public var enableTextStroke: Bool = true

    // MARK: - Performance Configuration
    public var maxHistoryStates: Int = 50
    public var enableMemoryMonitoring: Bool = true
    public var maxPreviewDimension: Int? = 2048
    public var enableGPUAcceleration: Bool = true
    public var autoSaveEnabled: Bool = false
    public var autoSaveInterval: TimeInterval = 30.0
    public var preloadFilters: Bool = true
    public var cacheProcessedImages: Bool = true
    public var lowMemoryMode: Bool = false

    // MARK: - Color Theme
    public var backgroundColor: UIColor = .black
    public var toolbarBackgroundColor: UIColor = UIColor(white: 0.1, alpha: 0.95)
    public var secondaryBackgroundColor: UIColor = UIColor(white: 0.2, alpha: 1.0)
    public var accentColor: UIColor = .systemBlue
    public var textColor: UIColor = .white
    public var secondaryTextColor: UIColor = UIColor(white: 0.7, alpha: 1.0)
    public var destructiveColor: UIColor = .systemRed
    public var successColor: UIColor = .systemGreen
    public var warningColor: UIColor = .systemYellow
    public var borderColor: UIColor = UIColor(white: 0.3, alpha: 1.0)
    public var selectedColor: UIColor = .systemBlue

    // MARK: - UI Behavior
    public var enableHapticFeedback: Bool = true
    public var enableAnimations: Bool = true
    public var animationDuration: TimeInterval = 0.3
    public var toolbarAnimated: Bool = true
    public var panelAnimated: Bool = true
    public var enableDoubleTapToZoom: Bool = true
    public var doubleTapZoomScale: CGFloat = 2.0
    public var maxZoomScale: CGFloat = 5.0
    public var minZoomScale: CGFloat = 0.5

    // MARK: - Gesture Configuration
    public var enablePinchToZoom: Bool = true
    public var enablePanGesture: Bool = true
    public var enableRotationGesture: Bool = true
    public var enableSwipeGestures: Bool = false
    public var swipeToUndoEnabled: Bool = false
    public var longPressForOptions: Bool = true

    // MARK: - Export Advanced
    public var showExportProgress: Bool = true
    public var exportProgressStyle: String = "bar" // "bar", "circular", "minimal"
    public var embedMetadata: Bool = true
    public var preserveExif: Bool = true
    public var compressionMethod: String = "balanced" // "fast", "balanced", "best"
    public var exportToPhotos: Bool = false
    public var exportShareSheet: Bool = true

    // MARK: - Validation & Constraints
    public var minImageDimension: Int = 100
    public var maxImageDimension: Int = 8192
    public var allowedImageFormats: [String] = ["jpg", "jpeg", "png", "heic", "heif"]
    public var maxFileSize: Int? = nil // bytes, nil = no limit
    public var warnOnLargeImages: Bool = true
    public var largeImageThreshold: Int = 4096

    // MARK: - Toolbar Layout
    public var toolbarPosition: String = "top" // "top", "bottom", "floating"
    public var toolbarHeight: CGFloat = 60
    public var toolbarPadding: CGFloat = 16
    public var toolbarSpacing: CGFloat = 12
    public var bottomToolbarLayout: String = "scrollable" // "scrollable", "grid", "grouped"
    public var toolbarCollapsible: Bool = false

    // MARK: - Panel Configuration
    public var panelPosition: String = "bottom" // "bottom", "side", "overlay"
    public var panelHeight: CGFloat = 200
    public var panelDismissable: Bool = true
    public var panelDragHandle: Bool = true
    public var panelBlurEffect: Bool = true

    // MARK: - Localization
    public var localizedStrings: [String: String] = [:]
    public var dateFormat: String = "yyyy-MM-dd HH:mm:ss"
    public var useSystemLanguage: Bool = true

    // MARK: - Initialization
    public init() {}

    // MARK: - Preset Configurations
    public static func minimal() -> ImageEditorUIConfig {
        var config = ImageEditorUIConfig()
        config.enableLayers = false
        config.enableDrawing = false
        config.enableText = false
        config.enableStickers = false
        config.enableLUT = false
        return config
    }

    public static func photoEditor() -> ImageEditorUIConfig {
        var config = ImageEditorUIConfig()
        config.enableStickers = false
        config.enableText = false
        return config
    }

    public static func socialMedia() -> ImageEditorUIConfig {
        var config = ImageEditorUIConfig()
        config.availableFilters = ["vintage", "dramatic", "noir", "fade", "instant"]
        config.maxExportDimension = 2048
        return config
    }

    public static func professional() -> ImageEditorUIConfig {
        var config = ImageEditorUIConfig()
        config.maxHistoryStates = 100
        config.allowedExportFormats = ["jpeg", "png", "heic"]
        config.maxExportDimension = nil // Full resolution
        return config
    }

    // MARK: - Helper Methods
    public func localized(_ key: String) -> String {
        return localizedStrings[key] ?? key
    }

    public mutating func setTheme(light: Bool) {
        if light {
            backgroundColor = .white
            toolbarBackgroundColor = UIColor(white: 0.95, alpha: 0.95)
            secondaryBackgroundColor = UIColor(white: 0.9, alpha: 1.0)
            textColor = .black
            secondaryTextColor = UIColor(white: 0.3, alpha: 1.0)
        } else {
            backgroundColor = .black
            toolbarBackgroundColor = UIColor(white: 0.1, alpha: 0.95)
            secondaryBackgroundColor = UIColor(white: 0.2, alpha: 1.0)
            textColor = .white
            secondaryTextColor = UIColor(white: 0.7, alpha: 1.0)
        }
    }

    public func isAdjustmentEnabled(_ adjustment: String) -> Bool {
        guard let available = availableAdjustments else { return true }
        return available.contains(adjustment)
    }

    public func isFilterEnabled(_ filter: String) -> Bool {
        guard let available = availableFilters else { return true }
        return available.contains(filter)
    }

    public func isBlendModeEnabled(_ mode: String) -> Bool {
        guard let available = availableBlendModes else { return true }
        return available.contains(mode)
    }

    public func getAdjustmentRange(_ adjustment: String) -> (min: Float, max: Float) {
        return adjustmentRanges[adjustment] ?? (-1.0, 1.0)
    }
}

// MARK: - Codable Support (for serialization from React Native)
extension ImageEditorUIConfig: Codable {
    enum CodingKeys: String, CodingKey {
        case enableAdjustments
        case enableFilters
        case enableTransforms
        case enableLayers
        case enableDrawing
        case enableText
        case enableStickers
        case enableLUT
        case showTopToolbar
        case showBottomToolbar
        case enableUndo
        case enableRedo
        case enableReset
        case enableExport
        case allowedExportFormats
        case defaultExportFormat
        case defaultExportQuality
        case maxExportDimension
        case availableFilters
        case defaultFilterIntensity
        case availableAdjustments
        case enableCrop
        case enableRotate
        case enableFlip
        case enableResize
        case rotationStep
        case defaultBrushSize
        case defaultBrushOpacity
        case enableEraser
        case minBrushSize
        case maxBrushSize
        case maxLayers
        case defaultLayerOpacity
        case availableBlendModes
        case defaultTextSize
        case availableFonts
        case enableTextShadow
        case enableTextStroke
        case maxHistoryStates
        case enableMemoryMonitoring
        case maxPreviewDimension
        case enableGPUAcceleration
        case localizedStrings
    }

    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)

        self.enableAdjustments = try container.decodeIfPresent(Bool.self, forKey: .enableAdjustments) ?? true
        self.enableFilters = try container.decodeIfPresent(Bool.self, forKey: .enableFilters) ?? true
        self.enableTransforms = try container.decodeIfPresent(Bool.self, forKey: .enableTransforms) ?? true
        self.enableLayers = try container.decodeIfPresent(Bool.self, forKey: .enableLayers) ?? true
        self.enableDrawing = try container.decodeIfPresent(Bool.self, forKey: .enableDrawing) ?? true
        self.enableText = try container.decodeIfPresent(Bool.self, forKey: .enableText) ?? true
        self.enableStickers = try container.decodeIfPresent(Bool.self, forKey: .enableStickers) ?? true
        self.enableLUT = try container.decodeIfPresent(Bool.self, forKey: .enableLUT) ?? true

        self.showTopToolbar = try container.decodeIfPresent(Bool.self, forKey: .showTopToolbar) ?? true
        self.showBottomToolbar = try container.decodeIfPresent(Bool.self, forKey: .showBottomToolbar) ?? true
        self.enableUndo = try container.decodeIfPresent(Bool.self, forKey: .enableUndo) ?? true
        self.enableRedo = try container.decodeIfPresent(Bool.self, forKey: .enableRedo) ?? true
        self.enableReset = try container.decodeIfPresent(Bool.self, forKey: .enableReset) ?? true
        self.enableExport = try container.decodeIfPresent(Bool.self, forKey: .enableExport) ?? true

        self.allowedExportFormats = try container.decodeIfPresent([String].self, forKey: .allowedExportFormats) ?? ["jpeg", "png", "heic"]
        self.defaultExportFormat = try container.decodeIfPresent(String.self, forKey: .defaultExportFormat) ?? "jpeg"
        self.defaultExportQuality = try container.decodeIfPresent(Float.self, forKey: .defaultExportQuality) ?? 0.9
        self.maxExportDimension = try container.decodeIfPresent(Int.self, forKey: .maxExportDimension)

        self.availableFilters = try container.decodeIfPresent([String].self, forKey: .availableFilters)
        self.defaultFilterIntensity = try container.decodeIfPresent(Float.self, forKey: .defaultFilterIntensity) ?? 1.0
        self.availableAdjustments = try container.decodeIfPresent([String].self, forKey: .availableAdjustments)

        self.enableCrop = try container.decodeIfPresent(Bool.self, forKey: .enableCrop) ?? true
        self.enableRotate = try container.decodeIfPresent(Bool.self, forKey: .enableRotate) ?? true
        self.enableFlip = try container.decodeIfPresent(Bool.self, forKey: .enableFlip) ?? true
        self.enableResize = try container.decodeIfPresent(Bool.self, forKey: .enableResize) ?? true
        self.rotationStep = try container.decodeIfPresent(Float.self, forKey: .rotationStep) ?? 90

        self.defaultBrushSize = try container.decodeIfPresent(Float.self, forKey: .defaultBrushSize) ?? 5.0
        self.defaultBrushOpacity = try container.decodeIfPresent(Float.self, forKey: .defaultBrushOpacity) ?? 1.0
        self.enableEraser = try container.decodeIfPresent(Bool.self, forKey: .enableEraser) ?? true
        self.minBrushSize = try container.decodeIfPresent(Float.self, forKey: .minBrushSize) ?? 1.0
        self.maxBrushSize = try container.decodeIfPresent(Float.self, forKey: .maxBrushSize) ?? 50.0

        self.maxLayers = try container.decodeIfPresent(Int.self, forKey: .maxLayers) ?? 10
        self.defaultLayerOpacity = try container.decodeIfPresent(Float.self, forKey: .defaultLayerOpacity) ?? 1.0
        self.availableBlendModes = try container.decodeIfPresent([String].self, forKey: .availableBlendModes)

        self.defaultTextSize = try container.decodeIfPresent(Float.self, forKey: .defaultTextSize) ?? 24.0
        self.availableFonts = try container.decodeIfPresent([String].self, forKey: .availableFonts)
        self.enableTextShadow = try container.decodeIfPresent(Bool.self, forKey: .enableTextShadow) ?? true
        self.enableTextStroke = try container.decodeIfPresent(Bool.self, forKey: .enableTextStroke) ?? true

        self.maxHistoryStates = try container.decodeIfPresent(Int.self, forKey: .maxHistoryStates) ?? 50
        self.enableMemoryMonitoring = try container.decodeIfPresent(Bool.self, forKey: .enableMemoryMonitoring) ?? true
        self.maxPreviewDimension = try container.decodeIfPresent(Int.self, forKey: .maxPreviewDimension)
        self.enableGPUAcceleration = try container.decodeIfPresent(Bool.self, forKey: .enableGPUAcceleration) ?? true

        self.localizedStrings = try container.decodeIfPresent([String: String].self, forKey: .localizedStrings) ?? [:]

        // Use default values for color properties (not decoded from JSON)
        self.backgroundColor = .black
        self.toolbarBackgroundColor = UIColor(white: 0.1, alpha: 0.95)
        self.secondaryBackgroundColor = UIColor(white: 0.2, alpha: 1.0)
        self.accentColor = .systemBlue
        self.textColor = .white
        self.secondaryTextColor = UIColor(white: 0.7, alpha: 1.0)
        self.defaultBrushColor = .black
        self.defaultTextColor = .black
        self.adjustmentRanges = [
            "brightness": (-1.0, 1.0),
            "contrast": (0.5, 1.5),
            "saturation": (0.0, 2.0),
            "exposure": (-2.0, 2.0),
            "temperature": (-1.0, 1.0),
            "tint": (-1.0, 1.0),
            "highlights": (-1.0, 1.0),
            "shadows": (-1.0, 1.0),
            "sharpness": (0.0, 2.0),
            "vignette": (0.0, 2.0)
        ]
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)

        try container.encode(enableAdjustments, forKey: .enableAdjustments)
        try container.encode(enableFilters, forKey: .enableFilters)
        try container.encode(enableTransforms, forKey: .enableTransforms)
        try container.encode(enableLayers, forKey: .enableLayers)
        try container.encode(enableDrawing, forKey: .enableDrawing)
        try container.encode(enableText, forKey: .enableText)
        try container.encode(enableStickers, forKey: .enableStickers)
        try container.encode(enableLUT, forKey: .enableLUT)

        try container.encode(showTopToolbar, forKey: .showTopToolbar)
        try container.encode(showBottomToolbar, forKey: .showBottomToolbar)
        try container.encode(enableUndo, forKey: .enableUndo)
        try container.encode(enableRedo, forKey: .enableRedo)
        try container.encode(enableReset, forKey: .enableReset)
        try container.encode(enableExport, forKey: .enableExport)

        try container.encode(allowedExportFormats, forKey: .allowedExportFormats)
        try container.encode(defaultExportFormat, forKey: .defaultExportFormat)
        try container.encode(defaultExportQuality, forKey: .defaultExportQuality)
        try container.encodeIfPresent(maxExportDimension, forKey: .maxExportDimension)

        try container.encodeIfPresent(availableFilters, forKey: .availableFilters)
        try container.encode(defaultFilterIntensity, forKey: .defaultFilterIntensity)
        try container.encodeIfPresent(availableAdjustments, forKey: .availableAdjustments)

        try container.encode(enableCrop, forKey: .enableCrop)
        try container.encode(enableRotate, forKey: .enableRotate)
        try container.encode(enableFlip, forKey: .enableFlip)
        try container.encode(enableResize, forKey: .enableResize)
        try container.encode(rotationStep, forKey: .rotationStep)

        try container.encode(defaultBrushSize, forKey: .defaultBrushSize)
        try container.encode(defaultBrushOpacity, forKey: .defaultBrushOpacity)
        try container.encode(enableEraser, forKey: .enableEraser)
        try container.encode(minBrushSize, forKey: .minBrushSize)
        try container.encode(maxBrushSize, forKey: .maxBrushSize)

        try container.encode(maxLayers, forKey: .maxLayers)
        try container.encode(defaultLayerOpacity, forKey: .defaultLayerOpacity)
        try container.encodeIfPresent(availableBlendModes, forKey: .availableBlendModes)

        try container.encode(defaultTextSize, forKey: .defaultTextSize)
        try container.encodeIfPresent(availableFonts, forKey: .availableFonts)
        try container.encode(enableTextShadow, forKey: .enableTextShadow)
        try container.encode(enableTextStroke, forKey: .enableTextStroke)

        try container.encode(maxHistoryStates, forKey: .maxHistoryStates)
        try container.encode(enableMemoryMonitoring, forKey: .enableMemoryMonitoring)
        try container.encodeIfPresent(maxPreviewDimension, forKey: .maxPreviewDimension)
        try container.encode(enableGPUAcceleration, forKey: .enableGPUAcceleration)

        try container.encode(localizedStrings, forKey: .localizedStrings)
    }
}
