import SpriteKit

final class GridRenderer {

    private let gridSize: GridSize
    let cellSize: CGFloat
    let gridOrigin: CGPoint  // bottom-left corner in scene coordinates

    // MARK: - Init

    init(gridSize: GridSize, sceneSize: CGSize) {
        self.gridSize = gridSize

        // Fill ~85% of screen width
        let targetWidth = sceneSize.width * 0.85
        cellSize = floor(targetWidth / CGFloat(gridSize.width))

        let totalW = cellSize * CGFloat(gridSize.width)
        let totalH = cellSize * CGFloat(gridSize.height)
        gridOrigin = CGPoint(
            x: (sceneSize.width  - totalW) / 2,
            y: (sceneSize.height - totalH) / 2
        )
    }

    // MARK: - Build nodes

    func buildBackground() -> SKNode {
        let root = SKNode()
        root.zPosition = 0

        // Grid background
        let totalW = cellSize * CGFloat(gridSize.width)
        let totalH = cellSize * CGFloat(gridSize.height)
        let bg = SKShapeNode(rect: CGRect(origin: .zero, size: CGSize(width: totalW, height: totalH)), cornerRadius: 8)
        bg.fillColor   = UIColor(hex: "#1A1A2E")
        bg.strokeColor = .clear
        bg.position    = .zero
        bg.zPosition   = 0
        root.addChild(bg)

        // Grid lines
        let lineColor = UIColor(hex: "#2A2A3E")
        for col in 0...gridSize.width {
            let x = CGFloat(col) * cellSize
            let line = SKShapeNode()
            let path = CGMutablePath()
            path.move(to: CGPoint(x: x, y: 0))
            path.addLine(to: CGPoint(x: x, y: totalH))
            line.path        = path
            line.strokeColor = lineColor
            line.lineWidth   = 1
            line.zPosition   = 1
            root.addChild(line)
        }
        for row in 0...gridSize.height {
            let y = CGFloat(row) * cellSize
            let line = SKShapeNode()
            let path = CGMutablePath()
            path.move(to: CGPoint(x: 0, y: y))
            path.addLine(to: CGPoint(x: totalW, y: y))
            line.path        = path
            line.strokeColor = lineColor
            line.lineWidth   = 1
            line.zPosition   = 1
            root.addChild(line)
        }

        root.position = gridOrigin
        return root
    }

    func buildWalls(_ walls: Set<GridPosition>) -> SKNode {
        let root = SKNode()
        root.zPosition = 2
        root.position  = gridOrigin

        for wall in walls {
            let size = cellSize * 0.9
            let rect = CGRect(x: -size / 2, y: -size / 2, width: size, height: size)
            let node = SKShapeNode(path: UIBezierPath(roundedRect: rect, cornerRadius: 4).cgPath)
            node.fillColor   = UIColor(hex: "#2A2A3E")
            node.strokeColor = UIColor(hex: "#3A3A4E")
            node.lineWidth   = 1
            node.position    = scenePosition(for: wall)
            // position is relative to gridOrigin, so subtract it
            node.position    = CGPoint(
                x: node.position.x - gridOrigin.x,
                y: node.position.y - gridOrigin.y
            )
            root.addChild(node)
        }
        return root
    }

    // MARK: - Coordinate helpers

    /// Convert grid position → scene coordinates (with Y-flip)
    func scenePosition(for pos: GridPosition) -> CGPoint {
        let spriteY = CGFloat(gridSize.height - 1 - pos.y) * cellSize + cellSize / 2
        let spriteX = CGFloat(pos.x) * cellSize + cellSize / 2
        return CGPoint(x: gridOrigin.x + spriteX, y: gridOrigin.y + spriteY)
    }
}
