from typing import Dict, Union

from graphql import (
    GraphQLBoolean,
    GraphQLFloat,
    GraphQLInputField,
    GraphQLInt,
    GraphQLList,
    GraphQLNonNull,
    GraphQLScalarType,
    GraphQLString,
)
from sqlalchemy import ARRAY, Boolean, Float, Integer
from sqlalchemy.dialects.postgresql import ARRAY as PGARRAY
from sqlalchemy.types import TypeEngine


def get_graphql_type_from_column(column_type: TypeEngine) -> Union[GraphQLScalarType, GraphQLList]:
    if isinstance(column_type, Integer):
        return GraphQLInt

    if isinstance(column_type, Float):
        return GraphQLFloat

    if isinstance(column_type, Boolean):
        return GraphQLBoolean

    if isinstance(column_type, (ARRAY, PGARRAY)):
        return GraphQLList(get_graphql_type_from_column(column_type.item_type))

    return GraphQLString


def get_base_comparison_fields(graphql_type: Union[GraphQLScalarType, GraphQLList]) -> Dict[str, GraphQLInputField]:
    return {
        "_eq": GraphQLInputField(graphql_type),
        "_neq": GraphQLInputField(graphql_type),
        "_in": GraphQLInputField(GraphQLList(GraphQLNonNull(graphql_type))),
        "_nin": GraphQLInputField(GraphQLList(GraphQLNonNull(graphql_type))),
        "_lt": GraphQLInputField(graphql_type),
        "_gt": GraphQLInputField(graphql_type),
        "_gte": GraphQLInputField(graphql_type),
        "_lte": GraphQLInputField(graphql_type),
        "_is_null": GraphQLInputField(GraphQLBoolean),
    }


def get_string_comparison_fields() -> Dict[str, GraphQLInputField]:
    return {"_like": GraphQLInputField(GraphQLString), "_nlike": GraphQLInputField(GraphQLString)}

[(36, 'graphql.GraphQLInputField', 'GraphQLInputField', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), (37, 'graphql.GraphQLInputField', 'GraphQLInputField', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), (40, 'graphql.GraphQLInputField', 'GraphQLInputField', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), (41, 'graphql.GraphQLInputField', 'GraphQLInputField', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), (42, 'graphql.GraphQLInputField', 'GraphQLInputField', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), (43, 'graphql.GraphQLInputField', 'GraphQLInputField', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), (44, 'graphql.GraphQLInputField', 'GraphQLInputField', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), (49, 'graphql.GraphQLInputField', 'GraphQLInputField', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), (49, 'graphql.GraphQLInputField', 'GraphQLInputField', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), (38, 'graphql.GraphQLNonNull', 'GraphQLNonNull', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n'), (39, 'graphql.GraphQLNonNull', 'GraphQLNonNull', False, 'from graphql import GraphQLBoolean, GraphQLFloat, GraphQLInputField, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLScalarType, GraphQLString\n')]