from __future__ import annotations

from pathlib import Path
from urllib.parse import quote_plus

from dotenv import set_key

from app.core.config import ROOT_DIR, Settings, refresh_settings
from app.db.session import configure_session_factory
from app.schemas.bootstrap import BootstrapSetupPayload, BootstrapStateRead

ENV_FILE = ROOT_DIR / ".env"
ENV_EXAMPLE_FILE = ROOT_DIR / ".env.example"


def ensure_env_file() -> Path:
    if ENV_FILE.exists():
        return ENV_FILE

    if ENV_EXAMPLE_FILE.exists():
        ENV_FILE.write_text(ENV_EXAMPLE_FILE.read_text(encoding="utf-8"), encoding="utf-8")
    else:
        ENV_FILE.write_text("", encoding="utf-8")

    return ENV_FILE


def build_database_url(payload: BootstrapSetupPayload) -> str:
    username = quote_plus(payload.postgres_user)
    password = quote_plus(payload.postgres_password)
    return (
        f"postgresql+psycopg://{username}:{password}"
        f"@{payload.postgres_host}:{payload.postgres_port}/{payload.postgres_db}"
    )


def build_bootstrap_state(
    settings: Settings,
    *,
    redact_infrastructure: bool = False,
) -> BootstrapStateRead:
    return BootstrapStateRead(
        initialized=settings.setup_completed,
        company={
            "name": settings.company_name,
            "code": settings.company_code,
            "admin_email": settings.admin_email,
        },
        web={"host": settings.web_host, "port": settings.web_port},
        server={"host": settings.app_host, "port": settings.app_port},
        database={
            "driver": "postgresql",
            "host": "" if redact_infrastructure else settings.postgres_host,
            "port": settings.postgres_port,
            "name": settings.postgres_db,
            "username": "" if redact_infrastructure else settings.postgres_user,
            "password_configured": bool(settings.postgres_password),
        },
        redis={
            "enabled": bool(settings.redis_url),
            "url": "" if redact_infrastructure else settings.redis_url or "",
        },
    )


def persist_bootstrap_config(
    payload: BootstrapSetupPayload,
    settings: Settings,
) -> BootstrapStateRead:
    env_file = ensure_env_file()
    database_url = build_database_url(payload)
    vite_api_base_url = f"http://{settings.app_host}:{settings.app_port}{settings.api_v1_prefix}"

    updates = {
        "SETUP_COMPLETED": "true",
        "COMPANY_NAME": payload.company_name,
        "COMPANY_CODE": payload.company_code,
        "ADMIN_EMAIL": payload.admin_email or "",
        "POSTGRES_HOST": payload.postgres_host,
        "POSTGRES_PORT": str(payload.postgres_port),
        "POSTGRES_DB": payload.postgres_db,
        "POSTGRES_USER": payload.postgres_user,
        "POSTGRES_PASSWORD": payload.postgres_password,
        "DATABASE_URL": database_url,
        "REDIS_URL": payload.redis_url or "",
        "VITE_API_BASE_URL": vite_api_base_url,
    }

    for key, value in updates.items():
        set_key(str(env_file), key, value, quote_mode="auto", encoding="utf-8")

    refreshed_settings = refresh_settings(updates)
    configure_session_factory()
    return build_bootstrap_state(refreshed_settings)
