package dodo_tools

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"

	"sketch.dev/llm"
)

type GetProjectConfigTool struct {
	apiBaseAddress string
	projectId      string
}

func NewGetProjectConfigTool(apiBaseAddress string, projectId string) *llm.Tool {
	tool := &GetProjectConfigTool{
		apiBaseAddress: apiBaseAddress,
		projectId:      projectId,
	}
	return &llm.Tool{
		Name:        "dodo_get_project_config",
		Description: "A tool for getting current state of the infrastructure configuration of a dodo project",
		InputSchema: llm.EmptySchema(),
		Run:         tool.Run,
		EndsTurn:    true,
	}
}

type GetProjectConfigInput struct {
}

type GetProjectConfigOutput struct {
	Config string `json:"config"`
}

func (d *GetProjectConfigTool) Run(ctx context.Context, m json.RawMessage) ([]llm.Content, error) {
	resp, err := http.Get(fmt.Sprintf("%s/api/project/%s/config", d.apiBaseAddress, d.projectId))
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("failed to get project config: %s", string(body))
	}
	output := GetProjectConfigOutput{
		Config: string(body),
	}
	jsonOutput, err := json.Marshal(output)
	if err != nil {
		return nil, err
	}
	return llm.TextContent(string(jsonOutput)), nil
}

type ValidateConfigTool struct {
	apiBaseAddress string
}

const (
	validateConfigSchemaInputSchema = `
{
	"type": "object",
	"properties": {
		"config": {
			"type": "string",
			"description": "The dodo-app configuration to validate"
		}
	},
	"required": ["config"]
}
`
)

func NewValidateConfigTool(apiBaseAddress string) *llm.Tool {
	tool := &ValidateConfigTool{
		apiBaseAddress: apiBaseAddress,
	}
	return &llm.Tool{
		Name:        "dodo_validate_config",
		Description: "A tool for validating the dodo-app configuration",
		InputSchema: llm.MustSchema(validateConfigSchemaInputSchema),
		Run:         tool.Run,
		EndsTurn:    true,
	}
}

type ValidateConfigInput struct {
	Config string `json:"config"`
}

type ValidateConfigOutput struct {
	Success bool `json:"success"`
	Errors  any  `json:"errors,omitempty"`
}

func (d *ValidateConfigTool) Run(ctx context.Context, m json.RawMessage) ([]llm.Content, error) {
	var input ValidateConfigInput
	if err := json.Unmarshal(m, &input); err != nil {
		return nil, err
	}
	resp, err := http.Post(fmt.Sprintf("%s/api/validate-config", d.apiBaseAddress), "application/json", bytes.NewBuffer([]byte(input.Config)))
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("failed to validate config: %s", string(body))
	}
	var output ValidateConfigOutput
	if err := json.Unmarshal(body, &output); err != nil {
		return nil, err
	}
	jsonOutput, err := json.Marshal(output)
	if err != nil {
		return nil, err
	}
	return llm.TextContent(string(jsonOutput)), nil
}

type DeployProjectTool struct {
	apiBaseAddress string
	projectId      string
}

const (
	deployProjectSchemaInputSchema = `
{
	"type": "object",
	"properties": {
		"config": {
			"type": "string",
			"description": "Serialized dodo-app configuration to deploy"
		}
	}
}
`
)

func NewDeployProjectTool(apiBaseAddress string, projectId string) *llm.Tool {
	tool := &DeployProjectTool{
		apiBaseAddress: apiBaseAddress,
		projectId:      projectId,
	}

	return &llm.Tool{
		Name:        "dodo_deploy_project",
		Description: "A tool for deploying the dodo-app configuration",
		InputSchema: llm.MustSchema(deployProjectSchemaInputSchema),
		Run:         tool.Run,
		EndsTurn:    true,
	}
}

type DeployProjectInput struct {
	Config string `json:"config"`
}

type DeployProjectOutput struct {
	Success bool `json:"success"`
	Errors  any  `json:"errors,omitempty"`
}

type deployProjectReq struct {
	Config map[string]any `json:"config"`
}

func (d *DeployProjectTool) Run(ctx context.Context, m json.RawMessage) ([]llm.Content, error) {
	var input DeployProjectInput
	if err := json.Unmarshal(m, &input); err != nil {
		return nil, err
	}
	req := deployProjectReq{}
	if err := json.Unmarshal([]byte(input.Config), &req.Config); err != nil {
		return nil, err
	}
	jsonReq, err := json.Marshal(req)
	if err != nil {
		return nil, err
	}
	resp, err := http.Post(fmt.Sprintf("%s/api/project/%s/deploy", d.apiBaseAddress, d.projectId), "application/json", bytes.NewBuffer(jsonReq))
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("failed to deploy project: %s", string(body))
	}
	return llm.TextContent(string("Project deployed successfully")), nil
}

// Save

type SaveProjectTool struct {
	apiBaseAddress string
	projectId      string
}

const (
	saveProjectSchemaInputSchema = `
{
	"type": "object",
	"properties": {
		"config": {
			"type": "string",
			"description": "Serialized dodo-app configuration to save"
		}
	}
}
`
)

func NewSaveProjectTool(apiBaseAddress string, projectId string) *llm.Tool {
	tool := &SaveProjectTool{
		apiBaseAddress: apiBaseAddress,
		projectId:      projectId,
	}

	return &llm.Tool{
		Name:        "dodo_save_config",
		Description: "A tool for saving the dodo-app configuration",
		InputSchema: llm.MustSchema(saveProjectSchemaInputSchema),
		Run:         tool.Run,
		EndsTurn:    true,
	}
}

type SaveProjectInput struct {
	Config string `json:"config"`
}

type SaveProjectOutput struct {
	Success bool `json:"success"`
	Errors  any  `json:"errors,omitempty"`
}

type saveProjectReq struct {
	Type   string         `json:"type"`
	Config map[string]any `json:"config"`
}

func (d *SaveProjectTool) Run(ctx context.Context, m json.RawMessage) ([]llm.Content, error) {
	var input SaveProjectInput
	if err := json.Unmarshal(m, &input); err != nil {
		return nil, err
	}
	req := saveProjectReq{
		Type: "config",
	}
	if err := json.Unmarshal([]byte(input.Config), &req.Config); err != nil {
		return nil, err
	}
	jsonReq, err := json.Marshal(req)
	if err != nil {
		return nil, err
	}
	resp, err := http.Post(fmt.Sprintf("%s/api/project/%s/saved", d.apiBaseAddress, d.projectId), "application/json", bytes.NewBuffer(jsonReq))
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("failed to save project: %s", string(body))
	}
	return llm.TextContent(string("Project saved successfully")), nil
}

func NewDodoTools(apiBaseAddress string, projectId string) []*llm.Tool {
	return []*llm.Tool{
		NewGetProjectConfigTool(apiBaseAddress, projectId),
		NewValidateConfigTool(apiBaseAddress),
		NewDeployProjectTool(apiBaseAddress, projectId),
		NewSaveProjectTool(apiBaseAddress, projectId),
	}
}
