import SpriteKit

// MARK: - Colors

extension BlockColor {
    var uiColor: UIColor {
        switch self {
        case .red:    return UIColor(hex: "#E63946")
        case .blue:   return UIColor(hex: "#457B9D")
        case .yellow: return UIColor(hex: "#F4D35E")
        case .purple: return UIColor(hex: "#7B2D8B")
        case .orange: return UIColor(hex: "#E76F51")
        case .green:  return UIColor(hex: "#2A9D8F")
        }
    }
}

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

// MARK: - BlockNode

final class BlockNode: SKShapeNode {

    let block: Block
    private var selectionRing: SKShapeNode?

    init(block: Block, cellSize: CGFloat) {
        self.block = block
        super.init()

        let size = cellSize * 0.82
        let rect = CGRect(x: -size / 2, y: -size / 2, width: size, height: size)
        path = UIBezierPath(roundedRect: rect, cornerRadius: size * 0.18).cgPath

        fillColor   = block.color.uiColor
        strokeColor = block.color.uiColor.darker(by: 0.25)
        lineWidth   = 1.5
        zPosition   = 10
        name        = "block_\(block.id)"

        // Secondary blocks get a white inner ring to distinguish them from primaries
        if !block.color.isPrimary {
            let inset = size - 8
            let innerRect = CGRect(x: -inset / 2, y: -inset / 2, width: inset, height: inset)
            let ring = SKShapeNode(path: UIBezierPath(roundedRect: innerRect, cornerRadius: size * 0.18 - 2).cgPath)
            ring.fillColor = .clear
            ring.strokeColor = SKColor.white.withAlphaComponent(0.4)
            ring.lineWidth = 2
            ring.zPosition = 1
            addChild(ring)
        }
    }

    required init?(coder aDecoder: NSCoder) { fatalError() }

    // MARK: Selection

    func setSelected(_ selected: Bool, cellSize: CGFloat) {
        selectionRing?.removeFromParent()
        selectionRing = nil
        guard selected else { return }

        let size = cellSize * 0.86
        let rect = CGRect(x: -size / 2, y: -size / 2, width: size, height: size)
        let ring = SKShapeNode(path: UIBezierPath(roundedRect: rect, cornerRadius: size * 0.18).cgPath)
        ring.fillColor   = .clear
        ring.strokeColor = .white
        ring.lineWidth   = 2
        ring.zPosition   = 11
        ring.name        = "selectionRing"

        let pulse = SKAction.sequence([
            SKAction.fadeAlpha(to: 0.4, duration: 0.5),
            SKAction.fadeAlpha(to: 1.0, duration: 0.5)
        ])
        ring.run(SKAction.repeatForever(pulse))
        addChild(ring)
        self.selectionRing = ring
    }

    // MARK: Destruction animation

    func animateDestruction(completion: @escaping () -> Void) {
        let shrink = SKAction.scale(to: 0.1, duration: 0.18)
        let fade   = SKAction.fadeOut(withDuration: 0.18)
        let group  = SKAction.group([shrink, fade])
        run(group) { completion() }

        // Particle burst — simple coloured circles
        for _ in 0..<6 {
            let dot = SKShapeNode(circleOfRadius: 4)
            dot.fillColor   = fillColor
            dot.strokeColor = .clear
            dot.zPosition   = 12
            parent?.addChild(dot)
            dot.position = position

            let angle = CGFloat.random(in: 0 ..< .pi * 2)
            let dist  = CGFloat.random(in: 20 ... 45)
            let dx = cos(angle) * dist
            let dy = sin(angle) * dist
            dot.run(SKAction.sequence([
                SKAction.group([
                    SKAction.moveBy(x: dx, y: dy, duration: 0.22),
                    SKAction.fadeOut(withDuration: 0.22)
                ]),
                SKAction.removeFromParent()
            ]))
        }
    }
}

// MARK: - SKColor helper

private extension UIColor {
    func darker(by factor: CGFloat) -> UIColor {
        var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
        getRed(&r, green: &g, blue: &b, alpha: &a)
        return UIColor(red: max(0, r - factor), green: max(0, g - factor),
                       blue: max(0, b - factor), alpha: a)
    }
}
