from db import get_connection


def upsert_referee(
    full_name: str,
    lastname: str = "",
    name: str = "",
    middle_name: str = "",
    city: str = "",
    external_id: str | None = None,
    is_active: bool = True,
) -> int:
    query = """
    INSERT INTO referees (
        external_id,
        full_name,
        lastname,
        name,
        middle_name,
        city,
        is_active,
        created_at,
        updated_at
    )
    VALUES (%s, %s, %s, %s, %s, %s, %s, NOW(), NOW())
    ON CONFLICT (external_id)
    DO UPDATE SET
        full_name = EXCLUDED.full_name,
        lastname = EXCLUDED.lastname,
        name = EXCLUDED.name,
        middle_name = EXCLUDED.middle_name,
        city = EXCLUDED.city,
        is_active = EXCLUDED.is_active,
        updated_at = NOW()
    RETURNING id;
    """

    conn = get_connection()
    try:
        with conn.cursor() as cur:
            cur.execute(
                query,
                (
                    str(external_id).strip() if external_id else None,
                    full_name.strip(),
                    lastname.strip(),
                    name.strip(),
                    middle_name.strip(),
                    city.strip(),
                    is_active,
                ),
            )
            row = cur.fetchone()
        conn.commit()
        return row[0]
    except Exception:
        conn.rollback()
        raise
    finally:
        conn.close()


def get_referee_id_by_name(full_name: str) -> int | None:
    query = """
    SELECT id
    FROM referees
    WHERE LOWER(full_name) = LOWER(%s)
    LIMIT 1;
    """

    conn = get_connection()
    try:
        with conn.cursor() as cur:
            cur.execute(query, (full_name.strip(),))
            row = cur.fetchone()
            return row[0] if row else None
    finally:
        conn.close()
        

def search_referees_for_admin(q: str = "") -> list[dict]:
    conn = get_connection()
    try:
        with conn.cursor() as cur:
            if q.strip():
                pattern = f"%{q.strip()}%"
                cur.execute(
                    """
                    SELECT
                        r.id,
                        r.full_name,
                        r.external_id
                    FROM referees r
                    WHERE
                        r.full_name ILIKE %s
                        OR COALESCE(r.external_id, '') ILIKE %s
                    ORDER BY r.full_name ASC, r.id ASC
                    LIMIT 200
                    """,
                    (pattern, pattern),
                )
            else:
                cur.execute(
                    """
                    SELECT
                        r.id,
                        r.full_name,
                        r.external_id
                    FROM referees r
                    ORDER BY r.id DESC
                    LIMIT 200
                    """
                )
            rows = cur.fetchall()

        return [
            {
                "id": row[0],
                "full_name": row[1] or "",
                "external_id": row[2] or "",
            }
            for row in rows
        ]
    finally:
        conn.close()


def get_referee_by_id(referee_id: int) -> dict | None:
    conn = get_connection()
    try:
        with conn.cursor() as cur:
            cur.execute(
                """
                SELECT
                    r.id,
                    r.full_name,
                    r.external_id
                FROM referees r
                WHERE r.id = %s
                LIMIT 1
                """,
                (referee_id,),
            )
            row = cur.fetchone()

        if not row:
            return None

        return {
            "id": row[0],
            "full_name": row[1] or "",
            "external_id": row[2] or "",
        }
    finally:
        conn.close()


def update_referee_admin(
    referee_id: int,
    full_name: str = "",
    external_id: str = "",
) -> None:
    conn = get_connection()
    try:
        with conn.cursor() as cur:
            cur.execute(
                """
                UPDATE referees
                SET
                    full_name = %s,
                    external_id = NULLIF(%s, '')
                WHERE id = %s
                """,
                (
                    full_name.strip(),
                    external_id.strip(),
                    referee_id,
                ),
            )
        conn.commit()
    except Exception:
        conn.rollback()
        raise
    finally:
        conn.close()


def get_all_referees() -> list[dict]:
    conn = get_connection()
    try:
        with conn.cursor() as cur:
            cur.execute(
                """
                SELECT
                    r.id,
                    r.full_name,
                    r.external_id
                FROM referees r
                WHERE COALESCE(r.is_active, TRUE) = TRUE
                ORDER BY r.full_name ASC, r.id ASC
                """
            )
            rows = cur.fetchall()

        return [
            {
                "referee_id": row[0],
                "id": row[0],
                "referee_name": row[1] or "",
                "full_name": row[1] or "",
                "external_id": row[2] or "",
            }
            for row in rows
        ]
    finally:
        conn.close()


def replace_match_referees(match_id: int, rows: list[dict]) -> None:
    delete_query = "DELETE FROM match_referees WHERE match_id = %s;"
    insert_query = """
    INSERT INTO match_referees (
        match_id,
        referee_id,
        referee_name,
        role,
        source,
        created_at,
        updated_at
    )
    VALUES (%s, %s, %s, %s, %s, NOW(), NOW());
    """

    conn = get_connection()
    try:
        with conn.cursor() as cur:
            cur.execute(delete_query, (match_id,))

            for row in rows or []:
                referee_id = row.get("referee_id") or row.get("id")
                referee_name = (
                    row.get("referee_name")
                    or row.get("full_name")
                    or row.get("name")
                    or ""
                ).strip()
                role = (row.get("role") or "").strip()

                if not referee_id or not referee_name or not role:
                    continue

                cur.execute(
                    insert_query,
                    (
                        match_id,
                        referee_id,
                        referee_name,
                        role,
                        row.get("source", "admin"),
                    ),
                )

        conn.commit()
    except Exception:
        conn.rollback()
        raise
    finally:
        conn.close()