import SwiftUI

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

    private var isReady: Bool {
        viewModel.state.phase != .notStarted && !viewModel.state.tableaus.isEmpty
    }

    private var deepestColumn: (faceDown: Int, faceUp: Int) {
        var worst = (faceDown: 0, faceUp: 1)
        for column in viewModel.state.tableaus {
            let faceUp = column.reversed().prefix(while: { $0.isFaceUp }).count
            let faceDown = column.count - faceUp
            let depth = faceDown * 15 + max(0, faceUp - 1) * 25 + 100
            let worstDepth = worst.faceDown * 15 + max(0, worst.faceUp - 1) * 25 + 100
            if depth > worstDepth {
                worst = (faceDown, faceUp)
            }
        }
        return worst
    }

    var body: some View {
        if isReady {
            VStack(spacing: 0) {
                ScoreBarView(
                    moves: viewModel.state.moves,
                    score: viewModel.state.score,
                    time: viewModel.elapsedSeconds.formattedTime,
                    theme: theme
                )

                GeometryReader { geometry in
                    let layout = CardLayout(
                        availableSize: geometry.size,
                        variant: viewModel.variant,
                        deepestColumn: deepestColumn
                    )

                    ScrollView(.vertical) {
                        boardContent(layout: layout)
                            .padding(.bottom, layout.horizontalPadding)
                            .frame(maxWidth: .infinity,
                                   minHeight: landscapeMinHeight(viewportHeight: geometry.size.height,
                                                                  isLandscape: layout.isLandscape),
                                   alignment: .top)
                            .contentShape(Rectangle())
                    }
                    .scrollIndicators(.hidden)
                    .scrollDisabled(!viewModel.draggedCards.isEmpty)
                    .coordinateSpace(name: "board")
                    .onPreferenceChange(DropTargetPreferenceKey.self) { targets in
                        viewModel.dropTargets = targets
                    }
                    .overlay {
                        DraggedCardsOverlay(
                            viewModel: viewModel,
                            layout: layout,
                            cardFaceStyle: cardFaceStyle,
                            cardBackDesign: cardBackDesign
                        )
                    }
                }
            }
            .background(theme.backgroundColor)
            .overlay {
                if viewModel.isWon {
                    VictoryOverlayView {
                        viewModel.newGame()
                    }
                }
            }
        } else {
            Color.clear
                .background(theme.backgroundColor)
        }
    }

    private func landscapeMinHeight(viewportHeight: CGFloat, isLandscape: Bool) -> CGFloat? {
        #if os(iOS)
        return isLandscape ? viewportHeight * 1.3 : nil
        #else
        return nil
        #endif
    }

    @ViewBuilder
    private func boardContent(layout: CardLayout) -> some View {
        switch viewModel.variant {
        case .klondike:
            KlondikeBoardView(viewModel: viewModel, layout: layout,
                               theme: theme, cardFaceStyle: cardFaceStyle,
                               cardBackDesign: cardBackDesign)
        case .spider:
            SpiderBoardView(viewModel: viewModel, layout: layout,
                             theme: theme, cardFaceStyle: cardFaceStyle,
                             cardBackDesign: cardBackDesign)
        case .freeCell:
            FreeCellBoardView(viewModel: viewModel, layout: layout,
                               theme: theme, cardFaceStyle: cardFaceStyle,
                               cardBackDesign: cardBackDesign)
        }
    }
}

extension Int {
    var formattedTime: String {
        let minutes = self / 60
        let seconds = self % 60
        return String(format: "%d:%02d", minutes, seconds)
    }
}
