use chrono::Utc;
use gloo_net::{http::Request, Error};
use graphql_client::GraphQLQuery;
use serde::{de::DeserializeOwned, Serialize};

type DateTime = chrono::DateTime<Utc>;
// The paths are relative to the directory where your `Cargo.toml` is located.
// Both json and the GraphQL schema language are supported as sources for the schema
#[derive(GraphQLQuery)]
#[graphql(
    schema_path = "graphql/schema.json",
    query_path = "graphql/front_page.graphql",
    response_derives = "Debug"
)]
pub struct FrontPageQuery;

#[derive(GraphQLQuery)]
#[graphql(
    schema_path = "graphql/schema.json",
    query_path = "graphql/catchup.graphql",
    response_derives = "Debug"
)]
pub struct CatchupQuery;

#[derive(GraphQLQuery)]
#[graphql(
    schema_path = "graphql/schema.json",
    query_path = "graphql/show_thread.graphql",
    response_derives = "Debug"
)]
pub struct ShowThreadQuery;

#[derive(GraphQLQuery)]
#[graphql(
    schema_path = "graphql/schema.json",
    query_path = "graphql/mark_read.graphql",
    response_derives = "Debug"
)]
pub struct MarkReadMutation;

#[derive(GraphQLQuery)]
#[graphql(
    schema_path = "graphql/schema.json",
    query_path = "graphql/add_tag.graphql",
    response_derives = "Debug"
)]
pub struct AddTagMutation;

#[derive(GraphQLQuery)]
#[graphql(
    schema_path = "graphql/schema.json",
    query_path = "graphql/remove_tag.graphql",
    response_derives = "Debug"
)]
pub struct RemoveTagMutation;

#[derive(GraphQLQuery)]
#[graphql(
    schema_path = "graphql/schema.json",
    query_path = "graphql/snooze.graphql",
    response_derives = "Debug"
)]
pub struct SnoozeMutation;

#[derive(GraphQLQuery)]
#[graphql(
    schema_path = "graphql/schema.json",
    query_path = "graphql/refresh.graphql",
    response_derives = "Debug"
)]
pub struct RefreshMutation;

pub async fn send_graphql<Body, Resp>(body: Body) -> Result<graphql_client::Response<Resp>, Error>
where
    Body: Serialize,
    Resp: DeserializeOwned + 'static,
{
    use web_sys::RequestMode;

    Request::post("/api/graphql/")
        .mode(RequestMode::Cors)
        .json(&body)?
        .send()
        .await?
        .json()
        .await
}
