package agent

import (
	"fmt"

	"webby-builder/internal/models"
)

// WebFetchHttpTool returns the webFetchHttp tool definition. The cross-tier
// hint ("USE THIS FIRST" + fallback-to-browser line) is only included when the
// browser tier is also registered (fetchMode == "both"). In "http"-only mode
// there is no other tier to defer to, so the hint is omitted.
func WebFetchHttpTool(fetchMode string) models.ToolDefinition {
	description := `Fetch a public URL via plain HTTP and return its content as markdown plus structured metadata.

It is fast, free, and works for most static sites, blogs, docs, and small e-commerce.

DO NOT use for private/internal URLs (the request will be rejected with ssrf_blocked).

Returns: { url, status, title, markdown, metadata: { description, og, twitter, canonical, links, images } } on success; { error, error_code, retryable, fallback_hint } on failure.`

	if fetchMode == "both" || fetchMode == "smart" {
		description = `Fetch a public URL via plain HTTP and return its content as markdown plus structured metadata.

USE THIS FIRST when the user references an external website. It is fast, free, and works for most static sites, blogs, docs, and small e-commerce.

If the response returns error_code "blocked_by_site" or the content is suspiciously short/empty, then use webBrowserOpen as the next fallback. If webBrowserOpen also returns "blocked_by_site", escalate to webFetchFirecrawl (most expensive tier).

DO NOT use for private/internal URLs (the request will be rejected with ssrf_blocked).

Returns: { url, status, title, markdown, metadata: { description, og, twitter, canonical, links, images } } on success; { error, error_code, retryable, fallback_hint } on failure.`
	}

	return models.ToolDefinition{
		Name:        "webFetchHttp",
		Description: description,
		Parameters: map[string]any{
			"type": "object",
			"properties": map[string]any{
				"url": map[string]any{
					"type":        "string",
					"description": "The fully-qualified http:// or https:// URL to fetch.",
				},
			},
			"required": []string{"url"},
		},
	}
}

// WebBrowserOpenTool returns the webBrowserOpen tool definition. The
// "Use ONLY when webFetchHttp returned blocked_by_site..." hint is only
// included when the HTTP tier is also registered (fetchMode == "both"). In
// "browser"-only mode there is no HTTP tier to defer to, so the hint is
// omitted.
func WebBrowserOpenTool(fetchMode string) models.ToolDefinition {
	description := `Open a new headless browser session and navigate to a URL.

Returns a session_id you must pass to subsequent webBrowser* calls. ALWAYS close the session with webBrowserClose when done — sessions are limited to 1 per build and 50 actions total.

Returns: { session_id, page_state: { url, title, markdown_excerpt, interactive_elements_summary } }.`

	if fetchMode == "both" || fetchMode == "smart" {
		description = `Open a new headless browser session and navigate to a URL. Use ONLY when webFetchHttp returned blocked_by_site or the site requires JavaScript to render.

If webBrowserOpen also returns blocked_by_site or browser_bot_detected, escalate to webFetchFirecrawl as the last resort.

Returns a session_id you must pass to subsequent webBrowser* calls. ALWAYS close the session with webBrowserClose when done — sessions are limited to 1 per build and 50 actions total.

Returns: { session_id, page_state: { url, title, markdown_excerpt, interactive_elements_summary } }.`
	}

	return models.ToolDefinition{
		Name:        "webBrowserOpen",
		Description: description,
		Parameters: map[string]any{
			"type": "object",
			"properties": map[string]any{
				"url": map[string]any{"type": "string", "description": "Initial URL to load."},
			},
			"required": []string{"url"},
		},
	}
}

func WebBrowserClickTool() models.ToolDefinition {
	return models.ToolDefinition{
		Name:        "webBrowserClick",
		Description: `Click an element matching the CSS selector in the current browser session. Returns updated page_state.`,
		Parameters: map[string]any{
			"type": "object",
			"properties": map[string]any{
				"session_id": map[string]any{"type": "string"},
				"selector":   map[string]any{"type": "string", "description": "CSS selector for the element to click."},
			},
			"required": []string{"session_id", "selector"},
		},
	}
}

func WebBrowserTypeTool() models.ToolDefinition {
	return models.ToolDefinition{
		Name:        "webBrowserType",
		Description: `Type text into an input matching the CSS selector. Returns updated page_state.`,
		Parameters: map[string]any{
			"type": "object",
			"properties": map[string]any{
				"session_id": map[string]any{"type": "string"},
				"selector":   map[string]any{"type": "string"},
				"text":       map[string]any{"type": "string"},
			},
			"required": []string{"session_id", "selector", "text"},
		},
	}
}

func WebBrowserScrollTool() models.ToolDefinition {
	return models.ToolDefinition{
		Name:        "webBrowserScroll",
		Description: `Scroll the page up or down by a pixel amount. Useful for triggering lazy-loaded content. Returns updated page_state.`,
		Parameters: map[string]any{
			"type": "object",
			"properties": map[string]any{
				"session_id": map[string]any{"type": "string"},
				"direction":  map[string]any{"type": "string", "enum": []string{"up", "down"}},
				"amount_px":  map[string]any{"type": "integer", "description": "Pixels to scroll (e.g. 800)."},
			},
			"required": []string{"session_id", "direction", "amount_px"},
		},
	}
}

func WebBrowserFillFormTool() models.ToolDefinition {
	return models.ToolDefinition{
		Name:        "webBrowserFillForm",
		Description: `Fill multiple form fields at once. Cheaper than calling webBrowserType per field. Returns updated page_state.`,
		Parameters: map[string]any{
			"type": "object",
			"properties": map[string]any{
				"session_id": map[string]any{"type": "string"},
				"fields": map[string]any{
					"type": "array",
					"items": map[string]any{
						"type": "object",
						"properties": map[string]any{
							"selector": map[string]any{"type": "string"},
							"value":    map[string]any{"type": "string"},
						},
						"required": []string{"selector", "value"},
					},
				},
			},
			"required": []string{"session_id", "fields"},
		},
	}
}

func WebBrowserWaitForTool() models.ToolDefinition {
	return models.ToolDefinition{
		Name:        "webBrowserWaitFor",
		Description: `Wait for an element to become visible (preferred) or wait a fixed number of milliseconds. Returns updated page_state.`,
		Parameters: map[string]any{
			"type": "object",
			"properties": map[string]any{
				"session_id": map[string]any{"type": "string"},
				"selector":   map[string]any{"type": "string", "description": "CSS selector to wait for (preferred)."},
				"ms":         map[string]any{"type": "integer", "description": "Fallback: fixed wait in milliseconds (used only if selector is empty)."},
			},
			"required": []string{"session_id"},
		},
	}
}

func WebBrowserNavigateTool() models.ToolDefinition {
	return models.ToolDefinition{
		Name:        "webBrowserNavigate",
		Description: `Navigate browser history: back, forward, or reload. Returns updated page_state.`,
		Parameters: map[string]any{
			"type": "object",
			"properties": map[string]any{
				"session_id": map[string]any{"type": "string"},
				"direction":  map[string]any{"type": "string", "enum": []string{"back", "forward", "reload"}},
			},
			"required": []string{"session_id", "direction"},
		},
	}
}

func WebBrowserGetDomTool() models.ToolDefinition {
	return models.ToolDefinition{
		Name:        "webBrowserGetDom",
		Description: `Return the full markdown + metadata extraction of the current page in the browser session. Call this when you need the complete content (not just the excerpt from page_state).`,
		Parameters: map[string]any{
			"type": "object",
			"properties": map[string]any{
				"session_id": map[string]any{"type": "string"},
			},
			"required": []string{"session_id"},
		},
	}
}

func WebBrowserCloseTool() models.ToolDefinition {
	return models.ToolDefinition{
		Name:        "webBrowserClose",
		Description: `Close the browser session and free resources. ALWAYS call this when you're done with a browser session.`,
		Parameters: map[string]any{
			"type": "object",
			"properties": map[string]any{
				"session_id": map[string]any{"type": "string"},
			},
			"required": []string{"session_id"},
		},
	}
}

// WebFetchFirecrawlTool returns the webFetchFirecrawl tool definition.
// The remaining-quota count is injected into the description at registration
// time so the AI is cost-aware. Pass remaining=nil to indicate unlimited.
func WebFetchFirecrawlTool(remaining *int) models.ToolDefinition {
	quotaLine := "Each call consumes 1 of your unlimited Firecrawl pages."
	if remaining != nil {
		quotaLine = fmt.Sprintf("Each call costs 1 of %d Firecrawl pages remaining this month.", *remaining)
	}
	description := fmt.Sprintf(`Fetch a public URL via the Firecrawl cloud scraper (handles WAFs, bot challenges, JS rendering, residential IPs).

Use ONLY when webFetchHttp returned error_code "blocked_by_site" AND webBrowserOpen also returned "blocked_by_site". This is the most expensive tier — do not call speculatively.

%s

Returns: { url, status, title, markdown, metadata } on success; { error, error_code, retryable } on failure. error_code "firecrawl_quota_exhausted" means the user's monthly allowance ran out; "firecrawl_session_cap_reached" means too many calls in this build.`, quotaLine)

	return models.ToolDefinition{
		Name:        "webFetchFirecrawl",
		Description: description,
		Parameters: map[string]any{
			"type": "object",
			"properties": map[string]any{
				"url": map[string]any{
					"type":        "string",
					"description": "The fully-qualified http:// or https:// URL to fetch.",
				},
			},
			"required": []string{"url"},
		},
	}
}
