import SwiftUI
import AVFoundation

struct SlotsGameView: View {
    @EnvironmentObject var gameState: GameState
    
    @State private var bet = 1
    @State private var isSpinning = false
    @State private var betGreen = true
    @State private var betRed = false
    @State private var betBlue = false
    @State private var betYellow = false
    @State private var betWhite = false
    @State private var betBlack = false
    @State private var topRow = ["SM Icon Rabbit", "SM Icon Hot dog", "SM Icon Crown"]
    @State private var middleRow = ["SM Icon Clover", "SM Icon Clover", "SM Icon Clover"]
    @State private var bottomRow = ["SM Icon Rapiers", "SM Icon Diamond", "SM Icon Hot dog"]
    @State private var spinAudio: AVAudioPlayer?
    @State private var winAudio: AVAudioPlayer?
    
    @GestureState private var isPressed = false
    
    func generateRandomIcon() -> String {
        switch Int.random(in: 0...99) {
        case 0...39:
            return "SM Icon Rapiers"
        case 40...64:
            return "SM Icon Hot dog"
        case 65...79:
            return "SM Icon Rabbit"
        case 80...87:
            return "SM Icon Cherries"
        case 88...92:
            return "SM Icon Clover"
        case 93...96:
            return "SM Icon Crown"
        case 97...98:
            return "SM Icon Eight"
        case 99:
            return "SM Icon Diamond"
        default:
            return ""
        }
    }
    
    func chooseChip(from chipValue: Int) {
        bet = chipValue
        
        betGreen = false
        betRed = false
        betBlue = false
        betYellow = false
        betWhite = false
        betBlack = false
        
        switch chipValue {
        case 1:
            betGreen = true
            break
        case 5:
            betRed = true
            break
        case 25:
            betBlue = true
            break
        case 100:
            betYellow = true
            break
        case 500:
            betWhite = true
            break
        case 5000:
            betBlack = true
            break
        default:
            break
        }
    }
    
    func spinSlotMachine() {
        for i in 0...270 {
            DispatchQueue.main.asyncAfter(deadline: .now() + (Double(1) + (Double(i) * 0.01))) {
                if i < 211 {
                    topRow[0] = generateRandomIcon()
                    middleRow[0] = generateRandomIcon()
                    bottomRow[0] = generateRandomIcon()
                }
                
                if i < 231 {
                    topRow[1] = generateRandomIcon()
                    middleRow[1] = generateRandomIcon()
                    bottomRow[1] = generateRandomIcon()
                }
                
                topRow[2] = generateRandomIcon()
                middleRow[2] = generateRandomIcon()
                bottomRow[2] = generateRandomIcon()
            }
        }
        
        DispatchQueue.main.asyncAfter(deadline: .now() + Double(4)) {
            calculateWinnings()
        }
    }
    
    func calculateWinnings() {
        isSpinning = false
        
        if ((middleRow[0] == middleRow[1]) && (middleRow[0] == middleRow[2])) {
            winAudio?.play()
            
            switch middleRow[0] {
            case "SM Icon Rapiers":
                gameState.money += (bet * 15)
                break
            case "SM Icon Hot dog":
                gameState.money += (bet * 60)
                break
            case "SM Icon Rabbit":
                gameState.money += (bet * 275)
                break
            case "SM Icon Cherries":
                gameState.money += (bet * 1900)
                break
            case "SM Icon Clover":
                gameState.money += (bet * 7800)
                break
            case "SM Icon Crown":
                gameState.money += (bet * 15000)
                break
            case "SM Icon Eight":
                gameState.money += (bet * 12000)
                break
            case "SM Icon Diamond":
                gameState.money += (bet * 1000000)
                break
            default:
                break
            }
        }
    }
    
    func initializeSounds() {
        guard let url = Bundle.main.url(forResource: "Slots Spin SFX", withExtension: "mp3") else {
            return
        }
        
        spinAudio = try? AVAudioPlayer(contentsOf: url)
        
        guard let url = Bundle.main.url(forResource: "Slots Win SFX", withExtension: "mp3") else {
            return
        }
        
        winAudio = try? AVAudioPlayer(contentsOf: url)
    }
    
    var body: some View {
        let pressGesture = DragGesture(minimumDistance: 0)
            .updating($isPressed) { _, state, _ in
                state = true
            }
            .onEnded { _ in
                if !isSpinning {
                    if !(gameState.money < bet) {
                        isSpinning = true
                        gameState.money -= bet
                        spinAudio?.stop()
                        spinAudio?.currentTime = 0
                        spinAudio?.play()
                        spinSlotMachine()
                    }
                }
            }
        
        ZStack {
            Image("Slots Cloth")
                .resizable()
                .scaledToFill()
            
            VStack {
                Text("\n")
                
                Text("$\(gameState.money)")
                    .foregroundColor(.black)
                    .font(.system(.title, design: .rounded)).bold()
                    .padding(10)
                    .background(Color.yellow)
                    .cornerRadius(10)
                    .padding(20)
                
                ZStack {
                    Image("Slot Machine BG")
                        .resizable()
                        .scaledToFit()
                        .frame(maxWidth: 500)
                    
                    VStack {
                        HStack {
                            Image(topRow[0])
                                .resizable()
                                .scaledToFit()
                                .frame(maxWidth: 80)
                            Text("          ")
                            Image(topRow[1])
                                .resizable()
                                .scaledToFit()
                                .frame(maxWidth: 80)
                            Text("          ")
                            Image(topRow[2])
                                .resizable()
                                .scaledToFit()
                                .frame(maxWidth: 80)
                        }
                        
                        HStack {
                            Image(middleRow[0])
                                .resizable()
                                .scaledToFit()
                                .frame(maxWidth: 100)
                            Text("     ")
                            Image(middleRow[1])
                                .resizable()
                                .scaledToFit()
                                .frame(maxWidth: 100)
                            Text("     ")
                            Image(middleRow[2])
                                .resizable()
                                .scaledToFit()
                                .frame(maxWidth: 100)
                        }
                        
                        HStack {
                            Image(bottomRow[0])
                                .resizable()
                                .scaledToFit()
                                .frame(maxWidth: 80)
                            Text("          ")
                            Image(bottomRow[1])
                                .resizable()
                                .scaledToFit()
                                .frame(maxWidth: 80)
                            Text("          ")
                            Image(bottomRow[2])
                                .resizable()
                                .scaledToFit()
                                .frame(maxWidth: 80)
                        }
                        
                        Text("\n\n\n\n\n\n\n")
                    }
                    
                    Image("Slot Machine Frame")
                        .resizable()
                        .scaledToFit()
                        .frame(maxWidth: 500)
                    
                    Image((isPressed && !isSpinning) ? "Slot Machine Button Pressed" : "Slot Machine Button")
                        .resizable()
                        .scaledToFit()
                        .frame(maxWidth: 500)
                        .gesture(pressGesture)
                        .disabled(!betGreen && !betRed && !betBlue && !betYellow && !betWhite && !betBlack)
                }
                
                HStack {
                    Button {
                        chooseChip(from: 1)
                    } label: {
                        Image("Chip 1")
                            .resizable()
                            .scaledToFit()
                            .frame(maxWidth: (betGreen ? 120 : 100))
                    }
                    Button {
                        chooseChip(from: 5)
                    } label: {
                        Image("Chip 5")
                            .resizable()
                            .scaledToFit()
                            .frame(maxWidth: (betRed ? 120 : 100))
                    }
                    Button {
                        chooseChip(from: 25)
                    } label: {
                        Image("Chip 25")
                            .resizable()
                            .scaledToFit()
                            .frame(maxWidth: (betBlue ? 120 : 100))
                    }
                    Button {
                        chooseChip(from: 100)
                    } label: {
                        Image("Chip 100")
                            .resizable()
                            .scaledToFit()
                            .frame(maxWidth: (betYellow ? 120 : 100))
                    }
                    Button {
                        chooseChip(from: 500)
                    } label: {
                        Image("Chip 500")
                            .resizable()
                            .scaledToFit()
                            .frame(maxWidth: (betWhite ? 120 : 100))
                    }
                    Button {
                        chooseChip(from: 5000)
                    } label: {
                        Image("Chip 5000")
                            .resizable()
                            .scaledToFit()
                            .frame(maxWidth: (betBlack ? 120 : 100))
                    }
                }
                
                Text("\n")
            }
        }
        .onDisappear() {
            spinAudio?.stop()
            spinAudio?.currentTime = 0
            
            winAudio?.stop()
            winAudio?.currentTime = 0
        }
        .onAppear() {
            initializeSounds()
        }
    }
}

#Preview {
    SlotsGameView()
        .environmentObject(GameState())
}
