# pyright: reportCallIssue=false

from __future__ import annotations

from behave import when

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


DEFAULT_TICKETINFO_PLACE_ID = "682733c16773cfa73dc8d0a7"


@when("prepare ticket and categories for category change test")  # pyright: ignore[reportGeneralTypeIssues]
def step_prepare_ticket_and_categories(context) -> None:
    """
    Подготовка тестовых данных:
    - place
    - 3 категории (old / in_group / out_group)
    - user + employee
    - category group по категории in_group + connect employee
    - ticket с категорией old (createTicket может падать по правам — это ок, тест должен упасть)
    """
    td = TicketTestData.from_behave_context(context)

    token = td.ensure_token()

    query = """
query ticketinfo($place_id: String!) {
  ticket(pagination:{skip:0,limit:25} ,filter:{place_id:$place_id}){
    results {
      id
      category { id title }
      assignee { id user { id username } }
    }
  }
}
""".strip()
    # Сначала пытаемся работать с существующей заявкой на заранее известном place_id.
    # Если на стенде нет заявок — пытаемся создать свою (если createTicket разрешён).
    td.place_id = DEFAULT_TICKETINFO_PLACE_ID
    resp = execute_graphql(query=query, variables={"place_id": td.place_id}, company_id=td.company_id, access_token=token)
    results = resp.get("data", {}).get("ticket", {}).get("results", [])

    if isinstance(results, list) and results:
        ticket0 = results[0]
        assert isinstance(ticket0, dict) and ticket0.get("id"), f"Некорректный ticket: {ticket0!r}"
        old_category = ticket0.get("category")
        assert isinstance(old_category, dict) and old_category.get("id") and old_category.get("title"), f"У ticket нет category: {ticket0!r}"

        context.ticket_id = ticket0["id"]
        td.ticket_id = ticket0["id"]
        old_category_id = old_category["id"]
        old_category_title = old_category["title"]
        place_id_for_new_categories = td.place_id
    else:
        # fallback: создаём тестовую заявку сами
        td.place_id = None
        td.ensure_place()
        place_id_for_new_categories = td.place_id
        assert place_id_for_new_categories
        old_category_id = td.create_ticket_category(title="cat-old", place_id=place_id_for_new_categories)
        old_category_title = "cat-old"
        try:
            td.create_ticket_with_category(category_id=old_category_id, place_id=place_id_for_new_categories)
        except AssertionError as e:
            raise AssertionError(
                "Нет доступных tickets для проверки (по умолчанию берём place_id "
                f"{DEFAULT_TICKETINFO_PLACE_ID}) и createTicket запрещён на стенде. "
                "Укажите place_id с существующими заявками (поменяйте DEFAULT_TICKETINFO_PLACE_ID в шаге) "
                "или дайте права на createTicket. "
                f"Детали: {e}"
            )
        context.ticket_id = td.ticket_id

    ids = {
        "old": old_category_id,
        "in_group": td.create_ticket_category(title=f"cat-in-group-{td.ticket_id}", place_id=place_id_for_new_categories),
        "out_group": td.create_ticket_category(title=f"cat-out-group-{td.ticket_id}", place_id=place_id_for_new_categories),
    }
    titles = {"old": old_category_title, "in_group": f"cat-in-group-{td.ticket_id}", "out_group": f"cat-out-group-{td.ticket_id}"}
    context.ticket_category_change_ids = ids
    context.ticket_category_change_titles = titles

    # создаём нового employee (user создастся внутри) — он должен оставаться привязанным в группе №1
    td.create_employee()
    assert td.account_id and td.employee_id, "Не создался employee/user для теста смены категории"
    context.ticket_employee_id = td.employee_id
    context.ticket_account_id = td.account_id
    context.ticket_username = td.username

    fixed_member = {"user_id": td.fixed_user_id, "employee_id": td.fixed_employee_id}
    new_member = {"user_id": td.account_id, "employee_id": td.employee_id}

    # Группа №1: две категории (old + in_group), в ней новый employee + фиксированный employee
    # => при смене old -> in_group новый employee должен остаться.
    td.create_category_group_for_categories(
        [ids["old"], ids["in_group"]],
        members=[new_member, fixed_member],
        cache=False,
    )

    # Группа №2: категория out_group, в ней только фиксированный employee (обязательное требование)
    # => при смене на out_group новый employee должен "отпасть".
    td.create_category_group_for_categories(
        [ids["out_group"]],
        members=[fixed_member],
        cache=False,
    )

    # cleanup: вернуть категорию обратно
    cleanup_fns = getattr(context, "_cleanup_fns", None)
    if isinstance(cleanup_fns, list):
        def _restore_category() -> None:
            mutation = """
mutation updatecategory($ticket_id: String!, $category_id: String!) {
  changeTicketCategory(dto: {ticket_id: $ticket_id, category_id: $category_id})
}
""".strip()
            execute_graphql(
                query=mutation,
                variables={"ticket_id": td.ticket_id, "category_id": ids["old"]},
                company_id=td.company_id,
                access_token=token,
            )
        cleanup_fns.append(_restore_category)

