from database.connection import get_db


async def upsert_bot_user(
    max_user_id: int,
    max_chat_id: int | None,
    username: str | None,
    first_name: str | None,
) -> dict:
    db = get_db()
    await db.execute(
        """
        INSERT INTO bot_users (max_user_id, max_chat_id, username, first_name)
        VALUES (?, ?, ?, ?)
        ON CONFLICT(max_user_id) DO UPDATE SET
            max_chat_id = COALESCE(excluded.max_chat_id, max_chat_id),
            username    = COALESCE(excluded.username, username),
            first_name  = COALESCE(excluded.first_name, first_name),
            updated_at  = datetime('now')
        """,
        (max_user_id, max_chat_id, username, first_name),
    )
    await db.commit()
    return await get_bot_user_by_max_id(max_user_id)


async def get_bot_user_by_max_id(max_user_id: int) -> dict | None:
    db = get_db()
    async with db.execute(
        "SELECT * FROM bot_users WHERE max_user_id = ?", (max_user_id,)
    ) as cur:
        row = await cur.fetchone()
    return dict(row) if row else None


async def get_bot_user_by_id(user_id: int) -> dict | None:
    db = get_db()
    async with db.execute(
        "SELECT * FROM bot_users WHERE id = ?", (user_id,)
    ) as cur:
        row = await cur.fetchone()
    return dict(row) if row else None


async def authorize_bot_user(
    max_user_id: int, phone: str, org_id: int, first_name: str | None = None
) -> None:
    db = get_db()
    await db.execute(
        """
        UPDATE bot_users
        SET phone = ?, org_id = ?, is_authorized = 1, is_blocked = 0,
            first_name = COALESCE(?, first_name), updated_at = datetime('now')
        WHERE max_user_id = ?
        """,
        (phone, org_id, first_name, max_user_id),
    )
    await db.commit()


async def block_bot_user(max_user_id: int, phone: str | None = None) -> None:
    db = get_db()
    await db.execute(
        """
        UPDATE bot_users
        SET is_blocked = 1, phone = COALESCE(?, phone), updated_at = datetime('now')
        WHERE max_user_id = ?
        """,
        (phone, max_user_id),
    )
    await db.commit()


async def reset_bot_user(user_id: int) -> None:
    """Сбрасывает авторизацию — пользователь должен заново пройти auth."""
    db = get_db()
    await db.execute(
        """
        UPDATE bot_users
        SET is_authorized = 0, is_blocked = 0, org_id = NULL, phone = NULL,
            updated_at = datetime('now')
        WHERE id = ?
        """,
        (user_id,),
    )
    await db.commit()


async def delete_bot_user(user_id: int) -> None:
    """Полное удаление пользователя бота (каскад удаляет заявки)."""
    db = get_db()
    await db.execute("DELETE FROM bot_users WHERE id = ?", (user_id,))
    await db.commit()


async def unblock_bot_user(user_id: int, org_id: int) -> None:
    db = get_db()
    await db.execute(
        """
        UPDATE bot_users
        SET is_blocked = 0, is_authorized = 1, org_id = ?, updated_at = datetime('now')
        WHERE id = ?
        """,
        (org_id, user_id),
    )
    await db.commit()


async def get_all_bot_users(
    is_authorized: int | None = None,
    is_blocked: int | None = None,
    org_id: int | None = None,
) -> list[dict]:
    db = get_db()
    conditions = []
    params: list = []
    if is_authorized is not None:
        conditions.append("bu.is_authorized = ?")
        params.append(is_authorized)
    if is_blocked is not None:
        conditions.append("bu.is_blocked = ?")
        params.append(is_blocked)
    if org_id is not None:
        conditions.append("bu.org_id = ?")
        params.append(org_id)

    where = ("WHERE " + " AND ".join(conditions)) if conditions else ""
    query = f"""
        SELECT bu.*, o.name as org_name
        FROM bot_users bu
        LEFT JOIN organizations o ON o.id = bu.org_id
        {where}
        ORDER BY bu.created_at DESC
    """
    async with db.execute(query, params) as cur:
        rows = await cur.fetchall()
    return [dict(r) for r in rows]
