/**
 * REFINED INSTRUCTIONS multi-agent pipeline
 *
 * Three roles work in sequence to produce high-quality build instructions:
 *   Communicator → Refiner → (optional) Reviewer
 *
 * The output format uses named markers so downstream skills can extract it:
 *   === REFINED INSTRUCTIONS START ===
 *   [narrative instructions in plain English]
 *   Please create exactly this.
 *   === REFINED INSTRUCTIONS END ===
 */

// ---------------------------------------------------------------------------
// System prompts
// ---------------------------------------------------------------------------

const COMMUNICATOR_SYSTEM = `You are the Communicator — a warm, perceptive interpreter of user requests.

Your job is to deeply understand what the user wants and produce a precise, self-contained REFINED INSTRUCTIONS block that a generative AI can execute without follow-up questions.

Process:
1. Identify the core goal and target audience.
2. Infer missing but obvious details (style, tone, device target, interactivity level).
3. Spell out every important feature, behaviour, and constraint in plain English.
4. End with the REFINED INSTRUCTIONS block using the exact markers below.

Output format — include ONLY this, no preamble:
=== REFINED INSTRUCTIONS START ===
[Narrative instructions. Be specific about layout, colours, interactions, data, edge cases, responsive behaviour, and accessibility. Write as if briefing a senior developer who will build it in one pass.]
Please create exactly this.
=== REFINED INSTRUCTIONS END ===`;

const REFINER_SYSTEM = `You are the Refiner — a meticulous technical editor who makes build instructions production-ready.

Given a REFINED INSTRUCTIONS block, you will:
1. Remove vague language ("nice", "good", "modern") and replace with specifics.
2. Add any missing cross-cutting concerns: responsive layout, keyboard navigation, empty states, loading states, error messages.
3. Eliminate contradictions and redundancy.
4. Keep the instructions focused — remove anything a one-file deliverable cannot achieve.
5. Return ONLY the improved REFINED INSTRUCTIONS block using the exact markers below.

Output format — include ONLY this, no preamble:
=== REFINED INSTRUCTIONS START ===
[Improved narrative instructions]
Please create exactly this.
=== REFINED INSTRUCTIONS END ===`;

const REVIEWER_SYSTEM = `You are the Reviewer — a quality-assurance expert who evaluates deliverables against their instructions.

Given the REFINED INSTRUCTIONS and the generated output, you will:
1. List which requirements are fully met.
2. List which requirements are partially met or missing.
3. Give an overall approval verdict.
4. Provide concise, actionable notes for improvement.

Return JSON only (no markdown fences):
{
  "approved": true | false,
  "met": ["..."],
  "unmet": ["..."],
  "notes": "One or two sentences of the most important fix to make."
}`;

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function extractBlock(text) {
  const start = text.indexOf('=== REFINED INSTRUCTIONS START ===');
  const end = text.indexOf('=== REFINED INSTRUCTIONS END ===');
  if (start === -1 || end === -1 || end <= start) return text.trim();
  return text.slice(start, end + '=== REFINED INSTRUCTIONS END ==='.length).trim();
}

// ---------------------------------------------------------------------------
// Exported pipeline functions
// ---------------------------------------------------------------------------

/**
 * Communicator pass — turns a raw user request into a structured REFINED INSTRUCTIONS block.
 *
 * @param {string} userRequest
 * @param {{ askLLM: Function, pickModel: Function }} deps
 * @returns {Promise<string>} The REFINED INSTRUCTIONS block
 */
export async function generateRefinedInstructions(userRequest, { askLLM, pickModel }) {
  const prompt = `${COMMUNICATOR_SYSTEM}

User request:
${userRequest}`;

  const raw = await askLLM(prompt, { model: pickModel('build') });
  return extractBlock(raw);
}

/**
 * Refiner pass — polishes an existing REFINED INSTRUCTIONS block.
 *
 * @param {string} rawInstructions  An existing REFINED INSTRUCTIONS block (or plain text)
 * @param {{ askLLM: Function, pickModel: Function }} deps
 * @returns {Promise<string>} An improved REFINED INSTRUCTIONS block
 */
export async function refineInstructions(rawInstructions, { askLLM, pickModel }) {
  const prompt = `${REFINER_SYSTEM}

Instructions to refine:
${rawInstructions}`;

  const raw = await askLLM(prompt, { model: pickModel('build') });
  return extractBlock(raw);
}

/**
 * Reviewer pass — evaluates generated output against the instructions.
 *
 * @param {string} instructions  The REFINED INSTRUCTIONS block used during generation
 * @param {string} output        The generated content (e.g. HTML)
 * @param {{ askLLM: Function, pickModel: Function }} deps
 * @returns {Promise<{ approved: boolean, notes: string, met: string[], unmet: string[] }>}
 */
export async function reviewOutput(instructions, output, { askLLM, pickModel }) {
  const prompt = `${REVIEWER_SYSTEM}

=== INSTRUCTIONS ===
${instructions}

=== OUTPUT (first 6000 chars) ===
${output.slice(0, 6000)}`;

  const raw = await askLLM(prompt, { model: pickModel('classify') });

  // Parse JSON — strip any accidental markdown fences
  try {
    const clean = raw.replace(/^```(?:json)?\s*/i, '').replace(/\s*```$/i, '').trim();
    return JSON.parse(clean);
  } catch {
    // Fallback: treat any response as notes, default to approved
    return { approved: true, notes: raw.slice(0, 300), met: [], unmet: [] };
  }
}
