//
//  ResultBannerView.swift
//  Blackjack
//
//  Displays the result of a round with breakdown.
//

import SwiftUI
import CasinoKit

struct ResultBannerView: View {
    let result: RoundResult
    let currentBalance: Int
    let minBet: Int
    let onNewRound: () -> Void
    let onPlayAgain: () -> Void
    
    @State private var showContent = false
    
    // MARK: - Scaled Metrics
    
    @ScaledMetric(relativeTo: .largeTitle) private var titleFontSize: CGFloat = Design.BaseFontSize.largeTitle
    @ScaledMetric(relativeTo: .title) private var resultFontSize: CGFloat = Design.BaseFontSize.title
    @ScaledMetric(relativeTo: .headline) private var amountFontSize: CGFloat = Design.BaseFontSize.xLarge
    @ScaledMetric(relativeTo: .body) private var buttonFontSize: CGFloat = Design.BaseFontSize.medium
    
    // MARK: - Computed
    
    private var isGameOver: Bool {
        currentBalance < minBet
    }
    
    /// Overall result based on total winnings (what the player actually cares about)
    private var overallResultText: String {
        if result.totalWinnings > 0 {
            return String(localized: "WIN!")
        } else if result.totalWinnings < 0 {
            return String(localized: "LOSE")
        } else {
            return String(localized: "PUSH")
        }
    }
    
    /// Color based on overall result
    private var overallResultColor: Color {
        if result.totalWinnings > 0 { return .green }
        if result.totalWinnings < 0 { return .red }
        return .blue
    }
    
    private var winningsText: String {
        if result.totalWinnings > 0 {
            return "+$\(result.totalWinnings)"
        } else if result.totalWinnings < 0 {
            return "-$\(abs(result.totalWinnings))"
        } else {
            return "$0"
        }
    }
    
    private var winningsColor: Color {
        if result.totalWinnings > 0 { return .green }
        if result.totalWinnings < 0 { return .red }
        return .blue
    }
    
    var body: some View {
        ZStack {
            // Full screen dark background
            Color.black.opacity(Design.Opacity.strong)
            
            // Content card
            VStack(spacing: Design.Spacing.xLarge) {
                // Overall result based on total winnings
                Text(overallResultText)
                    .font(.system(size: titleFontSize, weight: .black, design: .rounded))
                    .foregroundStyle(overallResultColor)
                
                // Winnings
                Text(winningsText)
                    .font(.system(size: amountFontSize, weight: .bold, design: .rounded))
                    .foregroundStyle(winningsColor)
                
                // Breakdown - all hands with amounts for splits
                VStack(spacing: Design.Spacing.small) {
                    ForEach(result.handResults.indices, id: \.self) { index in
                        let handResult = result.handResults[index]
                        let handWinnings = index < result.handWinnings.count ? result.handWinnings[index] : nil
                        // Hand numbering: index 0 = Hand 1 (played first, displayed rightmost)
                        let handLabel = result.handResults.count > 1
                            ? String(localized: "Hand \(index + 1)")
                            : String(localized: "Main Hand")
                        // Show amounts for split hands, or for single hand if there are winnings
                        let showAmount = result.hadSplit && handWinnings != nil
                        ResultRow(
                            label: handLabel,
                            result: handResult,
                            amount: showAmount ? handWinnings : nil
                        )
                    }
                    
                    if let insuranceResult = result.insuranceResult {
                        let showInsAmount = result.insuranceWinnings != 0
                        ResultRow(
                            label: String(localized: "Insurance"),
                            result: insuranceResult,
                            amount: showInsAmount ? result.insuranceWinnings : nil
                        )
                    }
                    
                    // Side bet results
                    if let ppResult = result.perfectPairsResult {
                        SideBetResultRow(
                            label: String(localized: "Perfect Pairs"),
                            resultText: ppResult.displayName,
                            isWin: ppResult.isWin,
                            amount: result.perfectPairsWinnings
                        )
                    }
                    
                    if let topResult = result.twentyOnePlusThreeResult {
                        SideBetResultRow(
                            label: String(localized: "21+3"),
                            resultText: topResult.displayName,
                            isWin: topResult.isWin,
                            amount: result.twentyOnePlusThreeWinnings
                        )
                    }
                }
                .padding(Design.Spacing.medium)
                .background(
                    RoundedRectangle(cornerRadius: Design.CornerRadius.medium)
                        .fill(Color.white.opacity(Design.Opacity.subtle))
                )
                
                // Game over message
                if isGameOver {
                    VStack(spacing: Design.Spacing.small) {
                        Text(String(localized: "You've run out of chips!"))
                            .font(.system(size: Design.BaseFontSize.medium, weight: .medium))
                            .foregroundStyle(.white.opacity(Design.Opacity.strong))
                        
                        Button(action: onPlayAgain) {
                            HStack(spacing: Design.Spacing.small) {
                                Image(systemName: "arrow.counterclockwise")
                                Text(String(localized: "Play Again"))
                            }
                            .font(.system(size: buttonFontSize, weight: .bold))
                            .foregroundStyle(.black)
                            .padding(.horizontal, Design.Spacing.xxLarge)
                            .padding(.vertical, Design.Spacing.medium)
                            .background(
                                Capsule()
                                    .fill(
                                        LinearGradient(
                                            colors: [Color.CasinoButton.goldLight, Color.CasinoButton.goldDark],
                                            startPoint: .top,
                                            endPoint: .bottom
                                        )
                                    )
                            )
                        }
                    }
                } else {
                    // New Round button
                    Button(action: onNewRound) {
                        HStack(spacing: Design.Spacing.small) {
                            Image(systemName: "arrow.clockwise")
                            Text(String(localized: "New Round"))
                        }
                        .font(.system(size: buttonFontSize, weight: .bold))
                        .foregroundStyle(.black)
                        .padding(.horizontal, Design.Spacing.xxLarge)
                        .padding(.vertical, Design.Spacing.medium)
                        .background(
                            Capsule()
                                .fill(
                                    LinearGradient(
                                        colors: [Color.CasinoButton.goldLight, Color.CasinoButton.goldDark],
                                        startPoint: .top,
                                        endPoint: .bottom
                                    )
                                )
                        )
                    }
                }
            }
            .padding(Design.Spacing.xxLarge)
            .background(
                RoundedRectangle(cornerRadius: Design.CornerRadius.xxLarge)
                    .fill(
                        LinearGradient(
                            colors: [Color.CasinoModal.backgroundLight, Color.CasinoModal.backgroundDark],
                            startPoint: .top,
                            endPoint: .bottom
                        )
                    )
                    .overlay(
                        RoundedRectangle(cornerRadius: Design.CornerRadius.xxLarge)
                            .strokeBorder(
                                overallResultColor.opacity(Design.Opacity.medium),
                                lineWidth: Design.LineWidth.medium
                            )
                    )
            )
            .shadow(color: overallResultColor.opacity(Design.Opacity.hint), radius: Design.Shadow.radiusXLarge)
            .frame(maxWidth: CasinoDesign.Size.maxModalWidth)
            .padding(.horizontal, Design.Spacing.large) // Prevent clipping on sides
            .scaleEffect(showContent ? Design.Scale.normal : Design.Scale.slightShrink)
            .opacity(showContent ? 1.0 : 0)
        }
        .onAppear {
            withAnimation(.spring(duration: Design.Animation.springDuration, bounce: Design.Animation.springBounce)) {
                showContent = true
            }
            
            // Play game over sound if out of chips (after a delay so it doesn't overlap with result sound)
            if isGameOver {
                Task {
                    try? await Task.sleep(for: .seconds(Design.Delay.gameOverSound))
                    SoundManager.shared.play(.gameOver)
                }
            }
        }
        .accessibilityElement(children: .contain)
        .accessibilityLabel(String(localized: "Round result: \(result.mainHandResult.displayText)"))
        .accessibilityAddTraits(AccessibilityTraits.isModal)
    }
}

// MARK: - Result Row

struct ResultRow: View {
    let label: String
    let result: HandResult
    var amount: Int? = nil
    
    private var showDebugBorders: Bool { Design.showDebugBorders }
    
    private var amountText: String? {
        guard let amount = amount else { return nil }
        if amount > 0 {
            return "+$\(amount)"
        } else if amount < 0 {
            return "-$\(abs(amount))"
        } else {
            return "$0"
        }
    }
    
    private var amountColor: Color {
        guard let amount = amount else { return .white }
        if amount > 0 { return .green }
        if amount < 0 { return .red }
        return .blue
    }
    
    var body: some View {
        HStack {
            Text(label)
                .font(.system(size: Design.BaseFontSize.medium))
                .foregroundStyle(.white.opacity(Design.Opacity.strong))
                .debugBorder(showDebugBorders, color: .blue, label: "Label")
            
            Spacer()
                .debugBorder(showDebugBorders, color: .yellow, label: "Spacer")
            
            // Show amount if provided
            if let amountText = amountText {
                Text(amountText)
                    .font(.system(size: Design.BaseFontSize.medium, weight: .semibold, design: .rounded))
                    .foregroundStyle(amountColor)
                    .frame(width: Design.Size.resultRowAmountWidth, alignment: .trailing)
                    .debugBorder(showDebugBorders, color: .green, label: "Amount")
            }
            
            Text(result.displayText)
                .font(.system(size: Design.BaseFontSize.large, weight: .bold))
                .foregroundStyle(result.color)
                .frame(width: Design.Size.resultRowResultWidth, alignment: .trailing)
                .lineLimit(1)
                .minimumScaleFactor(Design.MinScaleFactor.comfortable)
                .debugBorder(showDebugBorders, color: .red, label: "Result")
        }
        .debugBorder(showDebugBorders, color: .white, label: "ResultRow")
    }
}

// MARK: - Side Bet Result Row

struct SideBetResultRow: View {
    let label: String
    let resultText: String
    let isWin: Bool
    let amount: Int
    
    private var showDebugBorders: Bool { Design.showDebugBorders }
    
    private var amountText: String {
        if amount > 0 {
            return "+$\(amount)"
        } else if amount < 0 {
            return "-$\(abs(amount))"
        } else {
            return "$0"
        }
    }
    
    private var amountColor: Color {
        if amount > 0 { return .green }
        if amount < 0 { return .red }
        return .blue
    }
    
    private var resultColor: Color {
        isWin ? .green : .red
    }
    
    var body: some View {
        HStack {
            Text(label)
                .font(.system(size: Design.BaseFontSize.medium))
                .foregroundStyle(.white.opacity(Design.Opacity.strong))
                .debugBorder(showDebugBorders, color: .blue, label: "Label")
            
            Spacer()
                .debugBorder(showDebugBorders, color: .yellow, label: "Spacer")
            
            Text(amountText)
                .font(.system(size: Design.BaseFontSize.medium, weight: .semibold, design: .rounded))
                .foregroundStyle(amountColor)
                .frame(width: Design.Size.resultRowAmountWidth, alignment: .trailing)
                .debugBorder(showDebugBorders, color: .green, label: "Amount")
            
            Text(resultText)
                .font(.system(size: Design.BaseFontSize.large, weight: .bold))
                .foregroundStyle(resultColor)
                .frame(width: Design.Size.resultRowResultWidth, alignment: .trailing)
                .lineLimit(1)
                .minimumScaleFactor(Design.MinScaleFactor.comfortable)
                .debugBorder(showDebugBorders, color: .red, label: "Result")
        }
        .debugBorder(showDebugBorders, color: .white, label: "SideBetRow")
    }
}

#Preview("Single Hand") {
    ResultBannerView(
        result: RoundResult(
            handResults: [.blackjack],
            handWinnings: [150],
            insuranceResult: nil,
            insuranceWinnings: 0,
            totalWinnings: 150,
            wasBlackjack: true
        ),
        currentBalance: 10150,
        minBet: 10,
        onNewRound: {},
        onPlayAgain: {}
    )
}

#Preview("Multiple Split Hands") {
    ResultBannerView(
        result: RoundResult(
            handResults: [.bust, .win, .push],
            handWinnings: [-100, 100, 0],
            insuranceResult: nil,
            insuranceWinnings: 0,
            totalWinnings: 0,
            wasBlackjack: false
        ),
        currentBalance: 1000,
        minBet: 10,
        onNewRound: {},
        onPlayAgain: {}
    )
}

#Preview("Split with Insurance") {
    ResultBannerView(
        result: RoundResult(
            handResults: [.lose, .win],
            handWinnings: [-100, 200],
            insuranceResult: .insuranceWin,
            insuranceWinnings: 100,
            totalWinnings: 200,
            wasBlackjack: false
        ),
        currentBalance: 1200,
        minBet: 10,
        onNewRound: {},
        onPlayAgain: {}
    )
}

#Preview("With Side Bets") {
    ResultBannerView(
        result: RoundResult(
            handResults: [.win],
            handWinnings: [100],
            insuranceResult: nil,
            insuranceWinnings: 0,
            perfectPairsResult: .coloredPair,
            perfectPairsWinnings: 300,
            twentyOnePlusThreeResult: .nothing,
            twentyOnePlusThreeWinnings: -25,
            totalWinnings: 375,
            wasBlackjack: false
        ),
        currentBalance: 1375,
        minBet: 10,
        onNewRound: {},
        onPlayAgain: {}
    )
}

