import matrix
import shared
from pprint import pprint
from dataclasses import dataclass
from scanf import scanf


def load_blueprints(rows):
    blueprints = {}
    for row in rows:
        b, o_c, c_c, o_o_c, o_c_c, g_o_c, g_o_c = scanf(
            "Blueprint %d: Each ore robot costs %d ore. "
            "Each clay robot costs %d ore. "
            "Each obsidian robot costs %d ore and %d clay. "
            "Each geode robot costs %d ore and %d", row) 
        bp = Blueprint(b, o_c, c_c, o_o_c, o_c_c, g_o_c, g_o_c)
        blueprints[bp.id] = bp
    return blueprints


@dataclass
class Blueprint():
    id :int
    ore_ore_cost: int
    clay_ore_cost: int
    obsidian_ore_cost: int
    obsidian_clay_cost: int
    geode_ore_cost: int
    geode_obsidian_cost: int

    def can_produce_ore_robot(self, r):
        return r.ore >= self.ore_cost
    
    def can_produce_clay_robot(self, r):
        return r.ore >= self.clay_ore_cost

    def can_produce_obsidian_robot(self, r):
        return r.ore >= self.obsidian_ore_cost and r.clay >= self.obsidian_clay_cost

    def can_produce_geode_robot(self, r):
        return r.ore >= self.geode_ore_cost and r.obsidian >= self.geode_obsidian_cost


@dataclass
class Resources():
    ore: int = 0
    clay: int = 0
    obsidian: int = 0
    geodes: int = 0


@dataclass
class Robots():
    ore: int = 1
    clay: int = 0
    obsidian: int = 0
    geodes: int = 0
    

# @shared.profile
#def part1(rows, minutes=12):
def part1(rows, minutes=24):
    blueprints = load_blueprints(rows)
    quality = 0

    for _,bp in blueprints.items():
        resources = Resources()
        robots = Robots()
        for minute in range(1, minutes+1):
            print(f"== Minute {minute} ==")

            _add_ore = False
            _add_clay = False
            _add_obsidian = False
            _add_geode = False


            # SPEND THE RESOURCES
            if bp.can_produce_clay_robot(resources):
                # Do we have enough to build obsidian?
                if robots.clay < bp.obsidian_ore_cost:
                    print(f"Spend {bp.clay_ore_cost} ore to start building a clay-collecting robot.")
                    resources.ore -= bp.clay_ore_cost
                    _add_clay = True

            if bp.can_produce_obsidian_robot(resources):
                # Do we have enough to build geodes?
                if robots.obsidian < bp.geode_obsidian_cost:
                    print(f"Spend {bp.obsidian_ore_cost} ore and {bp.obsidian_clay_cost} clay to start building an obsidian-collecting robot.")
                    resources.ore -= bp.obsidian_ore_cost
                    resources.clay -= bp.obsidian_clay_cost
                    _add_obsidian = True

            if bp.can_produce_geode_robot(resources):
                print(f"Spend {bp.geode_ore_cost} ore and {bp.geode_obsidian_cost} obsidian to start building a geode-cracking robot.")
                resources.ore -= bp.geode_ore_cost
                resources.obsidian -= bp.geode_obsidian_cost
                _add_geode = True


            # GATHER RESOURCES
            resources.ore += robots.ore
            resources.clay += robots.clay
            resources.obsidian += robots.obsidian
            resources.geodes += robots.geodes

            if robots.ore > 0:
                print(f"{robots.ore} ore-collecting robot collects {robots.ore} ore; you now have {resources.ore} ore.")
            if robots.clay > 0:
                print(f"{robots.clay} clay-collecting robot collects {robots.clay} clay; you now have {resources.clay} clay.")
            if robots.obsidian > 0:
                print(f"{robots.obsidian} obsidian-collecting robot collects {robots.obsidian} obsidian; you now have {resources.obsidian} obsidian.")
            if robots.geodes > 0:
                print(f"{robots.geodes} geode-cracking robot collects {robots.geodes} geodes; you now have {resources.geodes} geodes.")


            # PRODUCE ROBOTS
            if _add_ore:
                robots.ore += 1
                print(f"The new ore-collecting robot is ready; you now have {robots.ore} of them.")
            if _add_clay:
                robots.clay += 1
                print(f"The new clay-collecting robot is ready; you now have {robots.clay} of them.")
            if _add_obsidian:
                robots.obsidian += 1
                print(f"The new obsidian-collecting robot is ready; you now have {robots.obsidian} of them.")
            if _add_geode:
                robots.geodes += 1
                print(f"The new geode-cracking robot is ready; you now have {robots.geodes} of them.")

            print()
        quality += (bp.id * resources.geodes)
    print(quality)



# @shared.profile
def part2(rows, minutes=24):
    pass


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


if __name__ == "__main__":
    main()
