import { formatExecutionContext, harnessRemediation } from "./outcome-presentation.js";
import type { HarnessOutcomeRecord } from "./types.js";

function escapeHtml(value: string): string {
  return value
    .replaceAll("&", "&amp;")
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")
    .replaceAll('"', "&quot;")
    .replaceAll("'", "&#39;");
}

function renderKeyValue(label: string, value: string, field?: string): string {
  const fieldAttr = field === undefined ? "" : ` data-outcome-field="${escapeHtml(field)}"`;
  return `<div${fieldAttr}><strong>${escapeHtml(label)}:</strong> ${escapeHtml(value)}</div>`;
}

function renderPlannedContext(outcome: HarnessOutcomeRecord): string {
  const formatted = formatExecutionContext(outcome.plannedContext);
  if (formatted.details.length === 0 && formatted.kind === "unknown") {
    return renderKeyValue("Planned context", "not recorded", "planned-context");
  }

  const rows = formatted.details
    .map((entry) => renderKeyValue(entry.label, entry.value))
    .join("");

  return `
    <section data-report-section="planned-context" aria-labelledby="planned-context-heading">
      <h2 id="planned-context-heading">Planned context</h2>
      <div data-outcome-field="planned-context">
        ${renderKeyValue("Kind", formatted.kind)}
        ${rows}
      </div>
    </section>
  `;
}

function renderArtifacts(outcome: HarnessOutcomeRecord): string {
  if (outcome.artifactRefs.length === 0) {
    return renderKeyValue("Artifacts", "none recorded", "artifacts");
  }

  const items = outcome.artifactRefs
    .map(
      (artifact) => `
        <li data-artifact-path="${escapeHtml(artifact.relativePath)}">
          ${escapeHtml(artifact.relativePath)} (${escapeHtml(artifact.mediaType)})
        </li>
      `,
    )
    .join("");

  return `
    <section data-report-section="artifacts" aria-labelledby="artifacts-heading">
      <h2 id="artifacts-heading">Artifacts</h2>
      <ul data-outcome-field="artifacts">${items}</ul>
    </section>
  `;
}

function renderPlannedScope(outcome: HarnessOutcomeRecord): string {
  const parts = [outcome.scope.id];
  if (outcome.scope.detectorId !== undefined) {
    parts.push(`detector=${outcome.scope.detectorId}`);
  }
  if (outcome.scope.surfaceId !== undefined) {
    parts.push(`surface=${outcome.scope.surfaceId}`);
  }
  return renderKeyValue("Planned scope", parts.join(", "), "planned-scope");
}

export function renderHarnessView(outcome: HarnessOutcomeRecord): string {
  const causeSummary = `${outcome.cause.code}: ${outcome.cause.message} (retryable=${String(
    outcome.cause.retryable,
  )})`;

  return `
    <article
      class="outcome-view harness-view"
      data-report-view="harness"
      data-outcome-id="${escapeHtml(outcome.id)}"
      data-adjudicable="false"
      data-non-adjudicable="true"
    >
      <header class="outcome-header">
        <h1>Harness failure</h1>
        <p class="non-adjudicable-banner" role="note">
          Non-adjudicable harness outcome. Correct the harness or rerun a successful comparable scope.
        </p>
      </header>

      ${renderKeyValue("Phase", outcome.phase, "phase")}
      ${renderPlannedScope(outcome)}
      ${renderPlannedContext(outcome)}
      ${renderKeyValue("Cause", causeSummary, "cause")}
      ${renderArtifacts(outcome)}
      ${renderKeyValue("Rerun remediation", harnessRemediation(outcome), "remediation")}
    </article>
  `;
}
