#pragma once

#include <optional>
#include <string>

// All building types defined in requirements.md. Belts and splitters share the
// enum for cost/construction/placement/visuals lookup, but their runtime data
// lives in the belt subsystem rather than in Building instances.
enum class BuildingType
{
    Miner,
    Smelter,
    Assembler,
    ReprocessingPlant,
    Shipyard,
    SalvageBay,
    Belt,
    Splitter,
    TunnelEntry,
    TunnelExit,
    Hq,
    PlayerDefenceStation,
    EnemyDefenceStation,
};

// Maps a config id string (e.g. "miner", "reprocessing_plant") to a
// BuildingType. Returns std::nullopt for unknown ids.
std::optional<BuildingType> parseBuildingType(const std::string& id);

// Canonical id string for a BuildingType. The inverse of parseBuildingType.
std::string buildingTypeId(BuildingType type);

// Smelter and Reprocessing Plant pick a recipe for themselves from the first material
// offered to them while they have none (REQ-BLD-AUTO-RECIPE). In every other respect
// their recipe is selected and held exactly as any other building's.
bool isAutoRecipeBuildingType(BuildingType type);

// Buildings that run a production cycle: Miner, Smelter, Assembler, Reprocessing
// Plant and Shipyard (REQ-UI-DEBUG-OVERLAY counts these).
bool isProductionBuildingType(BuildingType type);

// Belts, splitters, and tunnel ends keep their runtime data in the belt subsystem
// rather than in the Building instance, so placing/removing them must register or
// unregister a tile with BeltSystem.
bool isBeltSubsystemType(BuildingType type);

// Building types with player-facing settings that a blueprint can carry and hand to an
// existing building (REQ-UI-BLUEPRINT-TRANSFER): Miner, Assembler, Smelter and
// Reprocessing Plant (recipe -- the last two select their own when they have none,
// REQ-BLD-AUTO-RECIPE), Shipyard (schematic and module layout), Splitter (output
// filters). Every other type has nothing to configure, so a blueprint of one has
// nothing to transfer.
bool isConfigurableBuildingType(BuildingType type);
