//
//  CardLayouts.swift
//  CasinoKit
//
//  Layout views for displaying multiple cards (hand, fan, grid).
//

import SwiftUI

// MARK: - Card Hand

/// A horizontal scrolling row of cards, like a hand in a card game.
public struct CardHand: View {
    /// The cards in the hand.
    public let cards: [Card]
    
    /// Whether each card is face up.
    public var faceUp: Bool
    
    /// The width of each card.
    public var cardWidth: CGFloat
    
    /// The overlap amount between cards (negative for overlap, positive for spacing).
    public var overlap: CGFloat
    
    /// Creates a card hand view.
    /// - Parameters:
    ///   - cards: The cards to display.
    ///   - faceUp: Whether cards are face up (default: true).
    ///   - cardWidth: Width of each card (default: 80).
    ///   - overlap: Overlap between cards, negative for overlap (default: -30).
    public init(
        cards: [Card],
        faceUp: Bool = true,
        cardWidth: CGFloat = CasinoDesign.Size.cardWidth,
        overlap: CGFloat = -CasinoDesign.Spacing.xLarge
    ) {
        self.cards = cards
        self.faceUp = faceUp
        self.cardWidth = cardWidth
        self.overlap = overlap
    }
    
    public var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: overlap) {
                ForEach(Array(cards.enumerated()), id: \.element.id) { index, card in
                    CardView(card: card, isFaceUp: faceUp, cardWidth: cardWidth)
                        .zIndex(Double(index))
                }
            }
            .padding(.horizontal, CasinoDesign.Spacing.medium)
            .padding(.vertical, CasinoDesign.Spacing.small)
        }
    }
}

// MARK: - Card Fan

/// A fan-shaped arrangement of cards.
public struct CardFan: View {
    /// The cards to display.
    public let cards: [Card]
    
    /// Whether each card is face up.
    public var faceUp: Bool
    
    /// The width of each card.
    public var cardWidth: CGFloat
    
    /// The total angle span of the fan in degrees.
    public var angleSpan: Double
    
    /// Creates a fan of cards.
    /// - Parameters:
    ///   - cards: The cards to display.
    ///   - faceUp: Whether cards are face up (default: true).
    ///   - cardWidth: Width of each card (default: 100).
    ///   - angleSpan: Total angle span in degrees (default: 60).
    public init(
        cards: [Card],
        faceUp: Bool = true,
        cardWidth: CGFloat = CasinoDesign.Size.cardWidthLarge,
        angleSpan: Double = 60
    ) {
        self.cards = cards
        self.faceUp = faceUp
        self.cardWidth = cardWidth
        self.angleSpan = angleSpan
    }
    
    public var body: some View {
        ZStack {
            ForEach(Array(cards.enumerated()), id: \.element.id) { index, card in
                let angle = angleForCard(at: index)
                
                CardView(card: card, isFaceUp: faceUp, cardWidth: cardWidth)
                    .rotationEffect(.degrees(angle), anchor: .bottom)
                    .offset(y: -cardWidth * 0.3)
                    .zIndex(Double(index))
            }
        }
        .frame(height: cardWidth * CasinoDesign.Size.cardAspectRatio + CasinoDesign.Spacing.xLarge)
    }
    
    private func angleForCard(at index: Int) -> Double {
        guard cards.count > 1 else { return 0 }
        let step = angleSpan / Double(cards.count - 1)
        return -angleSpan / 2 + step * Double(index)
    }
}

// MARK: - Cards Grid

/// A grid view displaying cards.
public struct CardsGrid: View {
    /// The cards to display.
    public let cards: [Card]
    
    /// Whether each card is face up.
    public var faceUp: Bool
    
    /// The minimum width for each card.
    public var minCardWidth: CGFloat
    
    /// Spacing between cards.
    public var spacing: CGFloat
    
    /// Creates a grid showing specific cards.
    /// - Parameters:
    ///   - cards: The cards to display.
    ///   - faceUp: Whether cards are face up (default: true).
    ///   - minCardWidth: Minimum width for each card (default: 80).
    ///   - spacing: Spacing between cards (default: 10).
    public init(
        cards: [Card],
        faceUp: Bool = true,
        minCardWidth: CGFloat = CasinoDesign.Size.cardWidth,
        spacing: CGFloat = CasinoDesign.Spacing.small
    ) {
        self.cards = cards
        self.faceUp = faceUp
        self.minCardWidth = minCardWidth
        self.spacing = spacing
    }
    
    public var body: some View {
        ScrollView {
            LazyVGrid(
                columns: [GridItem(.adaptive(minimum: minCardWidth), spacing: spacing)],
                spacing: spacing
            ) {
                ForEach(cards) { card in
                    CardView(card: card, isFaceUp: faceUp, cardWidth: minCardWidth)
                }
            }
            .padding(spacing)
        }
    }
}

// MARK: - Previews

#Preview("Card Hand") {
    ZStack {
        Color(red: 0.05, green: 0.35, blue: 0.15)
            .ignoresSafeArea()
        
        CardHand(cards: [
            Card(suit: .hearts, rank: .ace),
            Card(suit: .hearts, rank: .king),
            Card(suit: .hearts, rank: .queen),
            Card(suit: .hearts, rank: .jack),
            Card(suit: .hearts, rank: .ten)
        ])
    }
}

#Preview("Card Fan") {
    ZStack {
        Color(red: 0.05, green: 0.35, blue: 0.15)
            .ignoresSafeArea()
        
        CardFan(cards: [
            Card(suit: .spades, rank: .ace),
            Card(suit: .hearts, rank: .king),
            Card(suit: .diamonds, rank: .queen),
            Card(suit: .clubs, rank: .jack),
            Card(suit: .spades, rank: .ten)
        ])
        .padding()
    }
}

#Preview("Cards Grid") {
    CardsGrid(cards: Suit.allCases.flatMap { suit in
        [Rank.ace, .king, .queen, .jack].map { rank in
            Card(suit: suit, rank: rank)
        }
    })
}

