from db import get_connection
from repositories.team_repository import get_team_id_by_external_id


def normalize_birth_date_for_input(value) -> str:
    if not value:
        return ""

    text = str(value).strip()

    if not text:
        return ""

    # Уже нормальный формат для input[type=date]
    if len(text) == 10 and text[4] == "-" and text[7] == "-":
        return text

    # Формат ДД.ММ.ГГГГ -> YYYY-MM-DD
    if len(text) == 10 and text[2] == "." and text[5] == ".":
        dd, mm, yyyy = text.split(".")
        return f"{yyyy}-{mm}-{dd}"

    return ""


def upsert_player(
    external_id: str,
    team_external_id: str,
    player: str,
    lastname: str = "",
    name: str = "",
    number: str = "",
    pos: str = "",
    amplua: str = "",
    born: str = "",
    games: int = 0,
    goals: int = 0,
    penaltys: int = 0,
    assists: int = 0,
    yellows: int = 0,
    reds: int = 0,
    is_active: bool = True,
) -> None:
    team_id = get_team_id_by_external_id(str(team_external_id).strip())
    if team_id is None:
        raise ValueError(f"Team not found by external_id: {team_external_id}")

    query = """
    INSERT INTO players (
        external_id,
        team_id,
        full_name,
        first_name,
        last_name,
        number,
        position,
        is_active,
        pos,
        amplua,
        born,
        games,
        goals,
        penaltys,
        assists,
        yellows,
        reds,
        created_at,
        updated_at
    )
    VALUES (
        %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
        NOW(), NOW()
    )
    ON CONFLICT (external_id)
    DO UPDATE SET
        team_id = EXCLUDED.team_id,
        full_name = EXCLUDED.full_name,
        first_name = EXCLUDED.first_name,
        last_name = EXCLUDED.last_name,
        number = EXCLUDED.number,
        position = EXCLUDED.position,
        is_active = EXCLUDED.is_active,
        pos = EXCLUDED.pos,
        amplua = EXCLUDED.amplua,
        born = EXCLUDED.born,
        games = EXCLUDED.games,
        goals = EXCLUDED.goals,
        penaltys = EXCLUDED.penaltys,
        assists = EXCLUDED.assists,
        yellows = EXCLUDED.yellows,
        reds = EXCLUDED.reds,
        updated_at = NOW();
    """

    conn = get_connection()
    try:
        with conn.cursor() as cur:
            cur.execute(
                query,
                (
                    str(external_id).strip(),
                    team_id,
                    player.strip(),
                    name.strip(),
                    lastname.strip(),
                    str(number).strip(),
                    amplua.strip(),
                    is_active,
                    pos.strip(),
                    amplua.strip(),
                    born.strip(),
                    games,
                    goals,
                    penaltys,
                    assists,
                    yellows,
                    reds,
                ),
            )
        conn.commit()
    except Exception:
        conn.rollback()
        raise
    finally:
        conn.close()


def get_match_by_external_id(external_id: str):
    query = """
    SELECT id, external_id, home_team_id, away_team_id
    FROM matches
    WHERE external_id = %s
    LIMIT 1;
    """

    conn = get_connection()
    try:
        with conn.cursor() as cur:
            cur.execute(query, (str(external_id).strip(),))
            return cur.fetchone()
    finally:
        conn.close()


def mark_match_parsed(external_id: str) -> None:
    query = """
    UPDATE matches
    SET parsed = TRUE,
        parse_error = NULL,
        updated_at = NOW()
    WHERE external_id = %s;
    """

    conn = get_connection()
    try:
        with conn.cursor() as cur:
            cur.execute(query, (str(external_id).strip(),))
        conn.commit()
    except Exception:
        conn.rollback()
        raise
    finally:
        conn.close()


def mark_match_parse_error(external_id: str, error_text: str) -> None:
    query = """
    UPDATE matches
    SET parsed = FALSE,
        parse_error = %s,
        updated_at = NOW()
    WHERE external_id = %s;
    """

    conn = get_connection()
    try:
        with conn.cursor() as cur:
            cur.execute(query, (str(error_text)[:2000], str(external_id).strip()))
        conn.commit()
    except Exception:
        conn.rollback()
        raise
    finally:
        conn.close()


def get_player_id_by_name_and_team(full_name: str, team_id: int) -> int | None:
    query = """
    SELECT id
    FROM players
    WHERE team_id = %s
      AND LOWER(full_name) = LOWER(%s)
    LIMIT 1;
    """

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


def get_player_id_by_external_id(external_id: str) -> int | None:
    query = """
    SELECT id,
    position
    FROM players
    WHERE external_id = %s
    LIMIT 1;
    """

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


from db import get_connection


def search_players_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
                        p.id,
                        p.full_name,
                        p.first_name,
                        p.last_name,
                        p.external_id,
                        p.position
                    FROM players p
                    WHERE
                        p.full_name ILIKE %s
                        OR p.first_name ILIKE %s
                        OR p.last_name ILIKE %s
                        OR COALESCE(p.external_id, '') ILIKE %s
                    ORDER BY p.full_name ASC, p.id ASC
                    LIMIT 200
                    """,
                    (pattern, pattern, pattern, pattern),
                )
            else:
                cur.execute(
                    """
                    SELECT
                        p.id,
                        p.full_name,
                        p.first_name,
                        p.last_name,
                        p.external_id,
                        p.position
                    FROM players p
                    ORDER BY p.id DESC
                    LIMIT 200
                    """
                )

            rows = cur.fetchall()

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


def get_player_by_id(player_id: int) -> dict | None:
    conn = get_connection()
    try:
        with conn.cursor() as cur:
            cur.execute(
                """
                SELECT
                    p.id,
                    p.full_name,
                    p.first_name,
                    p.last_name,
                    p.external_id,
                    p.position,
                    p.born,
                    p.photo,
                    p.video
                FROM players p
                WHERE p.id = %s
                LIMIT 1
                """,
                (player_id,),
            )
            row = cur.fetchone()

        if not row:
            return None

        return {
            "id": row[0],
            "full_name": row[1] or "",
            "first_name": row[2] or "",
            "last_name": row[3] or "",
            "external_id": row[4] or "",
            "position": row[5] or "",
            "birth_date": normalize_birth_date_for_input(row[6]),
            "photo": row[7] or "",
            "video": row[8] or "",
        }
    finally:
        conn.close()


def update_player_admin(
    player_id: int,
    full_name: str = "",
    first_name: str = "",
    last_name: str = "",
    external_id: str = "",
    position: str = "",
    birth_date: str = "",
    photo: str = "",
    video: str = "",
) -> None:
    conn = get_connection()
    try:
        with conn.cursor() as cur:
            cur.execute(
                """
                UPDATE players
                SET
                    full_name = %s,
                    first_name = %s,
                    last_name = %s,
                    external_id = NULLIF(%s, ''),
                    position = %s,
                    born = NULLIF(%s, '')::date,
                    photo = NULLIF(%s, ''),
                    video = NULLIF(%s, '')
                WHERE id = %s
                """,
                (
                    full_name.strip(),
                    first_name.strip(),
                    last_name.strip(),
                    external_id.strip(),
                    position.strip(),
                    birth_date.strip(),
                    photo.strip(),
                    video.strip(),
                    player_id,
                ),
            )
        conn.commit()
    except Exception:
        conn.rollback()
        raise
    finally:
        conn.close()
