"""Application configuration loaded from environment variables."""
from functools import lru_cache
from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    model_config = SettingsConfigDict(env_file=".env", extra="ignore")

    # FastAPI
    app_host: str = "0.0.0.0"
    app_port: int = 8080
    app_env: str = "dev"
    app_log_level: str = "INFO"
    webhook_secret: str = "change-me"
    command_api_key: str = "change-me"

    # Kafka
    kafka_bootstrap_servers: str = "kafka:9092"
    kafka_client_id: str = "btl-fastlane"

    topic_allocate_requested: str = "fastlane.tank.allocate.requested"
    topic_allocate_completed: str = "fastlane.tank.allocate.completed"
    topic_allocate_failed: str = "fastlane.tank.allocate.failed"
    topic_allocate_blocked: str = "fastlane.tank.allocate.blocked"

    # --- Single-task pipeline topics (James's minion pattern) --------------
    # Each step consumes ONE topic and produces ONE result topic. A step
    # never reaches beyond its single BASF endpoint.
    #
    #   requested            → [lookup]      → asset.lookup.done
    #   asset.lookup.done    → [upsert]      → asset.upserted
    #   asset.upserted       → [file-upload] → asset.docs.uploaded
    #   docs.accepted (webhook / async BASF review)
    #                        → [commit]      → tank.allocate.completed
    #
    # Any step failure lands on its own .failed topic (retryable) and also
    # on the terminal `tank.allocate.failed` for the ERP UI.
    topic_asset_lookup_done:  str = "fastlane.asset.lookup.done"
    topic_asset_upserted:     str = "fastlane.asset.upserted"
    topic_asset_docs_uploaded: str = "fastlane.asset.docs.uploaded"
    topic_docs_accepted:      str = "fastlane.docs.accepted"

    # Dead-letter topics — one per step. Poison-message safety.
    topic_lookup_dlq:      str = "fastlane.asset.lookup.dlq"
    topic_upsert_dlq:      str = "fastlane.asset.upsert.dlq"
    topic_file_upload_dlq: str = "fastlane.asset.docs.dlq"
    topic_commit_dlq:      str = "fastlane.asset.commit.dlq"

    # Consumer groups — one per single-task minion.
    consumer_group_lookup:        str = "fastlane.lookup"
    consumer_group_upsert:        str = "fastlane.upsert"
    consumer_group_file_upload:   str = "fastlane.file-upload"
    consumer_group_commit:        str = "fastlane.commit"
    consumer_group_commit_driver: str = "fastlane.commit-driver"
    consumer_group_status:        str = "fastlane.status.listener"

    # Legacy — kept only for the deprecated registration_minion (removed).
    consumer_group_registration: str = "fastlane.registration"

    # Fastlane API (spec v2.0.0 — "Asset API for carriers")
    #   Production: https://prod.fastlane.now/backend/asset/api/v1/restAPIs
    #   Staging   : https://staging.fastlane.now/backend/asset/api/v1/restAPIs
    fastlane_base_url: str = "https://staging.fastlane.now/backend/asset/api/v1/restAPIs"
    # Accept both FASTLANE_PUBLIC_KEY and FASTLANE_API_KEY from env (the .env
    # file historically uses FASTLANE_API_KEY — both map to the same thing).
    fastlane_public_key: str = "change-me-fastlane-public-key"
    fastlane_api_key: str = "change-me-fastlane-key"
    fastlane_erp_key: str = "change-me-erp-key-shared-with-fastlane"
    fastlane_timeout: int = 30
    # Default Fastlane numeric vehicle_type used by BTL.
    # Per client (A11): register only tanks of type 311–314
    #   311 = 20ft tank container (most of BTL fleet)
    #   312 = 32ft swap tank
    #   313 / 314 = other length variants
    fastlane_default_vehicle_type: int = 311
    fastlane_allowed_vehicle_types: str = "311,312,313,314"

    # Default owner block used when ERP does not supply one.
    # Client (A2b/A3): "Just use ITT as the owner and the address for Head Office."
    # Placeholder values below — override in .env with the real ITT HQ address.
    fastlane_default_owner_name: str = "ITT"
    fastlane_default_owner_street: str = "Head Office"
    fastlane_default_owner_zip: str = "00000"
    fastlane_default_owner_city: str = "Head Office"
    fastlane_default_owner_country: str = "GB"

    # locationList policy (client A4/A6):
    #   "1" = asset usable for NON-Hazardous jobs
    #   "2" = asset usable for Hazardous (DG) jobs
    #   "102" = BASF Ludwigshafen site (to be confirmed with BASF)
    # Every payload gets [ "1" | "2" , <site_code> ].
    fastlane_site_code_default: str = "102"

    # Client (A7/A8/A9): DO NOT commit immediately after newAsset/updateAsset.
    # After upsert the asset sits in `draft`, we uploadFile the supporting
    # documents, wait for BASF to accept them (webhook), and only then call
    # commitAsset. Keep False in production; True is a debug shortcut.
    fastlane_commit_after_upsert: bool = False

    # Nationality (client A12): "Not required for Tanks". If ERP still supplies
    # it we pass it through, otherwise we omit it entirely from the payload.
    fastlane_send_nationality: bool = False

    # ---- Mock mode --------------------------------------------------------
    # When true the FastlaneClient does NOT hit BASF; it returns synthetic
    # successful responses so the whole pipeline (Kafka → registration
    # minion → status listener → ERP callback) can be tested end-to-end
    # without BASF credentials. Flip to false as soon as we get real creds.
    fastlane_mock_mode: bool = True

    # ERP callback
    erp_status_endpoint: str = "http://erp.local/status"
    erp_callback_token: str = "change-me"
    erp_timeout: int = 15


@lru_cache
def get_settings() -> Settings:
    return Settings()
