package service_internal

import (
	"context"

	"git.itzana.me/strafesnet/maps-service/pkg/datastore"
	"git.itzana.me/strafesnet/maps-service/pkg/internal"
	"git.itzana.me/strafesnet/maps-service/pkg/model"
)

// CreateScript implements createScript operation.
//
// Create a new script.
//
// POST /scripts
func (svc *Service) CreateScript(ctx context.Context, req *api.ScriptCreate) (*api.ID, error) {
	script, err := svc.DB.Scripts().Create(ctx, model.Script{
		ID:           0,
		Name:         req.Name,
		Hash:         int64(model.HashSource(req.Source)),
		Source:       req.Source,
		ResourceType: model.ResourceType(req.ResourceType),
		ResourceID:   req.ResourceID.Or(0),
	})
	if err != nil {
		return nil, err
	}

	return &api.ID{
		ID: script.ID,
	}, nil
}

// ListScripts implements listScripts operation.
//
// Get list of scripts.
//
// GET /scripts
func (svc *Service) ListScripts(ctx context.Context, params api.ListScriptsParams) ([]api.Script, error) {
	filter := datastore.Optional()

	if params.Hash.IsSet(){
		hash, err := model.HashParse(params.Hash.Value)
		if err != nil {
			return nil, err
		}
		filter.AddNotNil("hash", int64(hash)) // No type safety!
	}
	if params.Name.IsSet(){
		filter.AddNotNil("name", params.Name.Value)
	}
	if params.Source.IsSet(){
		filter.AddNotNil("source", params.Source.Value)
	}
	if params.ResourceType.IsSet(){
		filter.AddNotNil("resource_type", params.ResourceType.Value)
	}
	if params.ResourceID.IsSet(){
		filter.AddNotNil("resource_id", params.ResourceID.Value)
	}

	items, err := svc.DB.Scripts().List(ctx, filter, model.Page{
		Number: params.Page,
		Size:   params.Limit,
	})
	if err != nil {
		return nil, err
	}

	var resp []api.Script
	for _, item := range items {
		resp = append(resp, api.Script{
			ID:           item.ID,
			Hash:         model.HashFormat(uint64(item.Hash)),
			Source:       item.Source,
			ResourceType: int32(item.ResourceType),
			ResourceID:   item.ResourceID,
		})
	}

	return resp, nil
}

// GetScript implements getScript operation.
//
// Get the specified script by ID.
//
// GET /scripts/{ScriptID}
func (svc *Service) GetScript(ctx context.Context, params api.GetScriptParams) (*api.Script, error) {
	script, err := svc.DB.Scripts().Get(ctx, params.ScriptID)
	if err != nil {
		return nil, err
	}

	return &api.Script{
		ID:           script.ID,
		Name:         script.Name,
		Hash:         model.HashFormat(uint64(script.Hash)),
		Source:       script.Source,
		ResourceType: int32(script.ResourceType),
		ResourceID:   script.ResourceID,
	}, nil
}