import rand
import readline { read_line }

enum Suit {
	hearts
	diamonds
	clubs
	spades
}

enum Rank {
	ace = 1
	two
	three
	four
	five
	six
	seven
	eight
	nine
	ten
	jack
	queen
	king
}

struct Card {
	suit Suit
	rank Rank
}

fn (c Card) str() string {
	return '${c.rank.str().capitalize()} of ${c.suit.str().capitalize()}'
}

struct Deck {
	mut:
	cards        []Card
	discard_pile []Card // New storage for discarded cards
}

fn new_deck() Deck {
	mut d := Deck{}
	suits := [Suit.hearts, .diamonds, .clubs, .spades]
	ranks := [Rank.two, .three, .four, .five, .six, .seven, .eight, .nine, .ten, .jack, .queen, .king, .ace]

	for s in suits {
		for r in ranks {
			d.cards << Card{
				suit: s
				rank: r
			}
		}
	}
	return d
}

fn (c Card) value() int {
	match c.rank {
		.ace { return 11 }
		.jack, .queen, .king { return 10 }
		else { return int(c.rank) }
	}
}

// Draw a card and automatically move it toward the "discard" logic later
fn (mut d Deck) draw() ?Card {
	if d.cards.len == 0 {
		return none
	}
	return d.cards.pop()
}

// Move a specific card to the discard pile
fn (mut d Deck) discard(c Card) {
	d.discard_pile << c
}

// Move all discarded cards back into the main deck and shuffle
fn (mut d Deck) reshuffle_discards() {
	println('--- Reshuffling discard pile back into the deck ---')// could comment out if you don't want it
	d.cards << d.discard_pile
	d.discard_pile.clear() // Empties the discard pile
	d.shuffle()
}

fn (mut d Deck) shuffle() {
	if d.cards.len == 0 {
		return
	}
	for i := d.cards.len - 1; i > 0; i-- {
		j := rand.intn(i + 1) or { 0 }
		d.cards[i], d.cards[j] = d.cards[j], d.cards[i]
	}
}

fn calculate_score(hand []Card) int {
	mut total := 0
	mut aces := 0
	for card in hand {
		total += card.value()
		if card.rank == .ace { aces++ }
	}
	// Adjust Aces from 11 to 1 if we're over 21
	for total > 21 && aces > 0 {
		total -= 10
		aces--
	}
	return total
}

fn main() {
	mut wins := 0
	mut loses := 0
	mut deck := new_deck()
	deck.shuffle()

	println('Welcome to V-Blackjack!')
	println('Blackjack pays 3 to 2')
	mut money:= read_line('\nWhat will you buy in for today?: ')!.trim_space().int()

	for {
		mut player_hand := []Card{}
		mut dealer_hand := []Card{}

		// Initial deal
		player_hand << deck.draw() or { break }
		dealer_hand << deck.draw() or { break }
		player_hand << deck.draw() or { break }
		dealer_hand << deck.draw() or { break }

		// Player Turn
		bet := read_line('Whats your bet?: ')!.trim_space().int()
		for {
			player_score := calculate_score(player_hand)
			println('\nMoney left: ${money}')
			println('Your hand: ${player_hand.map(it.str()).join(', ')} (Score: $player_score)')
			println('Dealer shows: ${dealer_hand[0]}')

			if player_score == 21 {
				println('Blackjack!')
				money += (bet*3)/2
				wins++
				break
			}
			if player_score > 21 {
				println('Bust! You lose.')
				money -= bet
				loses++
				break
			}

			action := read_line('Hit or Stand? (h/s): ')!.trim_space().to_lower()
			if action == 'h' {
				player_hand << deck.draw() or { break }
			} else {
				break
			}
		}
		player_final := calculate_score(player_hand)

		// Dealer Turn (only if player hasn't busted)
		if player_final <= 21 {
			println('\n--- Dealer\'s Turn ---')
			for calculate_score(dealer_hand) < 17 {
				dealer_hand << deck.draw() or { break }
			}

			dealer_final := calculate_score(dealer_hand)
			println('Money left: ${money}')
			println('Dealer hand: ${dealer_hand.map(it.str()).join(', ')} (Score: $dealer_final)')

			if dealer_final > 21 {
				println('Dealer busts! You win!')
				money += bet
				wins++
			} else if dealer_final > player_final {
				println('Dealer wins!')
				money -= bet
				loses++

			} else if dealer_final < player_final {
				println('You win!')
				money += bet
				wins++
			} else {
				println('Push (Tie)!')
			}
		}

		// Cleanup: Move cards to discard pile
		for c in player_hand { deck.discard(c) }
		for c in dealer_hand { deck.discard(c) }
		println('\nMoney left: ${money}')
		if money < 1 {
			println('You ran out of cash!')
			break
		}
		play_again := read_line('Play another round? (y/n): ')!.trim_space().to_lower()
		if play_again == 'n' {
			break
		}
	}
	println('Wins: ${wins} | Loses: ${loses}')
	println('Thanks for playing!')
}