//
//  GlassBackground.swift
//  Yattee
//
//  Adaptive glass background that uses liquid glass on iOS 26+ and falls back to materials on older versions.
//

import SwiftUI

// MARK: - Glass Style

/// Style options for the glass background effect
enum GlassStyle {
    /// Clear glass with minimal blur - subtle transparency
    case clear
    /// Regular glass with standard blur and reflection
    case regular
    /// Tinted glass with a color overlay
    case tinted(Color)
}

// MARK: - Glass Shape

/// Shape options for the glass background
enum GlassShape {
    /// Rectangle with corner radius
    case rect(cornerRadius: CGFloat)
    /// Capsule shape
    case capsule
    /// Circle shape
    case circle
}

// MARK: - Fallback Material

/// Material to use on iOS versions before 26
enum GlassFallbackMaterial {
    case ultraThinMaterial
    case thinMaterial
    case regularMaterial
    case thickMaterial
    case ultraThickMaterial
}

// MARK: - Glass Background Modifier

/// A view modifier that applies liquid glass effect on iOS 26+ and falls back to materials on older versions
struct GlassBackgroundModifier: ViewModifier {
    let style: GlassStyle
    let shape: GlassShape
    let fallbackMaterial: GlassFallbackMaterial
    let colorScheme: ColorScheme?

    init(
        style: GlassStyle = .clear,
        shape: GlassShape = .rect(cornerRadius: 12),
        fallbackMaterial: GlassFallbackMaterial = .ultraThinMaterial,
        colorScheme: ColorScheme? = nil
    ) {
        self.style = style
        self.shape = shape
        self.fallbackMaterial = fallbackMaterial
        self.colorScheme = colorScheme
    }

    func body(content: Content) -> some View {
        #if os(iOS) || os(macOS)
        if #available(iOS 26.0, macOS 26.0, *) {
            content.modifier(LiquidGlassModifier(style: style, shape: shape, colorScheme: colorScheme))
        } else {
            content.modifier(FallbackGlassModifier(shape: shape, material: fallbackMaterial, colorScheme: colorScheme))
        }
        #else
        // tvOS doesn't have glassEffect, always use fallback material
        content.modifier(FallbackGlassModifier(shape: shape, material: fallbackMaterial, colorScheme: colorScheme))
        #endif
    }
}

// MARK: - iOS 26+ / macOS 26+ Liquid Glass

#if os(iOS) || os(macOS)
@available(iOS 26.0, macOS 26.0, *)
private struct LiquidGlassModifier: ViewModifier {
    let style: GlassStyle
    let shape: GlassShape
    let colorScheme: ColorScheme?

    func body(content: Content) -> some View {
        switch shape {
        case .rect(let cornerRadius):
            applyGlassEffect(to: content, shape: .rect(cornerRadius: cornerRadius))
        case .capsule:
            applyGlassEffect(to: content, shape: .capsule)
        case .circle:
            applyGlassEffect(to: content, shape: .circle)
        }
    }

    @ViewBuilder
    private func applyGlassEffect<S: Shape>(to content: Content, shape: S) -> some View {
        if let scheme = colorScheme {
            switch style {
            case .clear:
                content.glassEffect(.clear, in: shape).environment(\.colorScheme, scheme)
            case .regular:
                content.glassEffect(.regular, in: shape).environment(\.colorScheme, scheme)
            case .tinted(let color):
                content.glassEffect(.regular.tint(color), in: shape).environment(\.colorScheme, scheme)
            }
        } else {
            switch style {
            case .clear:
                content.glassEffect(.clear, in: shape)
            case .regular:
                content.glassEffect(.regular, in: shape)
            case .tinted(let color):
                content.glassEffect(.regular.tint(color), in: shape)
            }
        }
    }
}
#endif

// MARK: - Fallback for older iOS / macOS

private struct FallbackGlassModifier: ViewModifier {
    let shape: GlassShape
    let material: GlassFallbackMaterial
    let colorScheme: ColorScheme?

    func body(content: Content) -> some View {
        switch shape {
        case .rect(let cornerRadius):
            content
                .background(materialBackground)
                .clipShape(RoundedRectangle(cornerRadius: cornerRadius))
        case .capsule:
            content
                .background(materialBackground)
                .clipShape(Capsule())
        case .circle:
            content
                .background(materialBackground)
                .clipShape(Circle())
        }
    }

    @ViewBuilder
    private var materialBackground: some View {
        if let colorScheme {
            rawMaterialBackground.environment(\.colorScheme, colorScheme)
        } else {
            rawMaterialBackground
        }
    }

    @ViewBuilder
    private var rawMaterialBackground: some View {
        switch material {
        case .ultraThinMaterial:
            Rectangle().fill(.ultraThinMaterial)
        case .thinMaterial:
            Rectangle().fill(.thinMaterial)
        case .regularMaterial:
            Rectangle().fill(.regularMaterial)
        case .thickMaterial:
            Rectangle().fill(.thickMaterial)
        case .ultraThickMaterial:
            Rectangle().fill(.ultraThickMaterial)
        }
    }
}

// MARK: - View Extension

extension View {
    /// Applies a glass background effect that adapts to the platform
    /// - Parameters:
    ///   - style: The glass style (clear, regular, or tinted)
    ///   - shape: The shape of the glass background
    ///   - fallbackMaterial: The material to use on iOS < 26
    ///   - colorScheme: Optional color scheme to force (affects glass appearance on iOS 26+)
    /// - Returns: A view with the glass background applied
    func glassBackground(
        _ style: GlassStyle = .clear,
        in shape: GlassShape = .rect(cornerRadius: 12),
        fallback: GlassFallbackMaterial = .ultraThinMaterial,
        colorScheme: ColorScheme? = nil
    ) -> some View {
        modifier(GlassBackgroundModifier(style: style, shape: shape, fallbackMaterial: fallback, colorScheme: colorScheme))
    }
}
