package llm

import (
	"context"
	"fmt"

	"gitea.maximumdirect.net/eric/notarius/internal/core/artifacts"
	"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
)

type scheduledClient struct {
	client    contracts.StructuredLLMClient
	scheduler *Scheduler
}

func NewScheduledClient(client contracts.StructuredLLMClient, scheduler *Scheduler) contracts.StructuredLLMClient {
	return &scheduledClient{
		client:    client,
		scheduler: scheduler,
	}
}

func (c *scheduledClient) CompleteStructured(ctx context.Context, req contracts.StructuredCompletionRequest, out any) (contracts.StructuredCompletionResponse, error) {
	if c == nil {
		return contracts.StructuredCompletionResponse{}, fmt.Errorf("scheduled LLM client must not be nil")
	}
	if c.client == nil {
		return contracts.StructuredCompletionResponse{}, fmt.Errorf("scheduled LLM client inner client must not be nil")
	}
	if c.scheduler == nil {
		return contracts.StructuredCompletionResponse{}, fmt.Errorf("scheduled LLM client scheduler must not be nil")
	}

	var response contracts.StructuredCompletionResponse
	err := c.scheduler.Run(ctx, func(ctx context.Context) error {
		var callErr error
		response, callErr = c.client.CompleteStructured(ctx, req, out)
		return callErr
	})
	if err != nil {
		return contracts.StructuredCompletionResponse{}, err
	}
	return response, nil
}

func (c *scheduledClient) LLMProfileManifests() []artifacts.LLMProfileManifest {
	if c == nil || c.client == nil {
		return nil
	}
	provider, ok := c.client.(contracts.LLMProfileManifestProvider)
	if !ok {
		return nil
	}
	return provider.LLMProfileManifests()
}

func (c *scheduledClient) LLMCheckpointFingerprints() ([]CheckpointFingerprint, error) {
	if c == nil || c.client == nil {
		return nil, nil
	}
	provider, ok := c.client.(CheckpointFingerprintProvider)
	if !ok {
		return nil, nil
	}
	return provider.LLMCheckpointFingerprints()
}
