# 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


DEFAULT_CATEGORY_ID = "6569776b0bb9d14b23bd4de7"


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 employee by category and company")  # pyright: ignore[reportGeneralTypeIssues]
def step_query_employee(context) -> None:
    td = TicketTestData.from_behave_context(context)
    token = td.ensure_token()

    query = """
query employee($category_id: String!, $company_id: String!) {
  employee(filters: {category_id: $category_id, company_id: $company_id}) {
    results {
      id
      company { id name }
      user {
        id
        username
        data { first_name last_name }
      }
    }
  }
}
""".strip()
    category_id = td.category_id or DEFAULT_CATEGORY_ID
    variables = {"category_id": category_id, "company_id": td.company_id}

    with allure.step("GraphQL: employee(filters: category_id + company_id)"):
        resp = execute_graphql(query=query, variables=variables, company_id=td.company_id, access_token=token)
        _attach_json("employee response", resp)
        context.employee_response = resp


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


@then("each employee result has id and user fields")  # pyright: ignore[reportGeneralTypeIssues]
def step_each_result_has_fields(context) -> None:
    resp = getattr(context, "employee_response", None)
    assert isinstance(resp, dict), f"Нет employee_response или не dict: {resp}"
    results = resp.get("data", {}).get("employee", {}).get("results", [])
    assert isinstance(results, list), "employee.results не list"
    for i, item in enumerate(results):
        assert isinstance(item, dict), f"results[{i}] не объект: {type(item)}"
        assert item.get("id"), f"results[{i}].id пустой"
        company = item.get("company")
        assert isinstance(company, dict), f"results[{i}].company не объект: {company}"
        assert company.get("id"), f"results[{i}].company.id пустой"
        assert company.get("name"), f"results[{i}].company.name пустой"
        user = item.get("user")
        assert isinstance(user, dict), f"results[{i}].user не объект: {user}"
        assert user.get("id"), f"results[{i}].user.id пустой"
        assert user.get("username"), f"results[{i}].user.username пустой"
        data = user.get("data")
        assert isinstance(data, dict), f"results[{i}].user.data не объект: {data}"
        assert data.get("first_name"), f"results[{i}].user.data.first_name пустой"
        assert data.get("last_name"), f"results[{i}].user.data.last_name пустой"


@then("created employee username is in results")  # pyright: ignore[reportGeneralTypeIssues]
def step_created_username_in_results(context) -> None:
    td = TicketTestData.from_behave_context(context)
    username = td.username
    assert username, "Нет username в TicketTestData (user ещё не создан)."

    resp = getattr(context, "employee_response", None)
    assert isinstance(resp, dict), f"Нет employee_response или не dict: {resp}"
    results = resp.get("data", {}).get("employee", {}).get("results", [])
    assert isinstance(results, list), "employee.results не list"

    usernames: list[str] = []
    for item in results:
        if isinstance(item, dict):
            user = item.get("user")
            if isinstance(user, dict) and user.get("username"):
                usernames.append(user["username"])
    _attach_json("employee.usernames (extracted)", usernames)
    assert username in usernames, f"Не нашли созданного пользователя {username} в employee.results: {usernames}"

