"""SQL parser — extracts CREATE TABLE/VIEW/PROCEDURE/FUNCTION/INDEX definitions."""

from __future__ import annotations

import re

from codectx.parser.types import EntityRecord, ParseResult

_CREATE_TABLE_RE = re.compile(
    r"CREATE\s+(?:OR\s+REPLACE\s+)?(?:TEMPORARY\s+|TEMP\s+)?TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?([`\"\[]?[\w.]+[`\"\]]?)",
    re.IGNORECASE,
)
_CREATE_VIEW_RE = re.compile(
    r"CREATE\s+(?:OR\s+REPLACE\s+)?(?:MATERIALIZED\s+)?VIEW\s+([`\"\[]?[\w.]+[`\"\]]?)",
    re.IGNORECASE,
)
_CREATE_PROC_RE = re.compile(
    r"CREATE\s+(?:OR\s+REPLACE\s+)?PROCEDURE\s+([`\"\[]?[\w.]+[`\"\]]?)",
    re.IGNORECASE,
)
_CREATE_FUNC_RE = re.compile(
    r"CREATE\s+(?:OR\s+REPLACE\s+)?FUNCTION\s+([`\"\[]?[\w.]+[`\"\]]?)",
    re.IGNORECASE,
)
_CREATE_INDEX_RE = re.compile(
    r"CREATE\s+(?:UNIQUE\s+)?INDEX\s+(?:IF\s+NOT\s+EXISTS\s+)?([`\"\[]?[\w.]+[`\"\]]?)\s+ON\s+([`\"\[]?[\w.]+[`\"\]]?)",
    re.IGNORECASE,
)
_CREATE_TRIGGER_RE = re.compile(
    r"CREATE\s+(?:OR\s+REPLACE\s+)?TRIGGER\s+([`\"\[]?[\w.]+[`\"\]]?)",
    re.IGNORECASE,
)
_COLUMN_RE = re.compile(
    r"^\s+([`\"\[]?\w+[`\"\]]?)\s+(?:INT|INTEGER|BIGINT|TEXT|VARCHAR|CHAR|BOOLEAN|BOOL|FLOAT|DOUBLE|DECIMAL|DATE|DATETIME|TIMESTAMP|BLOB|JSON|SERIAL|NUMERIC|REAL)\b",
    re.IGNORECASE | re.MULTILINE,
)

_NAME_STRIP_RE = re.compile(r"[`\"\[\]]")


def _strip_name(name: str) -> str:
    return _NAME_STRIP_RE.sub("", name).strip()


def _line_number(content: str, pos: int) -> int:
    return content[:pos].count("\n") + 1


def parse_sql(file_path: str, content: str) -> ParseResult:
    result = ParseResult(file_path=file_path, language="sql")

    for pattern, etype in [
        (_CREATE_TABLE_RE, "table"),
        (_CREATE_VIEW_RE, "view"),
        (_CREATE_PROC_RE, "procedure"),
        (_CREATE_FUNC_RE, "function"),
        (_CREATE_TRIGGER_RE, "trigger"),
    ]:
        for m in pattern.finditer(content):
            name = _strip_name(m.group(1))
            ln = _line_number(content, m.start())
            result.entities.append(EntityRecord(
                name=name.split(".")[-1],
                type=etype,
                qualified_name=name,
                start_line=ln,
                end_line=ln,
                language="sql",
            ))

    for m in _CREATE_INDEX_RE.finditer(content):
        idx_name = _strip_name(m.group(1))
        table_name = _strip_name(m.group(2))
        ln = _line_number(content, m.start())
        result.entities.append(EntityRecord(
            name=idx_name,
            type="index",
            qualified_name=idx_name,
            start_line=ln,
            end_line=ln,
            parent=table_name,
            language="sql",
        ))

    return result
