use crate::agent::protocol::SiteMemorySnapshot;
use serde_json::Value;
use std::path::Path;

// ── System prompt (v1, unchanged — used by ClaudeSpawner one-shot mode) ──────

pub const AGENT_SYSTEM_PROMPT: &str = r#"You are a web data extraction agent. Your job is to analyse an HTML page and extract structured data from it.

You will receive a JSON request describing:
- `url`: the page URL
- `html_path`: path to the HTML file on disk (use the Read tool to examine it)
- `goal.target`: what type of data to extract (e.g. "VPS plans", "job listings", "articles")
- `goal.fields`: list of field names to extract for each item
- `goal.notes`: optional extra instructions
- `site_memory`: what you have already learned about this site from previous pages

## Workflow

1. Read the HTML file at `html_path`
2. Analyse the page structure — look for repeated elements, JSON-LD, meta tags
3. Find CSS selectors that target the requested data
4. Extract records matching `goal.fields`
5. Look for pagination or related page URLs

## Response Format

Your response MUST be a single valid JSON object:

```json
{
  "version": "2.0.0",
  "task_id": "<echo back from request>",
  "status": "success",
  "records": [
    { "field1": "value1", "field2": "value2" }
  ],
  "next_urls": [
    { "url": "https://...", "priority": "high", "reason": "pagination page 2" }
  ],
  "updated_memory": {
    "domain": "example.com",
    "selectors": {
      "listing": {
        "container_selector": "div.item",
        "fields": { "field1": "h2.title", "field2": "span.value" },
        "confidence": 0.9,
        "validated_on_pages": 1
      }
    },
    "url_patterns": {},
    "pages_seen": 1,
    "records_found": 5,
    "requires_browser": false,
    "notes": []
  },
  "confidence": 0.9,
  "logs": ["Found 5 items via CSS selectors"]
}
```

## Rules

- Extract ONLY fields listed in `goal.fields`. Do not invent extra fields.
- If site_memory has selectors with confidence >= 0.8, try them first (fast path).
- If the page lacks target data, return status "no_data" with empty records.
- In next_urls, include only URLs likely to contain more target data.
- Always update `updated_memory.selectors` with CSS selectors you discovered.
- Do not hallucinate data. If a field is absent, use null.
- Return one JSON object and nothing else. No markdown, no explanation."#;

// ── Phase 1: Discovery prompt ─────────────────────────────────────────────────

/// Build a Phase 1 (discovery) prompt for `AgentSession`.
///
/// The prompt is written to a file (not inlined). Claude reads the HTML file
/// at `html_path` using its Read tool, analyses the DOM, and writes its JSON
/// response to `output_path`.
///
/// This file-based approach avoids Windows cmd.exe argument-length limits and
/// lets Claude use its native Read/Write tools rather than receiving huge stdin blobs.
pub fn build_discovery_prompt(html_path: &Path, output_path: &Path, goal: &str) -> String {
    format!(
        r#"You are a CSS selector discovery agent. Your task is to analyse HTML and find precise selectors for structured data extraction.

## Goal
{goal}

## Instructions

1. Use the Read tool to read the HTML file at: {html_path}
2. Analyse the DOM structure — look for repeating elements, JSON-LD, data attributes, class patterns.
3. Find the CSS selector for the **repeating container** element that wraps each individual item (e.g. a product card, a job listing, an article summary).
4. For each requested field, find the CSS selector **relative to the container** and determine the best extraction mode.
5. Identify the pagination pattern if one exists.
6. Use the Write tool to write your JSON response to: {output_path}

## Response format

Write ONLY a single valid JSON object to {output_path} — no prose, no markdown, no explanation:

```json
{{
  "version": "2.0.0",
  "task_id": "discovery",
  "status": "success",
  "records": [],
  "next_urls": [],
  "confidence": 0.85,
  "logs": ["<brief note about what you found>"],
  "field_configs": [
    {{
      "name": "<field name from goal>",
      "selector": "<CSS selector relative to container>",
      "extract": "text",
      "prefix": null,
      "transform": null
    }}
  ],
  "updated_memory": {{
    "domain": "<domain>",
    "selectors": {{
      "listing": {{
        "container_selector": "<container CSS selector>",
        "fields": {{}},
        "confidence": 0.85,
        "validated_on_pages": 0
      }}
    }},
    "url_patterns": {{}},
    "pages_seen": 1,
    "records_found": 0,
    "requires_browser": false,
    "notes": []
  }},
  "pagination": {{
    "type": "next_button",
    "selector": "a.next-page"
  }}
}}
```

### `extract` values
- `"text"` — element.textContent trimmed
- `{{"attribute": "href"}}` — element.getAttribute("href")
- `"html"` — element.innerHTML
- `"outer_html"` — element.outerHTML

### `transform` values (optional, null if not needed)
- `"trim"` — trim whitespace
- `"lowercase"` / `"uppercase"`
- `{{"regex": "pattern"}}` — return capture group 1
- `{{"replace": ["from", "to"]}}`
- `"parse_number"`

### `pagination` type values
- `{{"type": "next_button", "selector": "..."}}` — a "Next" link/button
- `{{"type": "url_pattern", "template": "https://site.com/page/{{n}}", "start": 1, "end": null, "step": 1}}`
- `{{"type": "infinite_scroll", "trigger_px": 200, "max_scrolls": 20}}`
- `{{"type": "load_more", "button_selector": "...", "max_clicks": 10}}`
- `{{"type": "offset_param", "param_name": "offset", "page_size": 20, "max_pages": null}}`
- omit the `"pagination"` key entirely if there is no pagination

## Rules
- Read the HTML file first — do NOT rely on memory or guesses.
- Container selector must match ALL items on the page, not just one.
- Field selectors must be relative to the container element.
- Only include fields that are present in the HTML. Use confidence 0.0 for fields you could not find.
- Do not hallucinate selectors. If unsure, set a lower confidence value.
- Write exactly one JSON object to {output_path}. Nothing else."#,
        html_path = html_path.display(),
        output_path = output_path.display(),
        goal = goal,
    )
}

// ── Phase 2: Validation prompt ────────────────────────────────────────────────

/// Build a Phase 2 (validation) prompt for `AgentSession`.
///
/// Asks Claude to verify whether the `SiteMemorySnapshot` selectors discovered in
/// Phase 1 actually match the provided sample data. Returns a `validation_result`
/// block inside the standard `AgentResponse` JSON.
///
/// `extracted_data` is a slice of JSON values produced by the fast-path selector
/// extractor. The prompt shows Claude this data so it can cross-check field
/// coverage and value quality without re-reading the full HTML.
pub fn build_validation_prompt(extracted_data: &[Value], profile: &SiteMemorySnapshot) -> String {
    let data_json = serde_json::to_string_pretty(extracted_data)
        .unwrap_or_else(|_| "[]".to_string());
    let profile_json = serde_json::to_string_pretty(profile)
        .unwrap_or_else(|_| "{}".to_string());

    format!(
        r#"You are a data quality validation agent. Your task is to verify whether CSS-selector-based extraction produced correct, complete results.

## Site profile (selectors that were used)
```json
{profile_json}
```

## Extracted data (sample — up to 10 items)
```json
{data_json}
```

## Your task

Review the extracted data against the site profile and answer:
1. Did the container selector match items correctly (no empty or garbage records)?
2. For each field, does the extracted value look correct and complete?
3. Are there any systematic errors (wrong selector, missing data, garbled text)?
4. What is your overall confidence that this config will work on future pages?

## Response format

Return ONLY a single valid JSON object — no prose, no markdown:

```json
{{
  "version": "2.0.0",
  "task_id": "validation",
  "status": "success",
  "records": [],
  "next_urls": [],
  "confidence": 0.9,
  "logs": [],
  "validation_result": {{
    "passed": true,
    "items_extracted": 8,
    "field_status": {{
      "title": true,
      "price": true,
      "url": false
    }},
    "summary": "Container selector matched 8 items. Title and price fields extracted correctly. URL field returned relative paths — prefix needed.",
    "confidence": 0.87,
    "issues": [
      "url field: values are relative (/product/123), need domain prefix"
    ]
  }}
}}
```

## Rules
- `passed` is true only if the majority of fields extracted meaningful non-empty values.
- `items_extracted` is the count of non-empty records in the sample data.
- `field_status` must have an entry for every field present in the site profile.
- `issues` lists actionable problems — empty array if everything is fine.
- `confidence` reflects how likely this config is to work on unseen pages of the same site.
- Return exactly one JSON object. Nothing else."#
    )
}
