//
//  VideoListLayout.swift
//  Yattee
//
//  Layout options for video listing views.
//

import SwiftUI

/// Layout type for video lists.
enum VideoListLayout: String, CaseIterable {
    case list
    case grid

    var displayName: LocalizedStringKey {
        switch self {
        case .list: "viewOptions.layout.list"
        case .grid: "viewOptions.layout.grid"
        }
    }

    var systemImage: String {
        switch self {
        case .list: "list.bullet"
        case .grid: "square.grid.2x2"
        }
    }
}

// MARK: - Grid Layout Helpers

/// Constants for grid layout calculations.
enum GridConstants {
    /// Minimum width for a video card thumbnail to remain usable.
    static let minCardWidth: CGFloat = {
        #if os(tvOS)
        200
        #else
        100
        #endif
    }()

    /// Spacing between grid items.
    static let spacing: CGFloat = {
        #if os(tvOS)
        48
        #else
        12
        #endif
    }()

    /// Horizontal padding for the grid container.
    static let horizontalPadding: CGFloat = 32

    /// Maximum allowed columns (to prevent excessive density).
    static let maxAllowedColumns = 6

    /// Minimum allowed columns. tvOS doesn't make sense with a single column.
    static let minAllowedColumns: Int = {
        #if os(tvOS)
        2
        #else
        1
        #endif
    }()

    /// Threshold for compact card styling (columns >= this use compact mode).
    static let compactThreshold = 3
}

/// Calculates the maximum number of grid columns that fit within a given width.
/// - Parameters:
///   - width: Available container width
///   - minCardWidth: Minimum width per card (defaults to GridConstants.minCardWidth)
///   - spacing: Spacing between cards (defaults to GridConstants.spacing)
/// - Returns: Maximum columns that fit, clamped between 1 and maxAllowedColumns
func maxGridColumns(
    forWidth width: CGFloat,
    minCardWidth: CGFloat = GridConstants.minCardWidth,
    spacing: CGFloat = GridConstants.spacing
) -> Int {
    let availableWidth = width - GridConstants.horizontalPadding
    // Formula: availableWidth = (columns * minCardWidth) + ((columns - 1) * spacing)
    // Solving for columns: columns = (availableWidth + spacing) / (minCardWidth + spacing)
    let maxColumns = Int((availableWidth + spacing) / (minCardWidth + spacing))
    return max(GridConstants.minAllowedColumns, min(maxColumns, GridConstants.maxAllowedColumns))
}

/// Creates grid columns for a LazyVGrid with the specified count.
/// - Parameter count: Number of columns
/// - Returns: Array of flexible GridItems with top alignment
func makeGridColumns(count: Int) -> [GridItem] {
    Array(repeating: GridItem(.flexible(), spacing: GridConstants.spacing, alignment: .top), count: max(GridConstants.minAllowedColumns, count))
}

// MARK: - Grid Layout Configuration

/// Encapsulates grid layout calculations for views with grid/list layouts.
///
/// Use this to eliminate repeated computed properties across grid-enabled views.
/// Create an instance with the current view width and user-selected column count,
/// then use the computed properties for layout decisions.
///
/// Usage:
/// ```swift
/// @State private var viewWidth: CGFloat = 0
/// @AppStorage("myView.gridColumns") private var gridColumns = 2
///
/// private var gridConfig: GridLayoutConfiguration {
///     GridLayoutConfiguration(viewWidth: viewWidth, gridColumns: gridColumns)
/// }
///
/// // Then use:
/// // gridConfig.effectiveColumns - actual column count
/// // gridConfig.isCompactCards - whether to use compact card styling
/// // gridConfig.columns - GridItem array for LazyVGrid
/// // gridConfig.maxColumns - for ViewOptionsSheet
/// ```
struct GridLayoutConfiguration {
    let viewWidth: CGFloat
    let gridColumns: Int

    /// Maximum columns that fit in the current width.
    var maxColumns: Int {
        maxGridColumns(forWidth: viewWidth)
    }

    /// Effective column count, clamped to valid range.
    var effectiveColumns: Int {
        min(max(GridConstants.minAllowedColumns, gridColumns), max(GridConstants.minAllowedColumns, maxColumns))
    }

    /// Whether cards should use compact styling (3+ columns).
    var isCompactCards: Bool {
        effectiveColumns >= GridConstants.compactThreshold
    }

    /// GridItem array for LazyVGrid columns parameter.
    var columns: [GridItem] {
        makeGridColumns(count: effectiveColumns)
    }
}
