/**
 * Diff 渲染工具
 * 功能：生成代码差异的 HTML 展示
 * 依赖：无
 * 使用场景：在变更面板中展示文件修改的 diff
 */

interface DiffLine {
  type: 'add' | 'remove' | 'context';
  content: string;
  oldLineNumber?: number;
  newLineNumber?: number;
}

/**
 * 简单的 diff 算法（基于行）
 */
export function generateDiff(oldContent: string, newContent: string): DiffLine[] {
  const oldLines = oldContent.split('\n');
  const newLines = newContent.split('\n');
  const result: DiffLine[] = [];

  let oldIndex = 0;
  let newIndex = 0;

  while (oldIndex < oldLines.length || newIndex < newLines.length) {
    const oldLine = oldLines[oldIndex];
    const newLine = newLines[newIndex];

    if (oldIndex >= oldLines.length) {
      // 只剩新行
      result.push({
        type: 'add',
        content: newLine,
        newLineNumber: newIndex + 1
      });
      newIndex++;
    } else if (newIndex >= newLines.length) {
      // 只剩旧行
      result.push({
        type: 'remove',
        content: oldLine,
        oldLineNumber: oldIndex + 1
      });
      oldIndex++;
    } else if (oldLine === newLine) {
      // 相同行
      result.push({
        type: 'context',
        content: oldLine,
        oldLineNumber: oldIndex + 1,
        newLineNumber: newIndex + 1
      });
      oldIndex++;
      newIndex++;
    } else {
      // 不同行，标记为删除和添加
      result.push({
        type: 'remove',
        content: oldLine,
        oldLineNumber: oldIndex + 1
      });
      result.push({
        type: 'add',
        content: newLine,
        newLineNumber: newIndex + 1
      });
      oldIndex++;
      newIndex++;
    }
  }

  return result;
}

/**
 * 将 diff 结果渲染为 HTML
 */
export function renderDiffHtml(diffLines: DiffLine[]): string {
  let html = '<div class="diff-viewer">';

  for (const line of diffLines) {
    const lineClass = `diff-line diff-line-${line.type}`;
    const oldNum = line.oldLineNumber ? `<span class="line-num">${line.oldLineNumber}</span>` : '<span class="line-num"></span>';
    const newNum = line.newLineNumber ? `<span class="line-num">${line.newLineNumber}</span>` : '<span class="line-num"></span>';
    const prefix = line.type === 'add' ? '+' : line.type === 'remove' ? '-' : ' ';
    const escapedContent = escapeHtml(line.content);

    html += `
      <div class="${lineClass}">
        ${oldNum}
        ${newNum}
        <span class="line-prefix">${prefix}</span>
        <span class="line-content">${escapedContent}</span>
      </div>
    `;
  }

  html += '</div>';
  return html;
}

/**
 * 转义 HTML 特殊字符
 */
function escapeHtml(text: string): string {
  const map: Record<string, string> = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#039;'
  };
  return text.replace(/[&<>"']/g, m => map[m]);
}

/**
 * 获取 diff 样式
 */
export function getDiffStyles(): string {
  return `
    .diff-viewer {
      font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
      font-size: 13px;
      line-height: 1.6;
      background: var(--vscode-editor-background);
      border: 1px solid var(--vscode-panel-border);
      border-radius: 6px;
      overflow: hidden;
    }

    .diff-line {
      display: flex;
      align-items: center;
      padding: 4px 0;
      white-space: pre;
      transition: background 0.15s;
    }

    .diff-line:hover {
      background: var(--vscode-list-hoverBackground);
    }

    .diff-line-add {
      background: rgba(40, 167, 69, 0.2);
      border-left: 3px solid #28a745;
    }

    .diff-line-add:hover {
      background: rgba(40, 167, 69, 0.25);
    }

    .diff-line-remove {
      background: rgba(220, 53, 69, 0.2);
      border-left: 3px solid #dc3545;
    }

    .diff-line-remove:hover {
      background: rgba(220, 53, 69, 0.25);
    }

    .diff-line-context {
      background: transparent;
      border-left: 3px solid transparent;
    }

    .line-num {
      display: inline-block;
      width: 45px;
      text-align: right;
      padding: 0 10px;
      color: var(--vscode-editorLineNumber-foreground);
      user-select: none;
      flex-shrink: 0;
      font-size: 11px;
      opacity: 0.7;
    }

    .line-prefix {
      display: inline-block;
      width: 24px;
      text-align: center;
      font-weight: bold;
      flex-shrink: 0;
      font-size: 14px;
    }

    .diff-line-add .line-prefix {
      color: #28a745;
    }

    .diff-line-remove .line-prefix {
      color: #dc3545;
    }

    .line-content {
      flex: 1;
      padding: 0 12px 0 8px;
      overflow-x: auto;
    }
  `;
}

