# pyright: reportCallIssue=false

from __future__ import annotations

import json
from typing import Any

import allure  # pyright: ignore[reportMissingImports]
from allure_commons.types import AttachmentType  # pyright: ignore[reportMissingImports]
from behave import then, when

from Ticket.testdata.ticket_test_data import TicketTestData
from worklib.graphql_client import execute_graphql


def _attach_json(name: str, payload: Any) -> None:
    allure.attach(
        json.dumps(payload, ensure_ascii=False, indent=2),
        name=name,
        attachment_type=AttachmentType.JSON,
    )


@when("query ticket categories by created place id")  # pyright: ignore[reportGeneralTypeIssues]
def step_query_ticket_categories_by_place(context) -> None:
    td = TicketTestData.from_behave_context(context)
    token = td.ensure_token()
    place_id = td.ensure_place()

    query = """
query categoryinfo($place_id: String!) {
  ticket_category(filters: {place_id: $place_id}) {
    results {
      id
      title
      place_ids
      company_id
    }
  }
}
""".strip()
    variables = {"place_id": place_id}

    with allure.step("GraphQL: ticket_category(filters: place_id)"):
        resp = execute_graphql(query=query, variables=variables, company_id=td.company_id, access_token=token)
        _attach_json("ticket_category response", resp)
        context.ticket_category_response = resp


@then("ticket_category results are not empty")  # pyright: ignore[reportGeneralTypeIssues]
def step_ticket_category_results_not_empty(context) -> None:
    resp = getattr(context, "ticket_category_response", None)
    assert isinstance(resp, dict), f"Нет ticket_category_response или не dict: {resp}"
    results = resp.get("data", {}).get("ticket_category", {}).get("results")
    _attach_json("ticket_category.results (extracted)", results)
    assert isinstance(results, list), f"ticket_category.results должен быть list. Ответ: {resp}"
    assert len(results) > 0, "ticket_category.results пустой — тест должен падать"


@then("created ticket category is present in results")  # pyright: ignore[reportGeneralTypeIssues]
def step_created_ticket_category_present(context) -> None:
    td = TicketTestData.from_behave_context(context)
    created_category_id = td.category_id
    created_place_id = td.place_id
    assert created_category_id, "Нет category_id в TicketTestData (category ещё не создана)."
    assert created_place_id, "Нет place_id в TicketTestData (place ещё не создан)."

    resp = getattr(context, "ticket_category_response", None)
    assert isinstance(resp, dict), f"Нет ticket_category_response или не dict: {resp}"
    results = resp.get("data", {}).get("ticket_category", {}).get("results", [])
    assert isinstance(results, list), "ticket_category.results не list"
    assert len(results) > 0, "ticket_category.results пустой — тест должен падать"

    match = None
    for item in results:
        if isinstance(item, dict) and item.get("id") == created_category_id:
            match = item
            break
    _attach_json("ticket_category.match (found)", match)
    assert match is not None, f"Не нашли созданную категорию id={created_category_id} в results"
    assert match.get("company_id") == td.company_id, f"company_id не совпал: {match.get('company_id')} != {td.company_id}"
    place_ids = match.get("place_ids")
    assert isinstance(place_ids, list), f"place_ids должен быть list, получено: {place_ids!r}"
    assert created_place_id in place_ids, f"В place_ids нет созданного place_id={created_place_id}. place_ids={place_ids}"

