from __future__ import annotations

import json
from typing import Any

from psycopg.cursor import Cursor


class BasePostgresHelpersMixin:
    """Static normalization and introspection helpers."""

    def _table_exists(cursor: Cursor[Any], table_name: str) -> bool:
        """Return True when a target table exists in the current schema search path."""
        cursor.execute("SELECT to_regclass(%s) IS NOT NULL AS exists", (table_name,))
        row = cursor.fetchone()
        return bool(row and row.get("exists"))

    def _ensure_list(value: Any) -> list[Any]:
        """Chuẩn hóa JSON/list từ PostgreSQL về list Python."""
        if value is None:
            return []
        if isinstance(value, list):
            return value
        if isinstance(value, str):
            try:
                parsed = json.loads(value)
            except json.JSONDecodeError:
                return []
            return parsed if isinstance(parsed, list) else []
        return []

    def _ensure_dict(value: Any) -> dict[str, Any]:
        """Chuẩn hóa JSON/object từ PostgreSQL về dict Python."""
        if value is None:
            return {}
        if isinstance(value, dict):
            return value
        if isinstance(value, str):
            try:
                parsed = json.loads(value)
            except json.JSONDecodeError:
                return {}
            return parsed if isinstance(parsed, dict) else {}
        return {}

    def _ensure_string_list(value: Any) -> list[str]:
        """Chuẩn hóa nhiều kiểu dữ liệu về list chuỗi."""
        if value is None:
            return []
        if isinstance(value, str):
            try:
                parsed = json.loads(value)
            except json.JSONDecodeError:
                return [value]
            if isinstance(parsed, list):
                return [str(item) for item in parsed]
            return [str(parsed)]
        if isinstance(value, list):
            return [str(item) for item in value]
        return [str(value)]
