// ═══════════════════════════════════════════════════════════
// MCP App Modal Hosting — HTML generation for HITL modals
// ═══════════════════════════════════════════════════════════

import { readFileSync, existsSync } from "node:fs";
import { resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import type { Pipeline } from "../types.js";

interface ModalContext {
  modalType: string;
  modalVersion: string;
  sessionId: string;
  pipelineId: string;
  pipelineName: string;
  itemId: string;
  itemName: string;
  theme: "dark" | "light";
  accentColor: string;
}

/**
 * Build the review modal HTML. This is a self-contained HTML document
 * that will be rendered in a sandboxed iframe by the MCP UI host.
 *
 * The modal communicates back via window.parent.postMessage().
 */
export function buildReviewModalHtml(
  context: ModalContext,
  pipeline: Pipeline,
  modalType: string,
): string {
  const contextJson = JSON.stringify(context);
  const pipelineJson = JSON.stringify({
    id: pipeline.id,
    name: pipeline.name,
    platform: pipeline.platform,
    stage: pipeline.currentStage,
    status: pipeline.status,
    priority: pipeline.priority,
    template: pipeline.template,
  });

  switch (modalType) {
    case "traffic-light":
      return buildTrafficLightModal(contextJson, pipelineJson, pipeline);
    case "report-card":
      return buildReportCardModal(contextJson, pipelineJson, pipeline);
    case "checklist-ceremony":
      return buildChecklistModal(contextJson, pipelineJson, pipeline);
    default:
      return buildTrafficLightModal(contextJson, pipelineJson, pipeline);
  }
}

function buildTrafficLightModal(
  contextJson: string,
  pipelineJson: string,
  pipeline: Pipeline,
): string {
  return `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Review: ${escapeHtml(pipeline.name)}</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
      background: #1a1a2e;
      color: #eee;
      padding: 24px;
      min-height: 100vh;
    }
    .header {
      text-align: center;
      margin-bottom: 24px;
    }
    .header h1 {
      font-size: 1.5rem;
      color: #fff;
      margin-bottom: 4px;
    }
    .header .subtitle {
      color: #888;
      font-size: 0.85rem;
    }
    .info-grid {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 12px;
      margin-bottom: 24px;
    }
    .info-card {
      background: #16213e;
      border-radius: 8px;
      padding: 12px;
    }
    .info-card .label {
      font-size: 0.75rem;
      color: #888;
      text-transform: uppercase;
      letter-spacing: 0.05em;
    }
    .info-card .value {
      font-size: 1.1rem;
      font-weight: 600;
      margin-top: 4px;
    }
    .traffic-lights {
      display: flex;
      justify-content: center;
      gap: 24px;
      margin: 32px 0;
    }
    .light-btn {
      width: 80px;
      height: 80px;
      border-radius: 50%;
      border: 3px solid transparent;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 2rem;
      transition: all 0.2s;
      opacity: 0.5;
    }
    .light-btn:hover { opacity: 1; transform: scale(1.1); }
    .light-btn.selected { opacity: 1; border-color: #fff; transform: scale(1.15); }
    .light-btn.approve { background: #22c55e; }
    .light-btn.needs-work { background: #f59e0b; }
    .light-btn.reject { background: #ef4444; }
    .notes-area {
      width: 100%;
      margin: 16px 0;
    }
    .notes-area textarea {
      width: 100%;
      height: 80px;
      background: #16213e;
      border: 1px solid #333;
      border-radius: 8px;
      color: #eee;
      padding: 12px;
      font-family: inherit;
      font-size: 0.9rem;
      resize: vertical;
    }
    .notes-area textarea:focus {
      outline: none;
      border-color: #4488FF;
    }
    .submit-btn {
      display: block;
      width: 100%;
      padding: 14px;
      border: none;
      border-radius: 8px;
      font-size: 1rem;
      font-weight: 600;
      cursor: pointer;
      background: #4488FF;
      color: #fff;
      transition: background 0.2s;
    }
    .submit-btn:hover { background: #3366DD; }
    .submit-btn:disabled { opacity: 0.4; cursor: not-allowed; }
    .decision-label {
      text-align: center;
      margin-top: 8px;
      font-size: 0.85rem;
      color: #888;
      min-height: 1.2em;
    }
  </style>
</head>
<body>
  <script>window.__FACTORY_CONTEXT__ = ${contextJson};</script>

  <div class="header">
    <h1>🚦 Review: ${escapeHtml(pipeline.name)}</h1>
    <div class="subtitle">${escapeHtml(pipeline.platform)} · ${pipeline.currentStage} stage</div>
  </div>

  <div class="info-grid">
    <div class="info-card">
      <div class="label">Priority</div>
      <div class="value">${pipeline.priority}</div>
    </div>
    <div class="info-card">
      <div class="label">Status</div>
      <div class="value">${pipeline.status}</div>
    </div>
    <div class="info-card">
      <div class="label">Stage</div>
      <div class="value">${pipeline.currentStage}</div>
    </div>
    <div class="info-card">
      <div class="label">Template</div>
      <div class="value">${pipeline.template}</div>
    </div>
  </div>

  <div class="traffic-lights">
    <button class="light-btn approve" data-decision="approved" title="Approve">✅</button>
    <button class="light-btn needs-work" data-decision="needs_work" title="Needs Work">⚠️</button>
    <button class="light-btn reject" data-decision="rejected" title="Reject">❌</button>
  </div>
  <div class="decision-label" id="decisionLabel"></div>

  <div class="notes-area">
    <textarea id="notes" placeholder="Add notes (optional for approve, required for reject)..."></textarea>
  </div>

  <button class="submit-btn" id="submitBtn" disabled>Select a decision above</button>

  <script>
    const startTime = Date.now();
    let selectedDecision = null;
    const decisionLabels = {
      approved: '✅ Approve — pipeline will advance',
      needs_work: '⚠️ Needs Work — send back with feedback',
      rejected: '❌ Reject — pipeline stops'
    };

    // Signal ready
    window.parent.postMessage({
      type: 'factory_modal_ready',
      modalType: 'traffic-light',
      version: '1.0.0'
    }, '*');

    // Light buttons
    document.querySelectorAll('.light-btn').forEach(btn => {
      btn.addEventListener('click', () => {
        document.querySelectorAll('.light-btn').forEach(b => b.classList.remove('selected'));
        btn.classList.add('selected');
        selectedDecision = btn.dataset.decision;
        document.getElementById('decisionLabel').textContent = decisionLabels[selectedDecision];
        document.getElementById('submitBtn').disabled = false;
        document.getElementById('submitBtn').textContent = 'Submit Review';
      });
    });

    // Submit
    document.getElementById('submitBtn').addEventListener('click', () => {
      if (!selectedDecision) return;
      const notes = document.getElementById('notes').value.trim();

      if (selectedDecision === 'rejected' && !notes) {
        document.getElementById('notes').style.borderColor = '#ef4444';
        document.getElementById('notes').placeholder = 'Please explain why you are rejecting...';
        return;
      }

      const response = {
        type: 'factory_modal_response',
        modalType: 'traffic-light',
        modalVersion: '1.0.0',
        pipelineId: window.__FACTORY_CONTEXT__.pipelineId,
        itemId: window.__FACTORY_CONTEXT__.itemId,
        sessionId: window.__FACTORY_CONTEXT__.sessionId,
        timestamp: new Date().toISOString(),
        responseTimeMs: Date.now() - startTime,
        feedback: {
          decision: {
            decision: selectedDecision,
            reason: notes || undefined
          }
        },
        meta: {
          timeToFirstInteractionMs: Date.now() - startTime,
          timeToDecisionMs: Date.now() - startTime,
          fieldsModified: [selectedDecision ? 'decision' : '', notes ? 'notes' : ''].filter(Boolean),
          totalInteractions: 0,
          viewportSize: { width: window.innerWidth, height: window.innerHeight },
          deviceType: window.innerWidth < 768 ? 'mobile' : 'desktop'
        }
      };

      window.parent.postMessage(response, '*');
    });
  </script>
</body>
</html>`;
}

function buildReportCardModal(
  contextJson: string,
  pipelineJson: string,
  pipeline: Pipeline,
): string {
  const dimensions = [
    { id: "code_quality", name: "Code Quality", weight: 3 },
    { id: "test_coverage", name: "Test Coverage", weight: 2 },
    { id: "documentation", name: "Documentation", weight: 2 },
    { id: "error_handling", name: "Error Handling", weight: 2 },
    { id: "architecture", name: "Architecture", weight: 1 },
    { id: "performance", name: "Performance", weight: 1 },
  ];

  return `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Report Card: ${escapeHtml(pipeline.name)}</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
      background: #1a1a2e;
      color: #eee;
      padding: 24px;
    }
    .header { text-align: center; margin-bottom: 24px; }
    .header h1 { font-size: 1.5rem; color: #fff; }
    .header .subtitle { color: #888; font-size: 0.85rem; }
    .dimension {
      background: #16213e;
      border-radius: 8px;
      padding: 16px;
      margin-bottom: 12px;
    }
    .dimension .dim-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 8px;
    }
    .dimension .dim-name { font-weight: 600; }
    .dimension .dim-score { font-size: 1.2rem; font-weight: bold; color: #4488FF; min-width: 2em; text-align: center; }
    .slider-container { position: relative; }
    input[type="range"] {
      width: 100%;
      -webkit-appearance: none;
      height: 6px;
      border-radius: 3px;
      background: #333;
      outline: none;
    }
    input[type="range"]::-webkit-slider-thumb {
      -webkit-appearance: none;
      width: 20px;
      height: 20px;
      border-radius: 50%;
      background: #4488FF;
      cursor: pointer;
    }
    .notes-area { width: 100%; margin: 16px 0; }
    .notes-area textarea {
      width: 100%; height: 80px; background: #16213e;
      border: 1px solid #333; border-radius: 8px; color: #eee;
      padding: 12px; font-family: inherit; font-size: 0.9rem; resize: vertical;
    }
    .notes-area textarea:focus { outline: none; border-color: #4488FF; }
    .submit-btn {
      display: block; width: 100%; padding: 14px; border: none;
      border-radius: 8px; font-size: 1rem; font-weight: 600; cursor: pointer;
      background: #4488FF; color: #fff; transition: background 0.2s;
    }
    .submit-btn:hover { background: #3366DD; }
    .avg-score { text-align: center; font-size: 2rem; font-weight: bold; color: #4488FF; margin: 16px 0; }
  </style>
</head>
<body>
  <script>window.__FACTORY_CONTEXT__ = ${contextJson};</script>

  <div class="header">
    <h1>📋 Report Card: ${escapeHtml(pipeline.name)}</h1>
    <div class="subtitle">${escapeHtml(pipeline.platform)} · Rate each dimension 1-10</div>
  </div>

  <div class="avg-score" id="avgScore">—</div>

  ${dimensions
    .map(
      (d) => `
  <div class="dimension">
    <div class="dim-header">
      <span class="dim-name">${d.name}</span>
      <span class="dim-score" id="score-${d.id}">5</span>
    </div>
    <div class="slider-container">
      <input type="range" min="1" max="10" value="5" data-dimension="${d.id}" data-weight="${d.weight}">
    </div>
  </div>`,
    )
    .join("")}

  <div class="notes-area">
    <textarea id="notes" placeholder="Overall feedback..."></textarea>
  </div>

  <button class="submit-btn" id="submitBtn">Submit Report Card</button>

  <script>
    const startTime = Date.now();
    const scores = {};

    window.parent.postMessage({ type: 'factory_modal_ready', modalType: 'report-card', version: '1.0.0' }, '*');

    function updateAvg() {
      const sliders = document.querySelectorAll('input[type="range"]');
      let totalWeighted = 0, totalWeight = 0;
      sliders.forEach(s => {
        const w = parseInt(s.dataset.weight);
        totalWeighted += parseInt(s.value) * w;
        totalWeight += w;
      });
      document.getElementById('avgScore').textContent = (totalWeighted / totalWeight).toFixed(1);
    }

    document.querySelectorAll('input[type="range"]').forEach(slider => {
      slider.addEventListener('input', () => {
        const dim = slider.dataset.dimension;
        scores[dim] = parseInt(slider.value);
        document.getElementById('score-' + dim).textContent = slider.value;
        updateAvg();
      });
      scores[slider.dataset.dimension] = 5;
    });
    updateAvg();

    document.getElementById('submitBtn').addEventListener('click', () => {
      const notes = document.getElementById('notes').value.trim();
      const dimensionScores = Object.entries(scores).map(([dim, score]) => ({
        dimension: dim,
        score: score,
        weight: parseInt(document.querySelector('[data-dimension="' + dim + '"]').dataset.weight)
      }));

      window.parent.postMessage({
        type: 'factory_modal_response',
        modalType: 'report-card',
        modalVersion: '1.0.0',
        pipelineId: ${contextJson}.pipelineId,
        itemId: ${contextJson}.itemId,
        sessionId: ${contextJson}.sessionId,
        timestamp: new Date().toISOString(),
        responseTimeMs: Date.now() - startTime,
        feedback: {
          scores: dimensionScores,
          freeText: notes ? { generalNotes: notes } : undefined
        },
        meta: {
          timeToFirstInteractionMs: Date.now() - startTime,
          timeToDecisionMs: Date.now() - startTime,
          fieldsModified: Object.keys(scores),
          totalInteractions: 0,
          viewportSize: { width: window.innerWidth, height: window.innerHeight },
          deviceType: window.innerWidth < 768 ? 'mobile' : 'desktop'
        }
      }, '*');
    });
  </script>
</body>
</html>`;
}

function buildChecklistModal(
  contextJson: string,
  pipelineJson: string,
  pipeline: Pipeline,
): string {
  const items = [
    { id: "tests_passing", label: "All tests passing", desc: "Unit, integration, and e2e" },
    { id: "coverage", label: "Test coverage ≥ 80%", desc: "Measured by coverage tool" },
    { id: "readme", label: "README.md complete", desc: "Description, setup, usage, API docs" },
    { id: "tools_doc", label: "TOOLS.md documents all tools", desc: "Every MCP tool documented" },
    { id: "no_secrets", label: "No hardcoded secrets", desc: "All secrets in env vars" },
    { id: "error_handling", label: "Proper error handling", desc: "All API calls wrapped" },
    { id: "code_review", label: "Code review passed", desc: "Reviewed by human or AI" },
    { id: "env_documented", label: "Environment vars documented", desc: ".env.example complete" },
  ];

  return `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Checklist: ${escapeHtml(pipeline.name)}</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
      background: #1a1a2e;
      color: #eee;
      padding: 24px;
    }
    .header { text-align: center; margin-bottom: 24px; }
    .header h1 { font-size: 1.5rem; color: #fff; }
    .header .subtitle { color: #888; font-size: 0.85rem; }
    .progress-bar {
      width: 100%;
      height: 8px;
      background: #333;
      border-radius: 4px;
      margin-bottom: 24px;
      overflow: hidden;
    }
    .progress-fill {
      height: 100%;
      background: #22c55e;
      border-radius: 4px;
      transition: width 0.3s;
    }
    .progress-text { text-align: center; color: #888; font-size: 0.85rem; margin-bottom: 16px; }
    .check-item {
      background: #16213e;
      border-radius: 8px;
      padding: 14px;
      margin-bottom: 8px;
      display: flex;
      align-items: flex-start;
      gap: 12px;
      cursor: pointer;
      transition: background 0.2s;
    }
    .check-item:hover { background: #1a2744; }
    .check-item input[type="checkbox"] {
      width: 20px; height: 20px; margin-top: 2px; cursor: pointer;
      accent-color: #22c55e;
    }
    .check-item .text .label { font-weight: 600; }
    .check-item .text .desc { color: #888; font-size: 0.8rem; margin-top: 2px; }
    .check-item.checked { opacity: 0.6; }
    .check-item.checked .label { text-decoration: line-through; }
    .submit-btn {
      display: block; width: 100%; padding: 14px; border: none;
      border-radius: 8px; font-size: 1rem; font-weight: 600; cursor: pointer;
      background: #22c55e; color: #fff; transition: background 0.2s; margin-top: 16px;
    }
    .submit-btn:hover { background: #16a34a; }
    .submit-btn:disabled { opacity: 0.4; cursor: not-allowed; background: #666; }
  </style>
</head>
<body>
  <script>window.__FACTORY_CONTEXT__ = ${contextJson};</script>

  <div class="header">
    <h1>✅ Checklist: ${escapeHtml(pipeline.name)}</h1>
    <div class="subtitle">Complete all items to approve</div>
  </div>

  <div class="progress-text" id="progressText">0 / ${items.length} completed</div>
  <div class="progress-bar"><div class="progress-fill" id="progressFill" style="width: 0%"></div></div>

  ${items
    .map(
      (item) => `
  <div class="check-item" data-id="${item.id}">
    <input type="checkbox" id="check-${item.id}">
    <div class="text">
      <div class="label">${item.label}</div>
      <div class="desc">${item.desc}</div>
    </div>
  </div>`,
    )
    .join("")}

  <button class="submit-btn" id="submitBtn" disabled>Complete all items to submit</button>

  <script>
    const startTime = Date.now();
    const checkOrder = [];
    const total = ${items.length};

    window.parent.postMessage({ type: 'factory_modal_ready', modalType: 'checklist-ceremony', version: '1.0.0' }, '*');

    function updateProgress() {
      const checked = document.querySelectorAll('input[type="checkbox"]:checked').length;
      const pct = Math.round((checked / total) * 100);
      document.getElementById('progressFill').style.width = pct + '%';
      document.getElementById('progressText').textContent = checked + ' / ' + total + ' completed';

      const btn = document.getElementById('submitBtn');
      if (checked === total) {
        btn.disabled = false;
        btn.textContent = '🎉 All Clear — Submit';
      } else {
        btn.disabled = true;
        btn.textContent = 'Complete all items to submit';
      }
    }

    document.querySelectorAll('.check-item').forEach(item => {
      const cb = item.querySelector('input[type="checkbox"]');
      item.addEventListener('click', (e) => {
        if (e.target !== cb) cb.checked = !cb.checked;
        item.classList.toggle('checked', cb.checked);
        if (cb.checked) checkOrder.push(item.dataset.id);
        updateProgress();
      });
    });

    document.getElementById('submitBtn').addEventListener('click', () => {
      const checks = {};
      document.querySelectorAll('input[type="checkbox"]').forEach(cb => {
        checks[cb.id.replace('check-', '')] = cb.checked;
      });

      window.parent.postMessage({
        type: 'factory_modal_response',
        modalType: 'checklist-ceremony',
        modalVersion: '1.0.0',
        pipelineId: ${contextJson}.pipelineId,
        itemId: ${contextJson}.itemId,
        sessionId: ${contextJson}.sessionId,
        timestamp: new Date().toISOString(),
        responseTimeMs: Date.now() - startTime,
        feedback: {
          checklist: {
            checks: checks,
            notes: {},
            checkOrder: checkOrder,
            allClear: true,
            completionRate: 1.0
          }
        },
        meta: {
          timeToFirstInteractionMs: Date.now() - startTime,
          timeToDecisionMs: Date.now() - startTime,
          fieldsModified: checkOrder,
          totalInteractions: checkOrder.length,
          viewportSize: { width: window.innerWidth, height: window.innerHeight },
          deviceType: window.innerWidth < 768 ? 'mobile' : 'desktop'
        }
      }, '*');
    });
  </script>
</body>
</html>`;
}

function escapeHtml(str: string): string {
  return str
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#039;");
}
