package graphql

import (
	"context"
	"errors"
	"fmt"
	"git.front.kjuulh.io/kjuulh/acc-server/generated/graphql"
)

// THIS CODE IS A STARTING POINT ONLY. IT WILL NOT BE UPDATED WITH SCHEMA CHANGES.

type Resolver struct {
	humans map[string]graphql.Human
}

type queryResolver struct {
	*Resolver
}

func (r *queryResolver) Character(ctx context.Context, id string) (graphql.Character, error) {
	//TODO implement me
	panic("implement me")
}

func (r *Resolver) Query() graphql.QueryResolver {
	return &queryResolver{r}
}

func (r *Resolver) Human() graphql.HumanResolver {
	return &humanResolver{r}
}

type humanResolver struct {
	*Resolver
}

func (h humanResolver) Friends(ctx context.Context, obj *graphql.Human) ([]*graphql.Human, error) {
	if obj.ID == "some-id" {
		return obj.Friends, nil
	}

	return []*graphql.Human{}, nil
}

func (h humanResolver) Height(ctx context.Context, obj *graphql.Human, unit *graphql.LengthUnit) (*graphql.Unit, error) {
	switch *unit {
	case graphql.LengthUnitMeter:
		return obj.Height, nil
	case graphql.LengthUnitFeet:
		return obj.Height, nil
	default:
		panic("Not implemented yet")
	}
}

func (r *queryResolver) Human(ctx context.Context, id string) (*graphql.Human, error) {
	fmt.Printf("%v+", r.humans)
	if human, ok := r.humans[id]; ok {
		return &human, nil
	}
	return nil, errors.New("human was not found given id")
}

func NewResolver() graphql.Config {
	r := Resolver{}

	r.humans = map[string]graphql.Human{
		"kasper": {
			ID:     "some-id",
			Name:   "kasper",
			Height: &graphql.Unit{Value: 0},
			Friends: []*graphql.Human{
				{
					ID:     "some-other-id",
					Name:   "Emma",
					Height: &graphql.Unit{Value: 5},
					Friends: []*graphql.Human{
						{
							ID: "blabla",
						},
					},
				},
			},
		},
	}

	return graphql.Config{Resolvers: &r}
}
