import matrix
import shared
from dataclasses import dataclass
from collections import defaultdict
from pprint import pprint
from typing import List

# STRENGTHS = list(reversed("A, K, Q, J, T, 9, 8, 7, 6, 5, 4, 3, 2".split(", ")))
STRENGTHS = "A, K, Q, J, T, 9, 8, 7, 6, 5, 4, 3, 2".split(", ")
STRENGTHS_TO_WEIGHT = {k: idx for idx, k in enumerate(STRENGTHS)}

STRENGTH_HANDS = [
    "Five of a Kind",
    "Four of a Kind",
    "Full House",
    "Three of a Kind",
    "Two Pair",
    "One Pair",
    "High Card",
]


def determine_hand(cards):
    card_set = set(cards)
    if len(card_set) == 1:
        return "Five of a Kind"

    same_cards = sorted([cards.count(a) for a in card_set])
    if len(same_cards) == 2:
        if max(same_cards) == 4:
            return "Four of a Kind"
        elif max(same_cards) == 3:
            return "Full House"
    elif len(same_cards) == 3:
        if max(same_cards) == 3:
            return "Three of a Kind"
        else:
            return "Two Pair"
    elif len(same_cards) == 4:
        return "One Pair"
    return "High Card"


@dataclass
class Hand:
    cards: str
    bid: int

    def counts(self):
        return Counter(self.cards)

    def kind(self):
        cards = [c for c in self.cards]
        return determine_hand(self.cards)

    def sort_cards(self):
        return [STRENGTHS_TO_WEIGHT[x] for x in self.cards]

    def __lt__(self, other):
        return self.sort_cards() > other.sort_cards()


# @shared.profile
def part1(rows):
    hands = defaultdict(list)
    for row in rows:
        cards, bid = row.split()
        hand = Hand(cards=cards, bid=int(bid))
        hands[hand.kind()].append(hand)
        hands[hand.kind()] = list(sorted(hands[hand.kind()]))
    in_order = []
    for kind in reversed(STRENGTH_HANDS):
        in_order.extend(hands[kind])
    total = 0
    for rank, card in enumerate(in_order):
        total += (rank + 1) * card.bid

    print(total)


# @shared.profile
def part2(rows):
    pass


def main():
    rows = [row for row in shared.load_rows(7)]
    with shared.elapsed_timer() as elapsed:
        part1(rows)
        print("🕒", elapsed())

    with shared.elapsed_timer() as elapsed:
        part2(rows)
        print("🕒", elapsed())


if __name__ == "__main__":
    main()
