"""
SQL 解析与分类：按 ; 拆分（尊重字符串与注释），识别 DDL / SELECT / 写操作。
"""
from __future__ import annotations

import re
from dataclasses import dataclass

import sqlparse


@dataclass
class StatementAnalysis:
    """单条 SQL 的分析结果"""
    sql: str
    stype: str  # "DDL" | "SELECT" | "INSERT" | "UPDATE" | "DELETE" | "OTHER"
    first_keyword: str
    need_confirm: bool
    message: str = ""


def split_sql(text: str) -> list[str]:
    """
    按语句结束符 ; 拆分，尊重字符串与注释。
    使用 sqlparse.split，并过滤空与纯空白/注释。
    """
    if not (text or "").strip():
        return []
    try:
        parts = sqlparse.split(text)
    except Exception:
        return []
    out = []
    for p in parts:
        s = (p or "").strip()
        if not s:
            continue
        # 去掉纯注释块
        parsed = sqlparse.parse(s)
        if not parsed:
            continue
        stmt = parsed[0]
        # 若整条是注释则跳过
        tokens = list(stmt.flatten())
        if not tokens or all(t.ttype in (sqlparse.tokens.Comment, sqlparse.tokens.Whitespace) for t in tokens):
            continue
        out.append(s)
    return out


def _first_keyword(sql: str) -> str:
    """取 SQL 第一个有效词（跳过注释与空白）。"""
    sql_clean = (sql or "").strip()
    if not sql_clean:
        return ""
    # 去掉行首注释
    for line in sql_clean.splitlines():
        line = line.strip()
        if line.startswith("--") or line.startswith("#"):
            continue
        m = re.match(r"^([a-zA-Z_]+)", line, re.IGNORECASE)
        if m:
            return (m.group(1) or "").upper()
    m = re.match(r"^\s*([a-zA-Z_]+)", sql_clean, re.IGNORECASE)
    return (m.group(1) or "").upper() if m else ""


def classify_statement(sql: str) -> tuple[str, str]:
    """
    分类单条 SQL。返回 (stype, first_keyword)。
    stype: DDL | SELECT | INSERT | UPDATE | DELETE | OTHER
    """
    first = _first_keyword(sql)
    if not first:
        return "OTHER", ""

    ddl_keywords = {"CREATE", "ALTER", "DROP", "TRUNCATE", "RENAME"}
    if first in ddl_keywords:
        return "DDL", first
    if first == "SELECT":
        return "SELECT", first
    if first == "INSERT":
        return "INSERT", first
    if first == "UPDATE":
        return "UPDATE", first
    if first == "DELETE":
        return "DELETE", first
    return "OTHER", first


def analyze_one(sql: str, read_only: bool = False) -> StatementAnalysis:
    """分析单条 SQL，返回是否需要确认等。"""
    stype, first = classify_statement(sql)
    need_confirm = False
    message = ""

    if stype == "DDL":
        message = "DDL 请在数据库客户端中手动执行，本 MCP 不执行 DDL。"
        need_confirm = False
    elif stype == "SELECT":
        message = "只读查询，将应用 max_select_rows 限制。"
    elif stype in ("INSERT", "UPDATE", "DELETE"):
        if read_only:
            message = "当前为只读模式，拒绝执行写操作。"
            need_confirm = False
        else:
            need_confirm = True
            message = "写操作需传入 confirm=true 后执行。"
    else:
        message = "未识别的语句类型，建议先使用 analyze_sql 查看。"
        need_confirm = True

    return StatementAnalysis(
        sql=sql.strip(),
        stype=stype,
        first_keyword=first,
        need_confirm=need_confirm,
        message=message,
    )


def analyze_many(sql_text: str, read_only: bool = False) -> list[StatementAnalysis]:
    """拆分多条并逐条分析，用于 analyze_sql 工具。"""
    statements = split_sql(sql_text)
    return [analyze_one(s, read_only) for s in statements]


def ensure_single_statement(sql_text: str) -> str:
    """
    若解析出多条语句则抛出 ValueError；否则返回 strip 后的单条。
    """
    statements = split_sql(sql_text)
    if len(statements) == 0:
        raise ValueError("未解析到有效 SQL 语句。")
    if len(statements) > 1:
        raise ValueError(
            f"当前仅支持单条 SQL，共解析到 {len(statements)} 条，请分批执行或只传入一条。"
        )
    return statements[0]
