import SwiftUI
import SpriteKit
import Combine

// MARK: - Observable game bridge (class so SwiftUI can observe it)

@MainActor
final class GameBridge: ObservableObject, GameSceneDelegate {
    @Published var moveCount = 0
    @Published var showWin = false
    @Published var winStars = 0

    func gameSceneDidUpdateMoveCount(_ count: Int) {
        moveCount = count
    }

    func gameSceneDidWin(moveCount: Int, stars: Int) {
        self.moveCount = moveCount
        self.winStars  = stars
        showWin        = true
    }
}

// MARK: - GameContainerView

struct GameContainerView: View {
    let levelId: String
    let levelNumber: Int
    let worldNumber: Int
    let onDismiss: () -> Void

    @StateObject private var bridge = GameBridge()
    @State private var gameScene: GameScene?
    @State private var initialState: GameState?
    @State private var par = 0
    @State private var loadError: String?

    var body: some View {
        ZStack {
            Color(hex: "#1A1A2E").ignoresSafeArea()

            if let error = loadError {
                VStack(spacing: 12) {
                    Text("Load Error")
                        .font(.system(size: 20, weight: .bold))
                        .foregroundColor(.red)
                    Text(error)
                        .font(.system(size: 14, design: .monospaced))
                        .foregroundColor(.white)
                        .multilineTextAlignment(.center)
                    Button("Back") { onDismiss() }
                        .foregroundColor(.red)
                }
                .padding()
            } else if let scene = gameScene {
                SpriteView(scene: scene)
                    .ignoresSafeArea()

                VStack {
                    topHUD
                    Spacer()
                    bottomHUD
                }
            }
        }
        .onAppear { loadLevel() }
        .sheet(isPresented: $bridge.showWin) {
            WinSheet(stars: bridge.winStars, moveCount: bridge.moveCount, par: par) {
                ProgressStore.shared.setStars(bridge.winStars, for: levelId)
                bridge.showWin = false
                onDismiss()
            }
        }
    }

    // MARK: HUD

    private var topHUD: some View {
        HStack {
            Button { onDismiss() } label: {
                Image(systemName: "xmark")
                    .font(.system(size: 16, weight: .bold))
                    .foregroundColor(.white.opacity(0.7))
                    .frame(width: 36, height: 36)
                    .background(Color.white.opacity(0.1))
                    .clipShape(Circle())
            }
            Spacer()
            VStack(spacing: 2) {
                Text("Level \(levelNumber)")
                    .font(.system(size: 13, weight: .semibold, design: .rounded))
                    .foregroundColor(.white.opacity(0.5))
                Text("Moves: \(bridge.moveCount)  /  Par: \(par)")
                    .font(.system(size: 15, weight: .bold, design: .monospaced))
                    .foregroundColor(.white)
            }
            Spacer()
            Color.clear.frame(width: 36, height: 36)
        }
        .padding(.horizontal, 20)
        .padding(.top, 12)
    }

    private var bottomHUD: some View {
        HStack(spacing: 24) {
            HUDButton(icon: "arrow.uturn.backward", label: "Undo") {
                gameScene?.applyUndo()
            }
            HUDButton(icon: "arrow.counterclockwise", label: "Restart") {
                if let s = initialState { gameScene?.applyRestart(initialState: s) }
            }
            HUDButton(icon: "line.3.horizontal", label: "Menu") {
                onDismiss()
            }
        }
        .padding(.bottom, 36)
    }

    // MARK: Load

    private func loadLevel() {
        let filename = "level_\(String(format: "%02d", levelNumber))"
        do {
            let state = try LevelLoader.load(levelId: filename, world: worldNumber)
            initialState = state
            par          = state.par
            // Use a placeholder size; GameScene recalculates cell layout in didMove(to:)
            // where it has the actual SKView bounds via self.size (set by scaleMode = .resizeFill)
            let scene    = GameScene(state: state, size: CGSize(width: 390, height: 844))
            scene.sceneDelegate = bridge
            gameScene    = scene
        } catch {
            loadError = error.localizedDescription
        }
    }
}

// MARK: - Win Sheet

private struct WinSheet: View {
    let stars: Int
    let moveCount: Int
    let par: Int
    let onContinue: () -> Void

    var body: some View {
        ZStack {
            Color(hex: "#1A1A2E").ignoresSafeArea()
            VStack(spacing: 28) {
                Text("Level Complete!")
                    .font(.system(size: 28, weight: .black, design: .rounded))
                    .foregroundColor(.white)
                HStack(spacing: 12) {
                    ForEach(0..<3, id: \.self) { i in
                        Text(i < stars ? "★" : "☆")
                            .font(.system(size: 40))
                            .foregroundColor(i < stars ? Color(hex: "#F4D35E") : .white.opacity(0.3))
                    }
                }
                Text("\(moveCount) moves  ·  Par: \(par)")
                    .font(.system(size: 15, design: .monospaced))
                    .foregroundColor(.white.opacity(0.5))
                Button(action: onContinue) {
                    Text("Continue")
                        .font(.system(size: 18, weight: .bold, design: .rounded))
                        .foregroundColor(.white)
                        .frame(width: 180, height: 52)
                        .background(Color(hex: "#E63946"))
                        .clipShape(RoundedRectangle(cornerRadius: 14))
                }
            }
            .padding(40)
        }
        .presentationDetents([.fraction(0.45)])
    }
}

// MARK: - HUD Button

private struct HUDButton: View {
    let icon: String
    let label: String
    let action: () -> Void

    var body: some View {
        Button(action: action) {
            VStack(spacing: 4) {
                Image(systemName: icon)
                    .font(.system(size: 20, weight: .medium))
                Text(label)
                    .font(.system(size: 11, design: .rounded))
            }
            .foregroundColor(.white.opacity(0.8))
            .frame(width: 64, height: 64)
            .background(Color.white.opacity(0.08))
            .clipShape(RoundedRectangle(cornerRadius: 14))
        }
    }
}

// MARK: - Color(hex:) for SwiftUI

extension Color {
    init(hex: String) {
        let h = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
        var val: UInt64 = 0
        Scanner(string: h).scanHexInt64(&val)
        self.init(
            red:   Double((val >> 16) & 0xFF) / 255,
            green: Double((val >> 8)  & 0xFF) / 255,
            blue:  Double(val & 0xFF)          / 255
        )
    }
}
