import SwiftUI

struct KlondikeBoardView: View {
    @Bindable var viewModel: GameViewModel
    let layout: CardLayout
    let theme: GameTheme
    let cardFaceStyle: CardFaceStyle
    let cardBackDesign: CardBackDesign

    var body: some View {
        VStack(spacing: layout.horizontalPadding) {
            HStack(spacing: layout.horizontalPadding) {
                stockView
                wasteView

                // Empty gap at column 2 position
                Color.clear
                    .frame(width: layout.cardWidth, height: layout.cardHeight)

                ForEach(0..<min(4, viewModel.state.foundations.count), id: \.self) { index in
                    foundationView(index: index)
                }
            }
            .padding(.horizontal, layout.horizontalPadding)

            // Tableau row: 7 columns
            HStack(alignment: .top, spacing: layout.horizontalPadding) {
                ForEach(0..<min(7, viewModel.state.tableaus.count), id: \.self) { column in
                    CardStackView(
                        cards: viewModel.state.tableaus[column],
                        location: .tableau(column),
                        layout: layout,
                        cardFaceStyle: cardFaceStyle,
                        cardBackDesign: cardBackDesign,
                        viewModel: viewModel
                    )
                }
            }
            .padding(.horizontal, layout.horizontalPadding)

        }
    }

    private var stockView: some View {
        Group {
            if viewModel.state.stock.isEmpty {
                CardView(card: nil, cardFaceStyle: cardFaceStyle, cardBackDesign: cardBackDesign,
                         size: layout.cardSize())
                    .overlay {
                        Image(systemName: "arrow.clockwise")
                            .font(.system(size: layout.cardWidth * 0.3))
                            .foregroundStyle(.white.opacity(0.5))
                    }
                    .accessibilityLabel(Text("Stock pile, empty. Double tap to recycle waste pile."))
            } else {
                CardView(card: Card(suit: .spades, rank: .ace),
                         cardFaceStyle: cardFaceStyle, cardBackDesign: cardBackDesign,
                         size: layout.cardSize())
                    .accessibilityLabel(Text("Stock pile, \(viewModel.state.stock.count) cards remaining"))
                    .accessibilityHint(Text("Double tap to draw"))
            }
        }
        .accessibilityAddTraits(.isButton)
        .onTapGesture { viewModel.drawFromStock() }
    }

    private var wasteView: some View {
        let topCard = viewModel.state.waste.last
        return CardView(card: topCard, cardFaceStyle: cardFaceStyle,
                 cardBackDesign: cardBackDesign, size: layout.cardSize())
            .accessibilityLabel(topCard != nil
                ? Text("Waste pile, \(topCard!.rank.displayName) of \(topCard!.suit.displayName)")
                : Text("Waste pile, empty"))
            .accessibilityHint(topCard != nil ? Text("Double tap to move") : Text(""))
            .onTapGesture { viewModel.tapCard(at: .waste, cardIndex: 0) }
            .simultaneousGesture(wasteDragGesture)
    }

    private func foundationView(index: Int) -> some View {
        let topCard = viewModel.state.foundations[index].last
        return CardView(card: topCard,
                 cardFaceStyle: cardFaceStyle, cardBackDesign: cardBackDesign,
                 size: layout.cardSize())
            .dropTarget(.foundation(index))
            .accessibilityLabel(topCard != nil
                ? Text("Foundation \(index + 1), \(topCard!.rank.displayName) of \(topCard!.suit.displayName)")
                : Text("Foundation \(index + 1), empty"))
    }

    private var wasteDragGesture: some Gesture {
        LongPressGesture(minimumDuration: 0.15)
            .sequenced(before: DragGesture(coordinateSpace: .named("board")))
            .onChanged { value in
                if case .second(true, let drag?) = value {
                    if viewModel.draggedCards.isEmpty, let card = viewModel.state.waste.last {
                        viewModel.beginDrag(cards: [card], from: .waste)
                    }
                    viewModel.dragPosition = drag.location
                }
            }
            .onEnded { value in
                if case .second(true, let drag?) = value {
                    viewModel.endDrag(at: drag.location)
                } else {
                    viewModel.cancelDrag()
                }
            }
    }
}
