from __future__ import annotations

import argparse
import json
import sys
from pathlib import Path
from typing import Any, Optional

import yaml


DEFAULT_CONFIG_PATH = Path(r"D:\projects\skills\vip-report\config.yaml")
DEFAULT_CONFIG_TABLE = "cepconfiguration"
DEFAULT_CONFIG_KEY = "vip-report"

SCRIPT_DIR = Path(__file__).resolve().parent
for dep_dir in [SCRIPT_DIR / ".pydeps", SCRIPT_DIR.parent / ".pydeps", Path.cwd() / ".pydeps"]:
    if dep_dir.exists() and str(dep_dir) not in sys.path:
        sys.path.insert(0, str(dep_dir))


def _import_pymysql():
    try:
        import pymysql  # type: ignore
    except Exception as exc:
        raise RuntimeError(
            "Missing dependency pymysql. Please install it in ShadowBot Python, or copy a .pydeps folder containing pymysql."
        ) from exc
    return pymysql


def add_config_source_args(parser: argparse.ArgumentParser, *, default_config: Optional[Path] = None) -> None:
    parser.add_argument("--config", default=str(default_config or DEFAULT_CONFIG_PATH))
    # Default to DB so automation can run without carrying local config files.
    parser.add_argument("--config-source", choices=["yaml", "db"], default="db")
    parser.add_argument("--config-table", default=DEFAULT_CONFIG_TABLE)
    parser.add_argument("--config-key", default=DEFAULT_CONFIG_KEY)
    parser.add_argument("--mysql-host", default="192.168.138.182")
    parser.add_argument("--mysql-port", type=int, default=3306)
    parser.add_argument("--mysql-user", default="ceptest")
    parser.add_argument("--mysql-password", default="ck@123456")
    parser.add_argument("--mysql-database", default="ckc_cep_db_test")


def mysql_conn_kwargs_from_args(args: argparse.Namespace) -> dict[str, Any]:
    return {
        "host": args.mysql_host,
        "port": int(args.mysql_port),
        "user": args.mysql_user,
        "password": args.mysql_password,
        "database": args.mysql_database,
        "charset": "utf8mb4",
    }


def load_runtime_config(args: argparse.Namespace, *, default_config: Optional[Path] = None) -> dict[str, Any]:
    if args.config_source == "yaml":
        path = Path(args.config or default_config or DEFAULT_CONFIG_PATH).resolve()
        return yaml.safe_load(path.read_text(encoding="utf-8"))
    return load_db_config(args)


def load_db_config(args: argparse.Namespace) -> dict[str, Any]:
    pymysql = _import_pymysql()
    table = str(args.config_table or DEFAULT_CONFIG_TABLE).strip()
    key = str(args.config_key or DEFAULT_CONFIG_KEY).strip()
    conn_args = mysql_conn_kwargs_from_args(args)
    conn_args["cursorclass"] = pymysql.cursors.DictCursor
    conn = pymysql.connect(**conn_args)
    try:
        with conn.cursor() as cur:
            cur.execute(
                """
                SELECT COLUMN_NAME
                FROM information_schema.COLUMNS
                WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME=%s
                """,
                (table,),
            )
            cols = {str(r["COLUMN_NAME"]).lower() for r in (cur.fetchall() or [])}
            if {"config_key", "config_json"}.issubset(cols):
                sql = f"SELECT config_json AS cfg FROM `{table}` WHERE config_key=%s ORDER BY id DESC LIMIT 1"
            elif {"key", "value"}.issubset(cols):
                sql = f"SELECT `value` AS cfg FROM `{table}` WHERE `key`=%s ORDER BY id DESC LIMIT 1"
            else:
                raise RuntimeError(
                    f"Unsupported config table schema for `{table}`. "
                    f"Need columns (config_key,config_json) or (key,value), actual={sorted(cols)}"
                )
            cur.execute(sql, (key,))
            row = cur.fetchone()
    finally:
        conn.close()

    if not row:
        raise RuntimeError(f"No config found in `{table}` for config_key={key!r}")

    raw = row.get("cfg")
    if raw is None:
        raise RuntimeError(f"`{table}` row found but config_json is NULL for config_key={key!r}")

    if isinstance(raw, (dict, list)):
        return raw

    text = str(raw).strip()
    if not text:
        raise RuntimeError(f"`{table}` row found but config_json is empty for config_key={key!r}")
    try:
        return json.loads(text)
    except Exception:
        return yaml.safe_load(text)
