import SwiftUI

struct FreeCellBoardView: 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) {
                ForEach(0..<min(4, viewModel.state.freeCells.count), id: \.self) { index in
                    freeCellView(index: index)
                }
                Spacer()
                ForEach(0..<min(4, viewModel.state.foundations.count), id: \.self) { index in
                    foundationView(index: index)
                }
            }
            .padding(.horizontal, layout.horizontalPadding)

            HStack(alignment: .top, spacing: layout.horizontalPadding) {
                ForEach(0..<min(8, 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 func freeCellView(index: Int) -> some View {
        let card = viewModel.state.freeCells[index]
        return CardView(card: card,
                 cardFaceStyle: cardFaceStyle, cardBackDesign: cardBackDesign,
                 size: layout.cardSize())
            .dropTarget(.freeCell(index))
            .accessibilityLabel(card != nil
                ? Text("Free cell \(index + 1), \(card!.rank.displayName) of \(card!.suit.displayName)")
                : Text("Free cell \(index + 1), empty"))
            .onTapGesture { viewModel.tapCard(at: .freeCell(index), cardIndex: 0) }
            .simultaneousGesture(freeCellDragGesture(index: index))
    }

    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 func freeCellDragGesture(index: Int) -> 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.freeCells[index] {
                        viewModel.beginDrag(cards: [card], from: .freeCell(index))
                    }
                    viewModel.dragPosition = drag.location
                }
            }
            .onEnded { value in
                if case .second(true, let drag?) = value {
                    viewModel.endDrag(at: drag.location)
                } else {
                    viewModel.cancelDrag()
                }
            }
    }
}
