<template>
  <div
    v-if="fileContent"
    class="content-viewer"
    :class="{
      'dark-mode': preferences.darkMode,
      'line-wrap': preferences.lineWrap
    }"
  >
    <RecycleScroller
      v-if="displayLines.length > 1000"
      ref="virtualScroller"
      class="scroller"
      :items="displayLines"
      :item-size="lineHeight"
      key-field="lineNumber"
    >
      <template #default="{ item }">
        <div
          :data-line="item.lineNumber"
          :class="[
            'line',
            { selected: selectedLines.has(item.lineNumber) },
            { 'highlight-match': item.hasMatch },
            { 'current-result': isCurrentResult(item.lineNumber) }
          ]"
          @click="toggleLineSelection(item.lineNumber, $event)"
        >
          <span v-if="preferences.showLineNumbers" class="line-number">
            {{ item.lineNumber }}
          </span>
          <pre
            v-highlight="highlightConfig"
          ><code>{{ item.content }}</code></pre>
        </div>
      </template>
    </RecycleScroller>

    <div v-else class="lines-container">
      <div
        v-for="line in displayLines"
        :key="line.lineNumber"
        :data-line="line.lineNumber"
        :class="[
          'line',
          { selected: selectedLines.has(line.lineNumber) },
          { 'highlight-match': line.hasMatch },
          { 'current-result': isCurrentResult(line.lineNumber) }
        ]"
        @click="toggleLineSelection(line.lineNumber, $event)"
      >
        <span v-if="preferences.showLineNumbers" class="line-number">
          {{ line.lineNumber }}
        </span>
        <pre v-highlight="highlightConfig"><code>{{ line.content }}</code></pre>
      </div>
    </div>

    <div v-if="fileTooLarge" class="warning-banner">
      ⚠️ File exceeds 10,000 lines. Showing first 10,000 lines only. Use search
      or filters to find specific content.
    </div>
  </div>
</template>

<script setup>
import { computed, toRef, ref } from 'vue';
import { RecycleScroller } from 'vue-virtual-scroller';
import { useLineSelection } from '../../composables/useLineSelection.js';

const props = defineProps({
  displayLines: {
    type: Array,
    default: () => []
  },
  fileContent: {
    type: String,
    default: ''
  },
  selectedFile: {
    type: String,
    default: ''
  },
  fileTooLarge: {
    type: Boolean,
    default: false
  },
  preferences: {
    type: Object,
    default: () => ({
      darkMode: false,
      lineWrap: false,
      showLineNumbers: true
    })
  },
  searchResults: {
    type: Array,
    default: () => []
  },
  currentResultIndex: {
    type: Number,
    default: 0
  },
  highlightConfig: {
    type: Object,
    default: () => ({
      theme: 'github',
      language: 'json'
    })
  },
  lineHeight: {
    type: Number,
    default: 20
  },
  selectionState: {
    type: Object,
    default: null
  }
});

const displayLines = toRef(props, 'displayLines');
const fileContent = toRef(props, 'fileContent');
const selectedFile = toRef(props, 'selectedFile');

const virtualScroller = ref(null);

const internalSelectionState = useLineSelection(
  displayLines,
  fileContent,
  selectedFile
);
const activeSelectionState = computed(
  () => props.selectionState || internalSelectionState
);
const { selectedLines, toggleLineSelection } = activeSelectionState.value;

const isCurrentResult = lineNumber => {
  if (!props.searchResults.length) return false;
  const currentLine = props.searchResults[props.currentResultIndex] + 1;
  return lineNumber === currentLine;
};

defineExpose({
  selectedLines,
  toggleLineSelection,
  virtualScroller
});
</script>

<style scoped>
.content-viewer {
  border: 1px solid #ddd;
  border-radius: 8px;
  background: #ffffff;
  max-height: 70vh;
  overflow: hidden;
}

.content-viewer.dark-mode {
  background: #1e1e1e;
  border-color: #333;
  color: #eee;
}

.content-viewer.line-wrap pre {
  white-space: pre-wrap;
}

.scroller,
.lines-container {
  max-height: 65vh;
  overflow-y: auto;
  background: #ffffff;
}

.content-viewer.dark-mode .scroller,
.content-viewer.dark-mode .lines-container {
  background: #1e1e1e;
}

.line {
  display: flex;
  gap: 10px;
  padding: 2px 8px;
  font-size: 13px;
  cursor: pointer;
  background: #ffffff !important;
}

.content-viewer.dark-mode .line {
  background: #1e1e1e !important;
}

.line.selected {
  background: rgba(102, 126, 234, 0.15) !important;
}

.content-viewer.dark-mode .line.selected {
  background: rgba(102, 126, 234, 0.25) !important;
}

.line.highlight-match {
  background: rgba(255, 234, 0, 0.25) !important;
}

.content-viewer.dark-mode .line.highlight-match {
  background: rgba(255, 234, 0, 0.15) !important;
}

.line.current-result {
  outline: 2px solid #ff9800;
  background: rgba(255, 193, 7, 0.3) !important;
}

.content-viewer.dark-mode .line.current-result {
  background: rgba(255, 193, 7, 0.2) !important;
}

.line-number {
  width: 50px;
  text-align: right;
  color: #999;
  user-select: none;
  flex-shrink: 0;
}

.content-viewer.dark-mode .line-number {
  color: #666;
}

/* Force transparent backgrounds on all elements inside lines */
.line * {
  background: transparent !important;
}

.line pre {
  margin: 0;
  background: transparent !important;
  color: inherit;
}

.line pre code {
  background: transparent !important;
  color: inherit;
  padding: 0 !important;
}

/* Light mode syntax highlighting */
.content-viewer:not(.dark-mode) .line pre code {
  color: #24292e !important;
}

.content-viewer:not(.dark-mode) :deep(.hljs) {
  background: transparent !important;
  color: #24292e !important;
}

.content-viewer:not(.dark-mode) :deep(.hljs-attr),
.content-viewer:not(.dark-mode) :deep(.hljs-attribute) {
  color: #6f42c1 !important;
  background: transparent !important;
}

.content-viewer:not(.dark-mode) :deep(.hljs-string) {
  color: #032f62 !important;
  background: transparent !important;
}

.content-viewer:not(.dark-mode) :deep(.hljs-number) {
  color: #005a9c !important;
  background: transparent !important;
}

.content-viewer:not(.dark-mode) :deep(.hljs-literal) {
  color: #d73a49 !important;
  background: transparent !important;
}

/* Dark mode syntax highlighting */
.content-viewer.dark-mode :deep(.hljs) {
  background: transparent !important;
  color: #e1e4e8 !important;
}

.content-viewer.dark-mode :deep(.hljs-attr),
.content-viewer.dark-mode :deep(.hljs-attribute) {
  color: #79b8ff !important;
  background: transparent !important;
}

.content-viewer.dark-mode :deep(.hljs-string) {
  color: #85e89d !important;
  background: transparent !important;
}

.content-viewer.dark-mode :deep(.hljs-number) {
  color: #79b8ff !important;
  background: transparent !important;
}

.content-viewer.dark-mode :deep(.hljs-literal) {
  color: #f97583 !important;
  background: transparent !important;
}

.warning-banner {
  background: #fff3cd;
  border-top: 1px solid #ffc107;
  color: #856404;
  padding: 12px;
  text-align: center;
  font-weight: 600;
}

.content-viewer.dark-mode .warning-banner {
  background: #3d3400;
  color: #ffeb3b;
  border-color: #ffc107;
}

.warning-banner {
  padding: 8px 10px;
  font-size: 13px;
  background: #fff3cd;
  border-top: 1px solid #ffeeba;
  color: #856404;
}
</style>
