<script setup lang="ts">
import { computed } from 'vue'
import type { FileDiff, DiffHunk } from '@/types/git'

const props = defineProps<{
  files: FileDiff[]
  expandedFiles?: Set<string>
}>()

const emit = defineEmits<{
  toggleFile: [path: string]
}>()

function isExpanded(path: string): boolean {
  return props.expandedFiles?.has(path) ?? true
}

function getStatusBadge(status: string) {
  const badges: Record<string, { label: string; class: string }> = {
    added: { label: 'A', class: 'badge-added' },
    modified: { label: 'M', class: 'badge-modified' },
    deleted: { label: 'D', class: 'badge-deleted' },
    renamed: { label: 'R', class: 'badge-renamed' }
  }
  return badges[status] || { label: '?', class: '' }
}

function getLineNumbers(hunk: DiffHunk) {
  let oldLine = hunk.oldStart
  let newLine = hunk.newStart

  return hunk.lines.map(line => {
    const result = {
      old: line.type === 'add' ? '' : oldLine,
      new: line.type === 'delete' ? '' : newLine
    }
    if (line.type !== 'add') oldLine++
    if (line.type !== 'delete') newLine++
    return result
  })
}
</script>

<template>
  <div class="diff-viewer">
    <div v-if="files.length === 0" class="empty-state">
      No hay cambios para mostrar
    </div>

    <div v-for="file in files" :key="file.path" class="file-diff">
      <div class="file-header" @click="emit('toggleFile', file.path)">
        <span :class="['status-badge', getStatusBadge(file.status).class]">
          {{ getStatusBadge(file.status).label }}
        </span>
        <span class="file-path">{{ file.path }}</span>
        <span v-if="file.oldPath" class="old-path">
          (from {{ file.oldPath }})
        </span>
        <svg v-if="file.isBinary" class="binary-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <rect x="2" y="3" width="20" height="18" rx="2" />
          <path d="M8 7v10M12 7v10M16 7v10" />
        </svg>
        <span class="toggle-icon">
          {{ isExpanded(file.path) ? '▼' : '▶' }}
        </span>
      </div>

      <div v-if="isExpanded(file.path) && !file.isBinary" class="file-content">
        <div v-for="(hunk, hunkIdx) in file.hunks" :key="hunkIdx" class="hunk">
          <div class="hunk-header">
            @@ -{{ hunk.oldStart }},{{ hunk.oldLines }} +{{ hunk.newStart }},{{ hunk.newLines }} @@
            <span v-if="hunk.header" class="hunk-context">{{ hunk.header }}</span>
          </div>
          <div class="hunk-lines">
            <div
              v-for="(line, lineIdx) in hunk.lines"
              :key="lineIdx"
              :class="['diff-line', `line-${line.type}`]"
            >
              <span class="line-number old">{{ getLineNumbers(hunk)[lineIdx].old }}</span>
              <span class="line-number new">{{ getLineNumbers(hunk)[lineIdx].new }}</span>
              <span class="line-prefix">{{ line.type === 'add' ? '+' : line.type === 'delete' ? '-' : ' ' }}</span>
              <span class="line-content">{{ line.content }}</span>
            </div>
          </div>
        </div>
      </div>

      <div v-else-if="file.isBinary" class="binary-notice">
        Archivo binario - no se puede mostrar diff
      </div>
    </div>
  </div>
</template>

<style scoped>
.diff-viewer {
  font-family: 'SF Mono', 'Fira Code', monospace;
  font-size: 13px;
  line-height: 1.5;
}

.empty-state {
  color: var(--text-muted);
  text-align: center;
  padding: 2rem;
}

.file-diff {
  border: 1px solid var(--border-color);
  border-radius: 8px;
  margin-bottom: 1rem;
  overflow: hidden;
}

.file-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 1rem;
  background: var(--bg-secondary);
  cursor: pointer;
  user-select: none;
}

.file-header:hover {
  background: var(--bg-hover);
}

.status-badge {
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
}

.badge-added {
  background: rgba(34, 197, 94, 0.2);
  color: #22c55e;
}

.badge-modified {
  background: rgba(234, 179, 8, 0.2);
  color: #eab308;
}

.badge-deleted {
  background: rgba(239, 68, 68, 0.2);
  color: #ef4444;
}

.badge-renamed {
  background: rgba(168, 85, 247, 0.2);
  color: #a855f7;
}

.file-path {
  color: var(--text-primary);
  flex: 1;
}

.old-path {
  color: var(--text-muted);
  font-size: 12px;
}

.binary-icon {
  color: var(--text-muted);
}

.toggle-icon {
  color: var(--text-muted);
  font-size: 10px;
}

.file-content {
  background: var(--bg-primary);
}

.hunk {
  border-top: 1px solid var(--border-color);
}

.hunk-header {
  padding: 0.5rem 1rem;
  background: var(--bg-hover);
  color: var(--accent);
  font-size: 12px;
}

.hunk-context {
  color: var(--text-muted);
  margin-left: 0.5rem;
}

.hunk-lines {
  overflow-x: auto;
}

.diff-line {
  display: flex;
  white-space: pre;
}

.line-number {
  min-width: 45px;
  padding: 0 0.5rem;
  text-align: right;
  color: var(--text-muted);
  background: var(--bg-secondary);
  user-select: none;
  border-right: 1px solid var(--border-color);
}

.line-number.old {
  border-right: none;
}

.line-prefix {
  width: 20px;
  text-align: center;
  user-select: none;
}

.line-content {
  flex: 1;
  padding-right: 1rem;
}

.line-context {
  background: transparent;
}

.line-add {
  background: rgba(34, 197, 94, 0.1);
}

.line-add .line-prefix,
.line-add .line-content {
  color: #22c55e;
}

.line-add .line-number.new {
  background: rgba(34, 197, 94, 0.15);
}

.line-delete {
  background: rgba(239, 68, 68, 0.1);
}

.line-delete .line-prefix,
.line-delete .line-content {
  color: #ef4444;
}

.line-delete .line-number.old {
  background: rgba(239, 68, 68, 0.15);
}

.binary-notice {
  padding: 1rem;
  color: var(--text-muted);
  text-align: center;
  font-style: italic;
}

@media (max-width: 768px) {
  .diff-viewer {
    font-size: 11px;
  }

  .file-header {
    padding: 0.5rem 0.75rem;
  }

  .file-path {
    font-size: 12px;
    word-break: break-all;
  }

  .status-badge {
    width: 18px;
    height: 18px;
    font-size: 10px;
  }

  .hunk-header {
    padding: 0.4rem 0.75rem;
    font-size: 11px;
  }

  .line-number {
    min-width: 32px;
    padding: 0 0.25rem;
    font-size: 10px;
  }

  .line-prefix {
    width: 16px;
  }

  .line-content {
    padding-right: 0.5rem;
  }
}
</style>
