# retoor <retoor@molodetz.nl>

from __future__ import annotations

import random

from .. import economy
from .common import GameError, _lvl, conditional_update_farm
from .farm import ensure_farm, get_farm


INFRA_COLUMN = {i.key: f"infra_{i.key}" for i in economy.INFRASTRUCTURE}


def buy_infrastructure(user: dict, key: str) -> dict:
    infra = economy.infra_for(key)
    if not infra:
        raise GameError("Unknown infrastructure.")
    farm = ensure_farm(user["uid"])
    column = INFRA_COLUMN[infra.key]
    rows = conditional_update_farm(
        farm["uid"],
        set_clause=f"coins = coins - :cost, {column} = 1",
        where_clause=(
            f"COALESCE({column}, 0) = 0 AND coins >= :cost "
            f"AND COALESCE(prestige, 0) >= :min_prestige"
        ),
        params={"cost": infra.cost, "min_prestige": infra.min_prestige},
    )
    if rows == 0:
        farm = get_farm(user["uid"])
        if _lvl(farm, column):
            raise GameError("You already own that infrastructure.")
        if _lvl(farm, "prestige") < infra.min_prestige:
            raise GameError(f"{infra.name} requires prestige {infra.min_prestige}.")
        raise GameError("Not enough coins for that infrastructure.")
    return {"key": infra.key, "spent": infra.cost}


def owns_infrastructure(farm: dict, key: str) -> bool:
    column = INFRA_COLUMN.get(key)
    return bool(column and _lvl(farm, column))


def roll_canary(coins_gain: int, plant_cost: int) -> int:
    roll = random.random()
    if roll < economy.CANARY_DOUBLE_CHANCE:
        return coins_gain * 2
    if roll < economy.CANARY_DOUBLE_CHANCE + economy.CANARY_FAIL_CHANCE:
        return min(coins_gain, plant_cost)
    return coins_gain
