"""
config.py — People Hub Interview Platform
Single source of truth for all configuration.
All values loaded from .env — nothing hardcoded.

Usage anywhere in the project:
    from config import settings
    settings.OPENAI_API_KEY
"""
from __future__ import annotations
from pathlib import Path
from dotenv import load_dotenv
import os

# Load .env relative to this file
load_dotenv(Path(__file__).parent / ".env")


class Settings:
    # ── Application ─────────────────────────────────────────────
    APP_HOST: str        = os.getenv("APP_HOST", "0.0.0.0")
    APP_PORT: int        = int(os.getenv("APP_PORT", "8000"))
    APP_DEBUG: bool      = os.getenv("APP_DEBUG", "true").lower() == "true"
    APP_NAME: str        = os.getenv("APP_NAME", "People Hub – Candidate Interview")
    APP_VERSION: str     = os.getenv("APP_VERSION", "1.0.0")

    # ── Security ─────────────────────────────────────────────────
    JWT_SECRET_KEY: str  = os.getenv("JWT_SECRET_KEY", "CHANGE_ME_IN_PRODUCTION")
    JWT_ALGORITHM: str   = os.getenv("JWT_ALGORITHM", "HS256")
    JWT_EXPIRE_MINUTES: int = int(os.getenv("JWT_EXPIRE_MINUTES", "480"))
    ACCESS_KEY_EXPIRE_HOURS: int = int(os.getenv("ACCESS_KEY_EXPIRE_HOURS", "72"))

    # ── OpenAI ───────────────────────────────────────────────────
    OPENAI_API_KEY: str    = os.getenv("OPENAI_API_KEY", "")
    OPENAI_BASE_URL: str   = os.getenv("OPENAI_BASE_URL", "https://api.openai.com/v1")
    OPENAI_MODEL: str      = os.getenv("OPENAI_MODEL", "gpt-4o-mini")
    OPENAI_TEMPERATURE: float = float(os.getenv("OPENAI_TEMPERATURE", "0.0"))
    OPENAI_MAX_TOKENS_COMPILE: int = int(os.getenv("OPENAI_MAX_TOKENS_COMPILE", "600"))
    OPENAI_MAX_TOKENS_EVAL: int    = int(os.getenv("OPENAI_MAX_TOKENS_EVAL", "1200"))
    OPENAI_MAX_TOKENS_CAPTCHA: int = int(os.getenv("OPENAI_MAX_TOKENS_CAPTCHA", "100"))

    # ── Data Storage ──────────────────────────────────────────────
    DATA_DIR: Path               = Path(os.getenv("DATA_DIR", "./data"))
    USERS_FILE: Path             = Path(os.getenv("USERS_FILE", "./data/users.json"))
    CODING_RESULTS_FILE: Path    = Path(os.getenv("CODING_RESULTS_FILE", "./data/coding_assessment.json"))
    FRAUD_LOG_FILE: Path         = Path(os.getenv("FRAUD_LOG_FILE", "./data/fraud_log.json"))
    SESSIONS_FILE: Path          = Path(os.getenv("SESSIONS_FILE", "./data/sessions.json"))
    PHOTO_DIR: Path              = Path(os.getenv("PHOTO_DIR", "./data/photos"))

    # ── CORS ──────────────────────────────────────────────────────
    ALLOWED_ORIGINS: list[str] = [
        o.strip()
        for o in os.getenv("ALLOWED_ORIGINS", "http://localhost:8000").split(",")
    ]

    # ── PostgreSQL ────────────────────────────────────────────────
    DB_HOST: str         = os.getenv("DB_HOST", "")
    DB_PORT: int         = int(os.getenv("DB_PORT", "5432"))
    DB_NAME: str         = os.getenv("DB_NAME", "")
    DB_USER: str         = os.getenv("DB_USER", "")
    DB_PASSWORD: str     = os.getenv("DB_PASSWORD", "")
    DB_SSLMODE: str      = os.getenv("DB_SSLMODE", "prefer")
    DB_CONNECT_TIMEOUT: int = int(os.getenv("DB_CONNECT_TIMEOUT", "10"))
    DB_POOL_MIN: int     = int(os.getenv("DB_POOL_MIN", "1"))
    DB_POOL_MAX: int     = int(os.getenv("DB_POOL_MAX", "10"))
    DB_FAIL_FAST: bool   = os.getenv("DB_FAIL_FAST", "true").lower() == "true"

    DB_TABLE_PARTICIPANT: str       = os.getenv("DB_TABLE_PARTICIPANT", "participant")
    DB_TABLE_ROLE_PLAY: str         = os.getenv("DB_TABLE_ROLE_PLAY", "role_play")
    DB_TABLE_CODING_QUESTIONS: str  = os.getenv("DB_TABLE_CODING_QUESTIONS", "coding_questions")

    # ── Logging ───────────────────────────────────────────────────
    LOG_LEVEL: str       = os.getenv("LOG_LEVEL", "INFO").upper()
    LOG_DB_PAYLOAD: bool = os.getenv("LOG_DB_PAYLOAD", "true").lower() == "true"

    @property
    def DB_DSN(self) -> str:
        """Single-line DSN suitable for psycopg2."""
        return (
            f"host={self.DB_HOST} port={self.DB_PORT} "
            f"dbname={self.DB_NAME} user={self.DB_USER} "
            f"password={self.DB_PASSWORD} sslmode={self.DB_SSLMODE} "
            f"connect_timeout={self.DB_CONNECT_TIMEOUT}"
        )

    # ── Fraud Detection ───────────────────────────────────────────
    FRAUD_MAX_TAB_SWITCHES: int   = int(os.getenv("FRAUD_MAX_TAB_SWITCHES", "3"))
    FRAUD_MAX_FACE_VIOLATIONS: int = int(os.getenv("FRAUD_MAX_FACE_VIOLATIONS", "3"))
    FRAUD_MAX_PASTE_EVENTS: int   = int(os.getenv("FRAUD_MAX_PASTE_EVENTS", "5"))
    FRAUD_INACTIVITY_SECONDS: int = int(os.getenv("FRAUD_INACTIVITY_SECONDS", "120"))

    # ── Session Lock (Role Play) ─────────────────────────────────
    # Master switch for the in-session navigation lock (back-button
    # guard, beforeunload prompt, keyboard shortcut swallow, sign-out
    # block) that protects a live role-play session. Set to "false"
    # in .env during demos / screen-share walkthroughs (Teams, Meet,
    # Zoom) so the presenter can move around freely; keep "true" in
    # production. Fraud-detection logic is independent of this flag
    # and continues to run unless explicitly disabled elsewhere.
    # Exposed to the frontend via /api/config/ui as
    # `is_session_lock_enabled` — the role-play page checks that
    # value before engaging the lock when entering the session
    # screen, so no existing IDs / APIs / WS payloads change.
    IS_SESSION_LOCK_ENABLED: bool = (
        os.getenv("IS_SESSION_LOCK_ENABLED", "true").strip().lower()
        in ("1", "true", "yes", "on")
    )

    # ── Interview Stages ──────────────────────────────────────────
    STAGE_ASSESSMENT: int      = 1
    STAGE_ROLEPLAY: int        = 2
    STAGE_CODING: int          = 3
    STAGE_TECHNICAL: int       = 4
    STAGE_HUMAN_INTERVIEW: int = 5
    STAGE_HR_ROUND: int        = 6

    STAGE_ROUTES: dict[int, str] = {
        1: "/people_hub_assessment",
        2: "/people_hub_role_play",
        3: "/people_hub_coding_assessment",
        4: "/interview/technical",
        5: "/interview/human",
        6: "/interview/hr",
    }

    STAGE_NAMES: dict[int, str] = {
        1: "AI Screening Assessment",
        2: "Role Play",
        3: "Coding Test",
        4: "Technical Interview",
        5: "Human Interview",
        6: "HR Round",
    }

    # ── UI feature flags ──────────────────────────────────────────
    # Toggle the "Developer Skill" entry on the setup screen. Production
    # should set SHOW_DEV_SKILL_BUTTON=false in .env so candidates don't
    # see internal-only entrances. Dev / staging keep it true.
    SHOW_DEV_SKILL_BUTTON: bool = os.getenv("SHOW_DEV_SKILL_BUTTON", "false").lower() == "true"

    # Support contact details — surfaced on the reusable stage popup
    # (no-interview / instructions screens) so the candidate has a
    # single source of help info regardless of round.
    SUPPORT_PHONE: str = os.getenv("SUPPORT_PHONE", "+91 9221980198")
    SUPPORT_EMAIL: str = os.getenv("SUPPORT_EMAIL", "support@golsh.com")

    # ── Coding Assessment ─────────────────────────────────────────
    CODING_TIME_MINUTES: int   = int(os.getenv("CODING_TIME_MINUTES", "45"))
    CODING_MAX_QUESTIONS: int  = int(os.getenv("CODING_MAX_QUESTIONS", "5"))

    # ── Tavus CVI ─────────────────────────────────────────────────
    TAVUS_API_KEY: str    = os.getenv("TAVUS_API_KEY", "")
    TAVUS_BASE_URL: str   = os.getenv("TAVUS_BASE_URL", "https://tavusapi.com/v2")
    TAVUS_REPLICA_ID: str = os.getenv("TAVUS_REPLICA_ID", "")
    TAVUS_PERSONA_ID: str = os.getenv("TAVUS_PERSONA_ID", "")

    # ── Role Play — manual avatar selection ──────────────────────
    # When true, the Custom Video Role Play flow opens an avatar
    # picker modal listing every MP4 in static/assets/avatars/ so
    # the candidate (or demo operator) can pick exactly which face
    # the AI uses. When false the existing seeded-random pick
    # (pick_avatar(seed=session_id)) runs unchanged. Exposed to the
    # frontend via /api/config/ui so the modal only mounts when
    # the flag is on.
    IS_VIDEO_ROLEPLAY_SELECTION: bool = (
        os.getenv("IS_VIDEO_ROLEPLAY_SELECTION", "true").strip().lower()
        in ("1", "true", "yes", "on")
    )

    # ── External People Hub APIs ──────────────────────────────────
    PEOPLEHUB_BASE_URL: str   = os.getenv(
        "PEOPLEHUB_BASE_URL",
        "https://demo.golsh2e.com/eReKruit/api",
    )
    PEOPLEHUB_TIMEOUT: int    = int(os.getenv("PEOPLEHUB_TIMEOUT", "20"))
    PEOPLEHUB_RETRIES: int    = int(os.getenv("PEOPLEHUB_RETRIES", "2"))
    PEOPLEHUB_VERIFY_TLS: bool = os.getenv("PEOPLEHUB_VERIFY_TLS", "true").lower() == "true"

    # Stage to fall back to if the external API doesn't return current_stage
    DEFAULT_FALLBACK_STAGE: int = int(os.getenv("DEFAULT_FALLBACK_STAGE", "2"))

    def ensure_dirs(self) -> None:
        """Create all required data directories on startup."""
        self.DATA_DIR.mkdir(parents=True, exist_ok=True)
        self.PHOTO_DIR.mkdir(parents=True, exist_ok=True)


settings = Settings()
