<template>
  <div class="code-diff-viewer">
    <div v-if="!diff" class="code-diff-viewer__empty">
      <FileTextOutlined style="font-size: 32px; color: var(--text-placeholder)" />
      <p>暂无代码变更</p>
    </div>
    <div v-else class="code-diff-viewer__content">
      <div class="code-diff-viewer__header">
        <span class="code-diff-viewer__file">{{ diff.file }}</span>
        <span class="code-diff-viewer__stats">
          <span class="code-diff-viewer__added">+{{ diff.added }}</span>
          <span class="code-diff-viewer__removed">-{{ diff.removed }}</span>
        </span>
      </div>
      <div class="code-diff-viewer__lines">
        <div
          v-for="(line, idx) in diff.lines"
          :key="idx"
          :class="['code-diff-viewer__line', `code-diff-viewer__line--${line.type}`]"
        >
          <span class="code-diff-viewer__num">{{ line.num }}</span>
          <span class="code-diff-viewer__prefix">{{ line.prefix }}</span>
          <span class="code-diff-viewer__text">{{ line.text }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { FileTextOutlined } from '@ant-design/icons-vue'

export interface DiffLine {
  num: number
  type: 'context' | 'added' | 'removed'
  prefix: string
  text: string
}

export interface DiffData {
  file: string
  added: number
  removed: number
  lines: DiffLine[]
}

defineProps<{
  diff: DiffData | null
}>()
</script>

<style scoped>
.code-diff-viewer {
  height: 100%;
  overflow: auto;
  font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', Menlo, Consolas, monospace;
  font-size: var(--font-sm);
  background: var(--code-bg);
  color: var(--code-fg);
}

.code-diff-viewer__empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  gap: var(--space-3);
  color: var(--text-placeholder);
  font-family: inherit;
}

.code-diff-viewer__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-2) var(--space-3);
  background: rgba(0, 0, 0, 0.2);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  position: sticky;
  top: 0;
  z-index: 1;
}

.code-diff-viewer__file {
  color: var(--code-fg);
  font-weight: var(--font-weight-medium);
}

.code-diff-viewer__stats {
  display: flex;
  gap: var(--space-2);
  font-size: var(--font-xs);
}

.code-diff-viewer__added {
  color: var(--color-success);
}

.code-diff-viewer__removed {
  color: var(--color-error);
}

.code-diff-viewer__line {
  display: flex;
  min-height: 20px;
  line-height: 20px;
}

.code-diff-viewer__line--added {
  background: var(--code-added-bg);
}

.code-diff-viewer__line--removed {
  background: var(--code-removed-bg);
}

.code-diff-viewer__num {
  width: 48px;
  text-align: right;
  padding-right: var(--space-2);
  color: var(--code-comment);
  user-select: none;
  flex-shrink: 0;
}

.code-diff-viewer__prefix {
  width: 16px;
  text-align: center;
  flex-shrink: 0;
}

.code-diff-viewer__line--added .code-diff-viewer__prefix {
  color: var(--color-success);
}

.code-diff-viewer__line--removed .code-diff-viewer__prefix {
  color: var(--color-error);
}

.code-diff-viewer__text {
  flex: 1;
  white-space: pre;
  overflow-x: auto;
}
</style>
