<script setup lang="ts">
import { computed } from "vue";
import type { DiffLine } from "@/composables/useAssist";

const props = defineProps<{
  diff: DiffLine[];
}>();

const CONTEXT_LINES = 3;
const MIN_COLLAPSE = 6; // Only collapse if there are more than this many consecutive equal lines

type CollapseMarker = { type: 'collapse'; count: number };
type DisplayItem = DiffLine | CollapseMarker;

const insertions = computed(() => props.diff.filter(l => l.type === 'insert').length);
const deletions = computed(() => props.diff.filter(l => l.type === 'delete').length);

const displayItems = computed<DisplayItem[]>(() => {
  const d = props.diff;
  if (!d.length) return [];

  // Mark which indices are within CONTEXT_LINES of a change
  const shown = new Set<number>();
  for (let i = 0; i < d.length; i++) {
    if (d[i].type !== 'equal') {
      for (let c = Math.max(0, i - CONTEXT_LINES); c <= Math.min(d.length - 1, i + CONTEXT_LINES); c++) {
        shown.add(c);
      }
    }
  }

  // If nothing changed, show all
  if (shown.size === 0) return d;

  const result: DisplayItem[] = [];
  let i = 0;
  while (i < d.length) {
    if (shown.has(i)) {
      result.push(d[i]);
      i++;
    } else {
      let count = 0;
      while (i < d.length && !shown.has(i)) { count++; i++; }
      if (count >= MIN_COLLAPSE) {
        result.push({ type: 'collapse', count });
      } else {
        // Too short to collapse — show as-is
        for (let k = i - count; k < i; k++) result.push(d[k]);
      }
    }
  }
  return result;
});

function markerFor(type: DiffLine['type']): string {
  if (type === 'insert') return '+';
  if (type === 'delete') return '−';
  return ' ';
}
</script>

<template>
  <div class="diff-view-full">
    <div class="diff-summary-bar">
      <span class="diff-summary-ins">+{{ insertions }} insertion{{ insertions !== 1 ? 's' : '' }}</span>
      <span class="diff-summary-del">−{{ deletions }} deletion{{ deletions !== 1 ? 's' : '' }}</span>
    </div>
    <div class="diff-scroll">
      <div v-if="!diff.length" class="diff-empty">No changes.</div>
      <template v-for="(item, i) in displayItems" :key="i">
        <div v-if="item.type === 'collapse'" class="diff-line diff-collapse">
          <span class="diff-marker">⋯</span>
          <span class="diff-text">{{ item.count }} unchanged line{{ item.count !== 1 ? 's' : '' }}</span>
        </div>
        <div
          v-else
          :class="['diff-line', `diff-${item.type}`]"
        >
          <span class="diff-marker">{{ markerFor(item.type) }}</span>
          <span class="diff-text">{{ item.text }}</span>
        </div>
      </template>
    </div>
  </div>
</template>

<style scoped>
.diff-view-full {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  border: 1px solid var(--fs-border-color);
  border-radius: var(--fs-radius-sm);
  background: var(--fs-surface-page);
  overflow: hidden;
}

.diff-summary-bar {
  position: sticky;
  top: 0;
  flex-shrink: 0;
  display: flex;
  gap: 1rem;
  padding: 0.4rem 0.75rem;
  background: var(--fs-surface-raised);
  border-bottom: 1px solid var(--fs-border-color);
  font-size: 0.78rem;
  font-family: monospace;
  font-weight: 600;
}

.diff-summary-ins { color: var(--fs-success); }
.diff-summary-del { color: var(--fs-error); }

.diff-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 0.3rem 0;
}

.diff-empty {
  padding: 0.75rem;
  font-size: 0.85rem;
  color: var(--fs-text-tertiary);
}

.diff-line {
  display: flex;
  align-items: baseline;
  padding: 0.04rem 0.5rem;
  line-height: 1.55;
  font-family: monospace;
  font-size: 0.82rem;
}

.diff-delete {
  background: color-mix(in srgb, var(--fs-error) 12%, transparent);
  color: var(--fs-error);
}

.diff-insert {
  background: color-mix(in srgb, var(--fs-success) 12%, transparent);
  color: var(--fs-success);
}

.diff-equal {
  color: var(--fs-text-tertiary);
}

.diff-collapse {
  color: var(--fs-text-tertiary);
  opacity: 0.6;
  border-top: 1px dashed var(--fs-border-color);
  border-bottom: 1px dashed var(--fs-border-color);
  padding-top: 0.2rem;
  padding-bottom: 0.2rem;
}

.diff-marker {
  flex-shrink: 0;
  width: 1rem;
  text-align: center;
  user-select: none;
  font-weight: 700;
}

.diff-text {
  flex: 1;
  white-space: pre-wrap;
  word-break: break-word;
}
</style>
