const MSG_COLORS = {
  user:        '#93c5fd', // blue
  assistant:   '#6ee7b7', // green
  tool_call:   '#fcd34d', // amber
  tool_result: '#cbd5e1', // slate
  thinking:    '#c4b5fd', // violet
  system:      '#d1d5db', // gray
};
const COMPACTION_COLOR = '#f59e0b';
const INTERRUPTION_COLOR = '#ef4444';
const COMPACTION_SIG = 'This session is being continued from a previous conversation';
const INTERRUPTION_CLAUDE_SIG = "The user doesn't want to proceed with this tool use";
const INTERRUPTION_CODEX_SIG = '<turn_aborted>';

let minimapVisible = false;
let isDragging = false;

export function renderMinimap(msgs) {
  const minimap = document.getElementById('minimap');
  const canvas = document.getElementById('minimap-canvas');
  const panel = document.getElementById('message-panel');

  if (!msgs || msgs.length < 10) {
    minimap.classList.add('hidden');
    minimapVisible = false;
    return;
  }

  minimap.classList.remove('hidden');
  minimapVisible = true;

  // Build block list from messages (skip progress and empty tool_calls)
  const blocks = [];
  for (const m of msgs) {
    if (m.type === 'progress') continue;
    if (m.type === 'tool_call' && !m.content && (!m.tool || !m.tool.tool_input)) continue;

    const isCompaction = m.type === 'user' && m.content && m.content.startsWith(COMPACTION_SIG);
    const isInterruption = (m.type === 'tool_result' && m.result && m.result.output && m.result.output.includes(INTERRUPTION_CLAUDE_SIG))
      || (m.type === 'user' && m.content && m.content.startsWith(INTERRUPTION_CODEX_SIG));
    // Estimate relative height: user/assistant are taller, tools are shorter
    let weight = 1;
    if (m.type === 'user' || m.type === 'assistant') weight = 2;
    if (m.content && m.content.length > 500) weight = 3;

    // Give interruption blocks more weight so markers are visible on minimap
    if (isInterruption) weight = Math.max(weight, 2);

    blocks.push({
      type: m.type,
      isCompaction,
      isInterruption,
      weight,
    });
  }

  drawCanvas(canvas, blocks);
  updateViewport();
}

function drawCanvas(canvas, blocks) {
  const container = canvas.parentElement;
  const height = container.clientHeight;
  const width = container.clientWidth;

  // Set actual pixel dimensions
  const dpr = window.devicePixelRatio || 1;
  canvas.width = width * dpr;
  canvas.height = height * dpr;
  canvas.style.width = width + 'px';
  canvas.style.height = height + 'px';

  const ctx = canvas.getContext('2d');
  ctx.scale(dpr, dpr);
  ctx.clearRect(0, 0, width, height);

  const totalWeight = blocks.reduce((s, b) => s + b.weight, 0);
  const gap = 0.5;

  let y = 0;
  for (const block of blocks) {
    const blockH = Math.max(1, (block.weight / totalWeight) * height - gap);

    if (block.isCompaction) {
      // Draw prominent compaction breakpoint band
      const midY = y + blockH / 2;
      // Amber background band
      ctx.fillStyle = 'rgba(245, 158, 11, 0.15)';
      ctx.fillRect(0, y, width, blockH);
      // Solid amber line
      ctx.strokeStyle = COMPACTION_COLOR;
      ctx.lineWidth = 2;
      ctx.setLineDash([]);
      ctx.beginPath();
      ctx.moveTo(0, midY);
      ctx.lineTo(width, midY);
      ctx.stroke();
      // Small diamond marker in center
      ctx.fillStyle = COMPACTION_COLOR;
      ctx.beginPath();
      ctx.moveTo(width / 2, midY - 3);
      ctx.lineTo(width / 2 + 3, midY);
      ctx.lineTo(width / 2, midY + 3);
      ctx.lineTo(width / 2 - 3, midY);
      ctx.closePath();
      ctx.fill();
    } else if (block.isInterruption) {
      const midY = y + blockH / 2;
      ctx.fillStyle = 'rgba(239, 68, 68, 0.15)';
      ctx.fillRect(0, y, width, blockH);
      ctx.strokeStyle = INTERRUPTION_COLOR;
      ctx.lineWidth = 2;
      ctx.setLineDash([]);
      ctx.beginPath();
      ctx.moveTo(0, midY);
      ctx.lineTo(width, midY);
      ctx.stroke();
      ctx.fillStyle = INTERRUPTION_COLOR;
      ctx.beginPath();
      ctx.moveTo(width / 2, midY - 3);
      ctx.lineTo(width / 2 + 3, midY);
      ctx.lineTo(width / 2, midY + 3);
      ctx.lineTo(width / 2 - 3, midY);
      ctx.closePath();
      ctx.fill();
    } else {
      ctx.fillStyle = MSG_COLORS[block.type] || '#d1d5db';
      // Draw slightly indented bars (like VS Code minimap lines)
      const indent = block.type === 'tool_call' || block.type === 'tool_result' ? 8 : 4;
      const barWidth = width - indent - 4;
      ctx.fillRect(indent, y, barWidth, Math.max(1, blockH - gap));
    }

    y += blockH + gap;
  }
}

export function updateViewport() {
  if (!minimapVisible) return;

  const panel = document.getElementById('message-panel');
  const viewport = document.getElementById('minimap-viewport');
  const minimap = document.getElementById('minimap');

  const scrollH = panel.scrollHeight;
  const clientH = panel.clientHeight;
  const scrollTop = panel.scrollTop;
  const minimapH = minimap.clientHeight;

  if (scrollH <= clientH) {
    // Everything visible, viewport covers all
    viewport.style.top = '0px';
    viewport.style.height = minimapH + 'px';
    return;
  }

  const viewportRatio = clientH / scrollH;
  const scrollRatio = scrollTop / (scrollH - clientH);

  const vpHeight = Math.max(8, viewportRatio * minimapH);
  const vpTop = scrollRatio * (minimapH - vpHeight);

  viewport.style.top = vpTop + 'px';
  viewport.style.height = vpHeight + 'px';
}

export function setupMinimapInteractions() {
  const minimap = document.getElementById('minimap');
  const panel = document.getElementById('message-panel');

  // Click to scroll
  minimap.addEventListener('mousedown', (e) => {
    e.preventDefault();
    isDragging = true;
    scrollToMinimapPosition(e);
  });

  document.addEventListener('mousemove', (e) => {
    if (!isDragging) return;
    e.preventDefault();
    scrollToMinimapPosition(e);
  });

  document.addEventListener('mouseup', () => {
    isDragging = false;
  });
}

function scrollToMinimapPosition(e) {
  const minimap = document.getElementById('minimap');
  const panel = document.getElementById('message-panel');
  const rect = minimap.getBoundingClientRect();
  const y = e.clientY - rect.top;
  const pct = Math.max(0, Math.min(1, y / rect.height));

  const maxScroll = panel.scrollHeight - panel.clientHeight;
  panel.scrollTop = pct * maxScroll;
}

export function hideMinimap() {
  document.getElementById('minimap').classList.add('hidden');
  minimapVisible = false;
}
