//
//  ChipView.swift
//  CasinoKit
//
//  A realistic casino-style betting chip.
//

import SwiftUI

/// A realistic casino-style betting chip.
public struct ChipView: View {
    let denomination: ChipDenomination
    let size: CGFloat
    let isSelected: Bool
    let theme: any CasinoTheme
    
    public init(
        denomination: ChipDenomination,
        size: CGFloat = CasinoDesign.Size.chipLarge,
        isSelected: Bool = false,
        theme: any CasinoTheme = DefaultCasinoTheme()
    ) {
        self.denomination = denomination
        self.size = size
        self.isSelected = isSelected
        self.theme = theme
    }
    
    // MARK: - Layout Constants
    
    private let innerCircleRatio: CGFloat = 0.65
    private let innerGradientRatio: CGFloat = 0.4
    private let textSizeRatio: CGFloat = 0.25
    private let selectionGlowPadding: CGFloat = CasinoDesign.Spacing.xSmall + CasinoDesign.Spacing.xxSmall
    
    private var colors: ChipColorSet {
        theme.chipColors(for: denomination)
    }
    
    public var body: some View {
        ZStack {
            // Base circle with gradient
            Circle()
                .fill(
                    RadialGradient(
                        colors: [
                            colors.secondary,
                            colors.primary,
                            colors.primary.opacity(CasinoDesign.Opacity.heavy)
                        ],
                        center: .topLeading,
                        startRadius: 0,
                        endRadius: size
                    )
                )
            
            // Edge stripes pattern
            ChipEdgePattern(stripeColor: colors.stripe)
                .clipShape(.circle)
            
            // Inner circle
            Circle()
                .fill(
                    RadialGradient(
                        colors: [
                            colors.secondary,
                            colors.primary
                        ],
                        center: .topLeading,
                        startRadius: 0,
                        endRadius: size * innerGradientRatio
                    )
                )
                .frame(width: size * innerCircleRatio, height: size * innerCircleRatio)
            
            // Inner border
            Circle()
                .strokeBorder(
                    colors.stripe.opacity(CasinoDesign.Opacity.heavy),
                    lineWidth: CasinoDesign.LineWidth.medium
                )
                .frame(width: size * innerCircleRatio, height: size * innerCircleRatio)
            
            // Denomination text
            Text(denomination.displayText)
                .font(.system(size: size * textSizeRatio, weight: .heavy, design: .rounded))
                .foregroundStyle(colors.stripe)
                .shadow(
                    color: .black.opacity(CasinoDesign.Opacity.light),
                    radius: CasinoDesign.LineWidth.thin,
                    x: CasinoDesign.Shadow.offsetSmall,
                    y: CasinoDesign.Shadow.offsetSmall
                )
            
            // Outer border
            Circle()
                .strokeBorder(
                    LinearGradient(
                        colors: [
                            Color.white.opacity(CasinoDesign.Opacity.medium),
                            Color.black.opacity(CasinoDesign.Opacity.light)
                        ],
                        startPoint: .topLeading,
                        endPoint: .bottomTrailing
                    ),
                    lineWidth: CasinoDesign.LineWidth.medium
                )
            
            // Selection glow
            if isSelected {
                Circle()
                    .strokeBorder(Color.yellow, lineWidth: CasinoDesign.LineWidth.thick)
                    .frame(width: size + selectionGlowPadding, height: size + selectionGlowPadding)
            }
        }
        .frame(width: size, height: size)
        .shadow(
            color: .black.opacity(CasinoDesign.Opacity.medium),
            radius: isSelected ? CasinoDesign.Shadow.radiusSmall * 2 : CasinoDesign.Shadow.radiusSmall,
            x: CasinoDesign.Shadow.offsetMedium,
            y: CasinoDesign.Shadow.offsetLarge
        )
        .scaleEffect(isSelected ? CasinoDesign.Scale.selected : CasinoDesign.Scale.normal)
        .animation(.spring(duration: CasinoDesign.Animation.quick), value: isSelected)
        .accessibilityLabel(denomination.accessibilityLabel)
        .accessibilityValue(isSelected ? String(localized: "Selected", bundle: .module) : "")
        .accessibilityAddTraits(.isButton)
    }
}

/// The decorative edge stripe pattern for chips.
public struct ChipEdgePattern: View {
    let stripeColor: Color
    
    public init(stripeColor: Color) {
        self.stripeColor = stripeColor
    }
    
    // MARK: - Pattern Constants
    
    private let stripeCount = 8
    private let stripeLengthRatio: CGFloat = 0.2
    
    public var body: some View {
        Canvas { context, size in
            let center = CGPoint(x: size.width / 2, y: size.height / 2)
            let radius = min(size.width, size.height) / 2
            let stripeWidth = CasinoDesign.Size.chipStripeWidth
            let stripeLength = radius * stripeLengthRatio
            
            for i in 0..<stripeCount {
                let angle = (Double(i) / Double(stripeCount)) * 2 * .pi
                
                let innerRadius = radius - stripeLength
                let outerRadius = radius - CasinoDesign.Size.chipStripeInset
                
                let startX = center.x + cos(angle) * innerRadius
                let startY = center.y + sin(angle) * innerRadius
                let endX = center.x + cos(angle) * outerRadius
                let endY = center.y + sin(angle) * outerRadius
                
                var path = Path()
                path.move(to: CGPoint(x: startX, y: startY))
                path.addLine(to: CGPoint(x: endX, y: endY))
                
                context.stroke(
                    path,
                    with: .color(stripeColor),
                    lineWidth: stripeWidth
                )
            }
        }
    }
}

#Preview {
    ZStack {
        Color(red: 0.05, green: 0.35, blue: 0.15)
            .ignoresSafeArea()
        
        VStack(spacing: CasinoDesign.Spacing.xxxLarge) {
            HStack(spacing: CasinoDesign.Spacing.xLarge) {
                ForEach(ChipDenomination.allCases.prefix(6)) { denom in
                    ChipView(denomination: denom, size: CasinoDesign.Size.chipMedium)
                }
            }
            
            ChipView(denomination: .hundred, size: 80, isSelected: true)
        }
    }
}

