import contextlib
import typing
from base64 import b64decode, b64encode
from typing import TYPE_CHECKING, Any

import strawberry

from gqlauth.core.exceptions import WrongUsage
from gqlauth.core.utils import camelize


def serialize_excpected_error(errors):
    if isinstance(errors, dict):
        if errors.get("__all__", False):
            errors["non_field_errors"] = errors.pop("__all__")
        return camelize(errors)
    elif isinstance(errors, list):
        return {"nonFieldErrors": errors}
    raise WrongUsage("`errors` must be list or dict!")


if TYPE_CHECKING:
    ExpectedErrorType = dict[Any, Any] | list[dict[Any, Any]]
else:
    ExpectedErrorType = strawberry.scalar(
        typing.NewType("ExpectedError", dict),
        description="""
		Errors messages and codes mapped to
		fields or non fields errors.
		Example:
		{
			field_name: [
				{
					"message": "error message",
					"code": "error_code"
				}
			],
			other_field: [
				{
					"message": "error message",
					"code": "error_code"
				}
			],
			nonFieldErrors: [
				{
					"message": "error message",
					"code": "error_code"
				}
			]
		}
		""",
        serialize=lambda value: serialize_excpected_error(value),
        parse_value=lambda value: value,
    )

with contextlib.suppress(ImportError):
    from PIL.Image import Image

    image = strawberry.scalar(
        typing.NewType("image", Image),
        serialize=lambda v: b64encode(v).decode("ascii"),
        parse_value=lambda v: b64decode(v),
    )
