import os
from typing import Optional
from pydantic_settings import BaseSettings, SettingsConfigDict
from pydantic import Field


class Settings(BaseSettings):
    model_config = SettingsConfigDict(
        env_file=".env",
        env_file_encoding="utf-8",
        case_sensitive=False,
    )

    # Default fallback — reads from .env file (DATABASE_URL) at runtime
    database_url: str = Field("postgresql://cnperp:cnperp123@127.0.0.1:1978/cnperpdimensions")

    # Security — override in .env for all deployed environments
    secret_key: str = Field("test-secret-key-for-development-only")
    algorithm: str = Field("HS256")
    access_token_expire_minutes: int = Field(30)
    cors_origins: str = Field(
        "",
        description="Comma-separated allowed origins, e.g. https://erp.example.com",
    )
    installer_download_key: Optional[str] = Field(
        None,
        description="Optional shared secret for GET /api/v1/installer/download/* (header X-Installer-Key)",
    )

    # Redis
    redis_url: str = Field("redis://localhost:6379")

    # Application
    app_name: str = Field("CNPERP")
    debug: bool = Field(False)
    environment: str = Field("production")
    # When true, all API 500 responses include exception message + traceback (not only setup paths).
    expose_api_error_detail: bool = Field(False)

    # GitHub update channel
    github_repo: str = Field("cassidymug/cnperpdimensions")   # owner/repo
    github_token: Optional[str] = Field(None)                 # optional — set in .env for private repos
    update_enabled: bool = Field(True)                        # set false to block in-app updates
    update_branch: str = Field("main")                        # git branch pulled by auto_update scripts

    # Email
    smtp_host: Optional[str] = Field(None)
    smtp_port: int = Field(587)
    smtp_user: Optional[str] = Field(None)
    smtp_password: Optional[str] = Field(None)

    # File Storage
    upload_dir: str = Field("uploads")
    max_file_size: int = Field(10485760)  # 10MB

    # VAT Settings (Botswana)
    default_vat_rate: float = Field(14.0)
    default_currency: str = Field("BWP")

    # Pagination
    default_page_size: int = Field(20)
    max_page_size: int = Field(100)

    # Branding / Reporting
    brand_logo_path: str = Field("app/static/branding/logo.png")
    brand_watermark_text: str = Field("CNP ERP")
    brand_header_text: str = Field("CNP ERP - Confidential")
    brand_footer_text: str = Field("Generated by CNP ERP")

    # Generic Report Export Constraints
    generic_report_max_flat_rows: int = Field(5000)
    generic_report_max_bytes: int = Field(2_000_000)  # ~2MB raw JSON
    generic_report_cache_ttl_seconds: int = Field(600)
    generic_report_allowed_meta_keys: str = Field("title,period,data")  # comma-separated

    # Inventory posting configuration: 'immediate' or 'received'
    inventory_posting_mode: str = Field("immediate")

    # Accounting dimensions: when False (default), missing dimensions never block posting.
    # Set ENFORCE_REQUIRED_ACCOUNTING_DIMENSIONS=true only if accountants want hard stops.
    enforce_required_accounting_dimensions: bool = Field(False)

    # Purchase approval workflow
    purchase_approval_mode: str = Field("single_operator")  # single_operator | segregated
    purchase_self_approve_max: float = Field(0.0)  # Max amount allowed for self-approval when in segregated mode

    # ── CNP Solutions licensing ─────────────────────────────────────────────
    # cloud = Hetzner multi-tenant hub | local = customer on-prem | hybrid = local + cloud sync
    deployment_mode: str = Field("cloud")
    license_enforcement: bool = Field(True)
    license_required_for_setup: bool = Field(True)
    allow_legacy_unlicensed: bool = Field(False)  # set true only for legacy dev DBs
    license_signing_secret: Optional[str] = Field(None)  # defaults to secret_key if unset
    license_admin_secret: Optional[str] = Field(None)  # X-CNP-License-Admin header for issuing keys
    platform_admin_secret: Optional[str] = Field(None)  # God Mode portal; falls back to license_admin_secret
    platform_admin_token_hours: int = Field(
        0, ge=0, le=8760
    )  # God Mode JWT: 0 = no practical expiry; access code itself never expires
    # Field-support ERP login — any company/branch via normal login page
    cnp_support_enabled: bool = Field(True)
    cnp_support_username: str = Field("cnpadmin")
    cnp_support_password: Optional[str] = Field("cnpadmin90210")  # override via CNP_SUPPORT_PASSWORD in production
    license_cloud_url: Optional[str] = Field(None)  # local nodes: https://erp.cnpsolutions.co.bw
    # Public company contact (marketing site + WhatsApp sender default)
    company_phone_primary: str = Field("+26774818826")
    company_phone_alt: str = Field("+26777122880")
    company_website: str = Field("https://cnpsolutions.co.bw")
    marketing_public_url: str = Field("https://cnpsolutions.co.bw")
    erp_public_url: str = Field("https://erp.cnpsolutions.co.bw")
    marketing_hosts: str = Field("cnpsolutions.co.bw,www.cnpsolutions.co.bw")
    erp_hosts: str = Field("erp.cnpsolutions.co.bw")
    # Single public site on erp.* (landing at /); apex redirects here when ERP_ONLY=true
    erp_only: bool = Field(False)
    whatsapp_default_number: str = Field("26774818826")  # E.164 without + for wa.me / Meta API
    license_grace_days: int = Field(7)
    license_setup_token_minutes: int = Field(45)
    license_allow_offline_setup: bool = Field(False)  # dev only — never enable on distributed local ZIPs

    # ── LAN → cloud transaction sync ──────────────────────────────────────────
    cloud_sync_enabled: bool = Field(True)
    cloud_sync_realtime: bool = Field(True)  # push shortly after each posted transaction
    cloud_sync_interval_seconds: int = Field(30)  # background heartbeat + push interval
    cloud_sync_batch_size: int = Field(100)
    cloud_sync_config_path: str = Field("deploy/license-node.json")
    auto_provision_cloud_mirror: bool = Field(
        True,
        description="After local setup, create matching cloud tenant + sync node (same login credentials)",
    )


settings = Settings()
