from __future__ import annotations

from dataclasses import dataclass
from enum import Enum
from typing import Dict, List, Tuple


class Resource(Enum):
    BRICK = "brick"
    LUMBER = "lumber"
    WOOL = "wool"
    GRAIN = "grain"
    ORE = "ore"
    DESERT = "desert"


class DevelopmentCard(Enum):
    KNIGHT = "knight"
    ROAD_BUILDING = "road_building"
    YEAR_OF_PLENTY = "year_of_plenty"
    MONOPOLY = "monopoly"
    VICTORY_POINT = "victory_point"


class BuildingType(Enum):
    SETTLEMENT = "settlement"
    CITY = "city"


RESOURCE_TOKENS: List[Resource] = [
    Resource.BRICK,
    Resource.BRICK,
    Resource.BRICK,
    Resource.LUMBER,
    Resource.LUMBER,
    Resource.LUMBER,
    Resource.LUMBER,
    Resource.WOOL,
    Resource.WOOL,
    Resource.WOOL,
    Resource.WOOL,
    Resource.GRAIN,
    Resource.GRAIN,
    Resource.GRAIN,
    Resource.GRAIN,
    Resource.ORE,
    Resource.ORE,
    Resource.ORE,
    Resource.DESERT,
]

NUMBER_TOKENS: List[int] = [
    2,
    3,
    3,
    4,
    4,
    5,
    5,
    6,
    6,
    8,
    8,
    9,
    9,
    10,
    10,
    11,
    11,
    12,
]

DEV_CARD_DISTRIBUTION: Dict[DevelopmentCard, int] = {
    DevelopmentCard.KNIGHT: 14,
    DevelopmentCard.ROAD_BUILDING: 2,
    DevelopmentCard.YEAR_OF_PLENTY: 2,
    DevelopmentCard.MONOPOLY: 2,
    DevelopmentCard.VICTORY_POINT: 5,
}

BUILD_COSTS: Dict[str, Dict[Resource, int]] = {
    "road": {Resource.BRICK: 1, Resource.LUMBER: 1},
    "settlement": {
        Resource.BRICK: 1,
        Resource.LUMBER: 1,
        Resource.WOOL: 1,
        Resource.GRAIN: 1,
    },
    "city": {Resource.GRAIN: 2, Resource.ORE: 3},
    "development": {Resource.WOOL: 1, Resource.GRAIN: 1, Resource.ORE: 1},
}

SETTLEMENT_LIMIT = 5
CITY_LIMIT = 4
ROAD_LIMIT = 15
VICTORY_POINTS_TO_WIN = 10


class PortKind(Enum):
    THREE_FOR_ONE = "three_for_one"
    TWO_FOR_ONE = "two_for_one"


@dataclass(frozen=True)
class Port:
    ratio: int
    resource: Resource | None
    kind: PortKind


PORT_SEQUENCE: List[Port] = [
    Port(3, None, PortKind.THREE_FOR_ONE),
    Port(2, Resource.BRICK, PortKind.TWO_FOR_ONE),
    Port(3, None, PortKind.THREE_FOR_ONE),
    Port(2, Resource.WOOL, PortKind.TWO_FOR_ONE),
    Port(3, None, PortKind.THREE_FOR_ONE),
    Port(2, Resource.GRAIN, PortKind.TWO_FOR_ONE),
    Port(2, Resource.LUMBER, PortKind.TWO_FOR_ONE),
    Port(3, None, PortKind.THREE_FOR_ONE),
    Port(2, Resource.ORE, PortKind.TWO_FOR_ONE),
]


CornerCoord = Tuple[int, int, int]
EdgeID = frozenset[CornerCoord]
