package loop

import (
	"context"
	"encoding/json"
	"fmt"
	"strings"
	"time"

	"dodo.cloud/neo/tools"

	"github.com/anthropics/anthropic-sdk-go"
)

type AnthropicAgent struct {
	pr     PromptReader
	reg    tools.Registry
	client anthropic.Client
}

func (a *AnthropicAgent) Run(todo *ToDo) error {
	sp := fmt.Sprintf(systemPrompt, ToDoJSONSchema())
	var toolParams []anthropic.ToolParam
	for _, t := range a.reg.All() {
		schema, err := GetToolSchema(t.InputSchema())
		if err != nil {
			return err
		}
		toolParams = append(toolParams, anthropic.ToolParam{
			Name:        t.Name(),
			Description: anthropic.String(t.Description()),
			InputSchema: schema,
		})
	}
	tools := make([]anthropic.ToolUnionParam, len(toolParams))
	for i, toolParam := range toolParams {
		tools[i] = anthropic.ToolUnionParam{OfTool: &toolParam}
	}
	for {
		todo.Lock()
		items := findActionableItems(todo, "assistant")
		if len(items) == 0 {
			fmt.Println("## AGENT NO ITEMS")
			todo.Unlock()
			time.Sleep(30 * time.Second)
			continue
		}
		var itemIds []string
		var messages []anthropic.MessageParam
		for _, i := range items {
			itemIds = append(itemIds, i.ID)
		}
		fmt.Println(todo.String())
		fmt.Printf("-- AGENT START WORKING %s\n", strings.Join(itemIds, ", "))
		b, err := json.MarshalIndent(todo, "", "\t")
		if err != nil {
			todo.Unlock()
			break
		}
		messages = append(messages, anthropic.NewUserMessage(anthropic.NewTextBlock(string(b))))
		messages = append(messages, anthropic.NewUserMessage(anthropic.NewTextBlock(
			fmt.Sprintf("Work on TODO item: %s", strings.Join(itemIds, ", ")))))
		for {
			resp, err := a.client.Messages.New(context.TODO(), anthropic.MessageNewParams{
				MaxTokens: 10240,
				System: []anthropic.TextBlockParam{
					{Text: sp},
				},
				Messages: messages,
				Model:    anthropic.ModelClaudeOpus4_6,
				Tools:    tools,
			})
			if err != nil {
				todo.Unlock()
				return err
			}
			fmt.Printf("--- STOP_REASON: %s\n", resp.StopReason)
			messages = append(messages, resp.ToParam())

			var toolResults []anthropic.ContentBlockParamUnion
			for _, block := range resp.Content {
				switch v := block.AsAny().(type) {
				case anthropic.TextBlock:
					fmt.Printf("AI: %s\n", v.Text)
				case anthropic.ToolUseBlock:
					args := v.JSON.Input.Raw()
					if v.Name == "bash_command" {
						fmt.Printf("!!!!! %s: ", args)
						p, err := a.pr.Read()
						if err != nil {
							todo.Unlock()
							return err
						}
						if p != "OK" {
							toolResults = append(toolResults, anthropic.NewToolResultBlock(v.ID, p, true))
							continue
						}
					}
					t := a.reg.Get(v.Name)
					if t == nil {
						toolResults = append(toolResults, anthropic.NewToolResultBlock(v.ID, fmt.Sprintf("unknown tool %q", v.Name), true))
						continue
					}

					fmt.Printf("CALLING TOOL: %s %s\n", v.Name, args)
					out, err := t.Call(string(args))
					if err != nil {
						fmt.Printf("ERR: %s\n", err.Error())
						toolResults = append(toolResults, anthropic.NewToolResultBlock(v.ID, err.Error(), true))
					} else {
						toolResults = append(toolResults, anthropic.NewToolResultBlock(v.ID, out, false))
					}
				}
			}
			if len(toolResults) == 0 {
				break
			}
			messages = append(messages, anthropic.NewUserMessage(toolResults...))
		}
		for _, i := range items {
			i.AssignedTo = "user"
		}
		todo.Unlock()
	}
	return nil
}
