"""Production/runtime settings layered over the original FTG settings."""
import os
from corsheaders.defaults import default_headers


def _bool(name, default=False):
    return os.environ.get(name, str(default)).strip().lower() in {"1", "true", "yes", "on"}


def _int(name, default):
    return int(os.environ.get(name, default))


def configure(base):
    debug = bool(base.get("DEBUG", True))
    for name in ("FTG_BRIDGE_DEPOSITS_ENABLED", "FTG_BRIDGE_WITHDRAWALS_ENABLED", "FTG_BRIDGE_REDEMPTION_APPROVED"):
        base[name] = _bool(name, False)
    for name in ("FTG_BRIDGE_PROVIDER", "FTG_BRIDGE_NETWORK", "FTG_BRIDGE_TOKEN_CONTRACT"):
        base[name] = os.environ.get(name, "").strip()

    # PostgreSQL-first configuration. SQLite remains available only for local
    # development/test convenience; deploy checks reject it in production.
    db_engine = os.environ.get("DJANGO_DB_ENGINE", "").strip().lower()
    postgres_requested = db_engine in {"postgres", "postgresql"} or bool(os.environ.get("POSTGRES_DB"))
    if postgres_requested:
        options = {}
        sslmode = os.environ.get("POSTGRES_SSLMODE", "").strip()
        if sslmode:
            options["sslmode"] = sslmode
        base["DATABASES"] = {
            "default": {
                "ENGINE": "django.db.backends.postgresql",
                "NAME": os.environ.get("POSTGRES_DB", "ftg"),
                "USER": os.environ.get("POSTGRES_USER", "ftg"),
                "PASSWORD": os.environ.get("POSTGRES_PASSWORD", ""),
                "HOST": os.environ.get("POSTGRES_HOST", "127.0.0.1"),
                "PORT": os.environ.get("POSTGRES_PORT", "5432"),
                # ASGI requests run in short-lived thread contexts. Do not keep
                # one idle connection per context indefinitely by default.
                "CONN_MAX_AGE": _int("POSTGRES_CONN_MAX_AGE", 0),
                "CONN_HEALTH_CHECKS": True,
                "OPTIONS": options,
            }
        }

    redis_url = os.environ.get("REDIS_URL") or os.environ.get("ACCOUNT_REDIS_URL")
    base["RUNTIME_REDIS_URL"] = redis_url or ""
    if redis_url:
        base["CACHES"] = {
            "default": {
                "BACKEND": "django.core.cache.backends.redis.RedisCache",
                "LOCATION": redis_url,
                "TIMEOUT": 300,
                "KEY_PREFIX": os.environ.get("REDIS_KEY_PREFIX", "ftg"),
            }
        }
    else:
        base.setdefault("CACHES", {"default": {"BACKEND": "django.core.cache.backends.locmem.LocMemCache"}})

    broker = os.environ.get("CELERY_BROKER_URL") or redis_url or "redis://127.0.0.1:6379/1"
    base["CELERY_BROKER_URL"] = broker
    base["CELERY_RESULT_BACKEND"] = os.environ.get("CELERY_RESULT_BACKEND", broker)
    base["CELERY_TASK_ACKS_LATE"] = True
    base["CELERY_TASK_REJECT_ON_WORKER_LOST"] = True
    base["CELERY_WORKER_PREFETCH_MULTIPLIER"] = 1
    base["CELERY_TASK_TRACK_STARTED"] = True
    base["CELERY_TASK_TIME_LIMIT"] = _int("CELERY_TASK_TIME_LIMIT", 600)
    base["CELERY_TASK_SOFT_TIME_LIMIT"] = _int("CELERY_TASK_SOFT_TIME_LIMIT", 540)
    base["CELERY_BROKER_TRANSPORT_OPTIONS"] = {"visibility_timeout": _int("CELERY_VISIBILITY_TIMEOUT", 3600)}
    base["CELERY_TASK_DEFAULT_QUEUE"] = "ftg-default"
    base["CELERY_TASK_ROUTES"] = {
        "core_runtime.process_friendlies": {"queue": "friendlies"},
        "core_runtime.process_token_bridge": {"queue": "token-bridge"},
        "core_runtime.consume_domain_event": {"queue": "domain-events"},
        "core_runtime.process_live_matches": {"queue": "live-matches"},
        "core_runtime.process_matchday": {"queue": "matches"},
        "core_runtime.project_match_analytics": {"queue": "analytics"},
        "core_runtime.process_player_dynamics": {"queue": "analytics"},
        "notifications.*": {"queue": "notifications"},
        "core_runtime.training_reminders": {"queue": "notifications"},
        "core_runtime.*": {"queue": "ftg-default"},
    }
    base["CELERY_BEAT_SCHEDULE"] = {
        "runtime-heartbeat": {"task": "core_runtime.heartbeat", "schedule": 30.0},
        "outbox-dispatch": {"task": "core_runtime.dispatch_outbox", "schedule": 5.0},
        "account-email-dispatch": {"task": "core_runtime.dispatch_account_emails", "schedule": 60.0},
        "evidence-scan": {"task": "core_runtime.scan_evidence", "schedule": 30.0},
        "friendly-cycle": {"task": "core_runtime.process_friendlies", "schedule": 30.0},
        "marketplace-cycle": {"task": "core_runtime.process_marketplace", "schedule": 30.0},
        "matchday-cycle": {"task": "core_runtime.process_matchday", "schedule": 20.0},
        "training-cycle": {"task": "core_runtime.process_training", "schedule": 60.0},
        "season-cycle": {"task": "core_runtime.process_seasons", "schedule": 60.0},
        "live-match-cycle": {"task": "core_runtime.process_live_matches", "schedule": 10.0},
        "match-analytics-cycle": {"task": "core_runtime.project_match_analytics", "schedule": 60.0},
        "player-dynamics-cycle": {"task": "core_runtime.process_player_dynamics", "schedule": 90.0},
        "matchday-commercial-cycle": {"task": "core_runtime.settle_matchday_commercial", "schedule": 120.0},
        "finance-projection": {"task": "core_runtime.sync_club_finance", "schedule": 300.0},
        "contract-terms-cycle": {"task": "core_runtime.process_contract_terms", "schedule": 300.0},
        "payroll-cycle": {"task": "core_runtime.process_payroll", "schedule": 3600.0},
        "player-loan-cycle": {"task": "core_runtime.process_player_loans", "schedule": 3600.0},
        "club-debt-cycle": {"task": "core_runtime.process_club_debt", "schedule": 3600.0},
        "club-licensing-monitor": {"task": "core_runtime.monitor_club_licensing", "schedule": 3600.0},
        "club-licensing-remediation-cycle": {"task": "core_runtime.process_licensing_remediation", "schedule": 3600.0},
        "competition-entry-rights-cycle": {"task": "core_runtime.process_competition_entry_rights", "schedule": 3600.0},
        "competition-draw-governance-cycle": {"task": "core_runtime.process_competition_draw_governance", "schedule": 3600.0},
        "competition-calendar-governance-cycle": {"task": "core_runtime.process_competition_calendar_governance", "schedule": 900.0},
        "match-result-governance-cycle": {"task": "core_runtime.process_match_result_governance", "schedule": 900.0},
        "replay-execution-cycle": {"task": "core_runtime.process_replay_execution", "schedule": 300.0},
        "regulatory-appeals-cycle": {"task": "core_runtime.process_regulatory_appeals", "schedule": 3600.0},
        "mother-final-appeals-cycle": {"task": "core_runtime.process_mother_appeals", "schedule": 3600.0},
        "regulatory-evidence-integrity": {"task": "core_runtime.verify_regulatory_evidence", "schedule": 86400.0},
        "club-asset-valuation": {"task": "core_runtime.snapshot_club_assets", "schedule": 86400.0},
        "player-progression-materialization": {"task": "core_runtime.materialize_player_progression", "schedule": 86400.0},
        "notification-delivery": {"task": "notifications.dispatch_deliveries", "schedule": 30.0},
        "notification-consumer-retry": {"task": "notifications.retry_failed_receipts", "schedule": 60.0},
        "notification-retention": {"task": "notifications.cleanup", "schedule": 86400.0},
        "training-reminders": {"task": "core_runtime.training_reminders", "schedule": 60.0},
    }
    from .scheduling import select_schedule
    if base["FTG_BRIDGE_PROVIDER"]:
        base["CELERY_BEAT_SCHEDULE"]["token-bridge"] = {"task": "core_runtime.process_token_bridge", "schedule": 15.0}
    base["FTG_SCHEDULER_MODE"] = os.environ.get("FTG_SCHEDULER_MODE", "all").strip().lower()
    base["CELERY_BEAT_SCHEDULE"] = select_schedule(
        base["CELERY_BEAT_SCHEDULE"], base["FTG_SCHEDULER_MODE"],
    )
    base["CELERY_TIMEZONE"] = base.get("TIME_ZONE", "UTC")
    base["SEASON_KICKOFF_BATCH_SIZE"] = _int("SEASON_KICKOFF_BATCH_SIZE", 50)
    base["CELERY_TASK_ALWAYS_EAGER"] = _bool("CELERY_TASK_ALWAYS_EAGER", False)
    base["CELERY_TASK_EAGER_PROPAGATES"] = True

    base["RUNTIME_DOMAIN_EVENT_QUEUE"] = os.environ.get("RUNTIME_DOMAIN_EVENT_QUEUE", "domain-events")
    base["RUNTIME_DOMAIN_EVENT_CONSUMERS"] = [
        "notifications.services.consume_domain_event",
        "official_history.services.consume_domain_event",
        "federation_rankings.services.consume_domain_event",
        "historical_movements.services.consume_domain_event",
        "competition_entry_rights.services.consume_domain_event",
        "competition_draw_governance.services.consume_domain_event",
        "competition_calendar_governance.services.consume_domain_event",
        "match_officials_governance.services.consume_domain_event",
        "match_result_governance.services.consume_domain_event",
        "replay_execution.services.consume_domain_event",
    ]
    base["NOTIFICATION_DELIVERY_MAX_ATTEMPTS"] = _int("NOTIFICATION_DELIVERY_MAX_ATTEMPTS", 8)
    base["NOTIFICATION_CONSUMER_MAX_ATTEMPTS"] = _int("NOTIFICATION_CONSUMER_MAX_ATTEMPTS", 12)
    base["RUNTIME_OUTBOX_MAX_ATTEMPTS"] = _int("RUNTIME_OUTBOX_MAX_ATTEMPTS", 12)
    base["RUNTIME_REQUIRE_WORKER_HEARTBEAT"] = _bool("RUNTIME_REQUIRE_WORKER_HEARTBEAT", not debug)
    base["RUNTIME_WORKER_HEARTBEAT_MAX_AGE_SECONDS"] = _int("RUNTIME_WORKER_HEARTBEAT_MAX_AGE_SECONDS", 120)

    # Container/host filesystem paths are explicit in production so static
    # collection and private evidence/media survive application image updates.
    if os.environ.get("DJANGO_STATIC_ROOT"):
        base["STATIC_ROOT"] = os.environ["DJANGO_STATIC_ROOT"]
    if os.environ.get("DJANGO_MEDIA_ROOT"):
        base["MEDIA_ROOT"] = os.environ["DJANGO_MEDIA_ROOT"]

    base["FILE_UPLOAD_PERMISSIONS"] = 0o640
    base["FILE_UPLOAD_DIRECTORY_PERMISSIONS"] = 0o750
    base["DATA_UPLOAD_MAX_MEMORY_SIZE"] = _int("DATA_UPLOAD_MAX_MEMORY_SIZE", 4 * 1024 * 1024)
    base["SECURE_REFERRER_POLICY"] = "strict-origin-when-cross-origin"
    base["SESSION_COOKIE_SAMESITE"] = "Lax"
    base["CSRF_COOKIE_SAMESITE"] = "Lax"

    log_level = os.environ.get("DJANGO_LOG_LEVEL", "INFO").upper()
    base["LOGGING"] = {
        "version": 1,
        "disable_existing_loggers": False,
        "formatters": {
            "standard": {
                "format": "{asctime} {levelname} {name} {message}",
                "style": "{",
            }
        },
        "handlers": {
            "console": {
                "class": "logging.StreamHandler",
                "formatter": "standard",
            }
        },
        "root": {"handlers": ["console"], "level": log_level},
        "loggers": {
            "django.security": {"handlers": ["console"], "level": "WARNING", "propagate": False},
            "django.request": {"handlers": ["console"], "level": "WARNING", "propagate": False},
        },
    }

    base["REGULATORY_EVIDENCE_MAX_UPLOAD_BYTES"] = _int("REGULATORY_EVIDENCE_MAX_UPLOAD_BYTES", 25 * 1024 * 1024)
    base["REGULATORY_EVIDENCE_REQUIRE_MALWARE_SCAN"] = _bool("REGULATORY_EVIDENCE_REQUIRE_MALWARE_SCAN", False)
    base["REGULATORY_EVIDENCE_CLAMD_HOST"] = os.environ.get("REGULATORY_EVIDENCE_CLAMD_HOST", "")
    base["REGULATORY_EVIDENCE_CLAMD_PORT"] = _int("REGULATORY_EVIDENCE_CLAMD_PORT", 3310)
    base["REGULATORY_EVIDENCE_CLAMD_TIMEOUT"] = _int("REGULATORY_EVIDENCE_CLAMD_TIMEOUT", 60)
    allowed_evidence_types = [x.strip() for x in os.environ.get(
        "REGULATORY_EVIDENCE_ALLOWED_CONTENT_TYPES",
        "application/pdf,image/png,image/jpeg,text/plain,text/csv,application/json,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    ).split(",") if x.strip()]
    base["REGULATORY_EVIDENCE_ALLOWED_CONTENT_TYPES"] = allowed_evidence_types

    base["CORS_ALLOW_HEADERS"] = [
        *default_headers,
        "idempotency-key",
    ]
    base["CORS_ALLOW_CREDENTIALS"] = True

    cors_origins = [x.strip() for x in os.environ.get("CORS_ALLOWED_ORIGINS", "").split(",") if x.strip()]
    if cors_origins:
        base["CORS_ALLOWED_ORIGINS"] = cors_origins
    csrf_origins = [x.strip() for x in os.environ.get("CSRF_TRUSTED_ORIGINS", "").split(",") if x.strip()]
    if csrf_origins:
        base["CSRF_TRUSTED_ORIGINS"] = csrf_origins

    # Production defaults: proxy/security hardening remains environment-aware.
    if not debug:
        base["SECURE_HSTS_SECONDS"] = _int("SECURE_HSTS_SECONDS", 31536000)
        base["SECURE_HSTS_INCLUDE_SUBDOMAINS"] = True
        base["SECURE_HSTS_PRELOAD"] = _bool("SECURE_HSTS_PRELOAD", False)
        base["SECURE_CONTENT_TYPE_NOSNIFF"] = True
        base["X_FRAME_OPTIONS"] = "DENY"
        if _bool("DJANGO_BEHIND_HTTPS_PROXY", False):
            base["SECURE_PROXY_SSL_HEADER"] = ("HTTP_X_FORWARDED_PROTO", "https")
            base["USE_X_FORWARDED_HOST"] = True

NOTIFICATION_DELIVERY_CLAIM_TIMEOUT_SECONDS = int(os.getenv("NOTIFICATION_DELIVERY_CLAIM_TIMEOUT_SECONDS", "600"))
NOTIFICATION_RETENTION_DAYS = int(os.getenv("NOTIFICATION_RETENTION_DAYS", "180"))
