<template>
  <div class="text-viewer w-full h-full bg-white dark:bg-gray-900 relative">
    <!-- Toolbar -->
    <div v-if="mode === 'edit'" class="border-b border-gray-200 dark:border-gray-700 p-2 bg-gray-50 dark:bg-gray-800">
      <div class="flex items-center space-x-4">
        <!-- File Type Info -->
        <div class="flex items-center space-x-2">
          <Icon 
            :name="getFileTypeIcon(document.name)" 
            :class="['w-5 h-5', getFileTypeColor(document.name)]"
          />
          <span class="text-sm font-medium text-gray-700 dark:text-gray-300">
            {{ getFileTypeName(document.name) }}
          </span>
        </div>
        
        <!-- Text Options -->
        <div v-if="isPlainText" class="flex items-center space-x-2">
          <label class="text-sm text-gray-700 dark:text-gray-300">
            Word Wrap:
            <input
              v-model="wordWrap"
              type="checkbox"
              class="ml-1"
            />
          </label>
          
          <label class="text-sm text-gray-700 dark:text-gray-300">
            Line Numbers:
            <input
              v-model="showLineNumbers"
              type="checkbox"
              class="ml-1"
            />
          </label>
        </div>
      </div>
    </div>
    
    <!-- Content Area -->
    <div class="flex-1 flex overflow-hidden">
      <!-- Line Numbers -->
      <div 
        v-if="showLineNumbers && isPlainText"
        class="bg-gray-50 dark:bg-gray-800 border-r border-gray-200 dark:border-gray-600 px-2 py-4 text-right text-sm text-gray-500 dark:text-gray-400 font-mono select-none"
        :style="{ minWidth: lineNumberWidth + 'px' }"
      >
        <div
          v-for="lineNum in totalLines"
          :key="lineNum"
          class="leading-6"
        >
          {{ lineNum }}
        </div>
      </div>
      
      <!-- Text Content -->
      <div class="flex-1 overflow-auto">
        <!-- Markdown Preview -->
        <div 
          v-if="isMarkdown && mode === 'view'"
          class="prose dark:prose-invert max-w-none p-6"
          v-html="markdownHtml"
        ></div>
        
        <!-- JSON Formatted View -->
        <div 
          v-else-if="isJson && mode === 'view'"
          class="p-4"
        >
          <pre class="text-sm font-mono text-gray-800 dark:text-gray-200 whitespace-pre-wrap"><code>{{ formattedJson }}</code></pre>
        </div>
        
        <!-- CSV Table View -->
        <div 
          v-else-if="isCsv && mode === 'view'"
          class="p-4"
        >
          <div class="overflow-auto">
            <table class="min-w-full border-collapse border border-gray-300 dark:border-gray-600">
              <thead>
                <tr class="bg-gray-50 dark:bg-gray-800">
                  <th
                    v-for="(header, index) in csvHeaders"
                    :key="index"
                    class="border border-gray-300 dark:border-gray-600 px-3 py-2 text-left text-sm font-medium text-gray-900 dark:text-gray-100"
                  >
                    {{ header }}
                  </th>
                </tr>
              </thead>
              <tbody>
                <tr
                  v-for="(row, rowIndex) in csvRows"
                  :key="rowIndex"
                  :class="rowIndex % 2 === 0 ? 'bg-white dark:bg-gray-900' : 'bg-gray-50 dark:bg-gray-800'"
                >
                  <td
                    v-for="(cell, cellIndex) in row"
                    :key="cellIndex"
                    class="border border-gray-300 dark:border-gray-600 px-3 py-2 text-sm text-gray-700 dark:text-gray-300"
                  >
                    {{ cell }}
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
        
        <!-- Plain Text Editor/Viewer -->
        <div 
          v-else
          class="h-full"
        >
          <textarea
            v-if="mode === 'edit'"
            v-model="editableContent"
            @input="handleContentChange"
            @keydown="handleKeydown"
            class="w-full h-full p-4 border-none resize-none focus:outline-none bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 font-mono text-sm leading-6"
            :class="{
              'whitespace-pre-wrap': wordWrap,
              'whitespace-pre': !wordWrap
            }"
            :placeholder="getPlaceholderText()"
          ></textarea>
          
          <pre 
            v-else
            class="w-full h-full p-4 text-sm font-mono text-gray-800 dark:text-gray-200 leading-6 overflow-auto"
            :class="{
              'whitespace-pre-wrap': wordWrap,
              'whitespace-pre': !wordWrap
            }"
          >{{ displayContent }}</pre>
        </div>
      </div>
    </div>
    
    <!-- Status Bar -->
    <div class="border-t border-gray-200 dark:border-gray-700 p-2 bg-gray-50 dark:bg-gray-800">
      <div class="flex items-center justify-between text-xs text-gray-500 dark:text-gray-400">
        <div class="flex items-center space-x-4">
          <span>{{ formatFileSize(document.size) }}</span>
          <span>{{ totalLines }} lines</span>
          <span v-if="characterCount">{{ characterCount }} characters</span>
          <span v-if="wordCount">{{ wordCount }} words</span>
        </div>
        
        <div v-if="mode === 'edit'" class="flex items-center space-x-4">
          <span v-if="cursorPosition">Line {{ cursorPosition.line }}, Column {{ cursorPosition.column }}</span>
          <span>{{ fileEncoding }}</span>
        </div>
      </div>
    </div>
    
    <!-- Save Button (Edit Mode) -->
    <div v-if="mode === 'edit'" class="absolute bottom-4 right-4">
      <button
        @click="saveDocument"
        class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 flex items-center space-x-2 shadow-lg"
      >
        <Icon name="mdi:content-save" class="w-4 h-4" />
        <span>Save</span>
      </button>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, nextTick } from 'vue';

const props = defineProps({
  document: {
    type: Object,
    required: true
  },
  mode: {
    type: String,
    default: 'view' // 'view' | 'edit'
  },
  content: {
    type: String,
    default: ''
  }
});

const emit = defineEmits([
  'content-changed',
  'save-requested'
]);

// State
const editableContent = ref('');
const wordWrap = ref(true);
const showLineNumbers = ref(true);
const cursorPosition = ref({ line: 1, column: 1 });
const fileEncoding = ref('UTF-8');

// Computed properties
const fileExtension = computed(() => {
  return props.document.name?.split('.').pop()?.toLowerCase() || '';
});

const isMarkdown = computed(() => {
  return ['md', 'markdown'].includes(fileExtension.value);
});

const isJson = computed(() => {
  return fileExtension.value === 'json';
});

const isCsv = computed(() => {
  return fileExtension.value === 'csv';
});

const isPlainText = computed(() => {
  return ['txt', 'log', 'conf', 'ini'].includes(fileExtension.value);
});

const displayContent = computed(() => {
  return props.content || editableContent.value || '';
});

const totalLines = computed(() => {
  return displayContent.value.split('\n').length;
});

const characterCount = computed(() => {
  return displayContent.value.length;
});

const wordCount = computed(() => {
  return displayContent.value.trim().split(/\s+/).filter(word => word.length > 0).length;
});

const lineNumberWidth = computed(() => {
  return Math.max(totalLines.value.toString().length * 8 + 16, 40);
});

const markdownHtml = computed(() => {
  if (!isMarkdown.value) return '';
  
  // Simple markdown to HTML conversion (in real app, use a proper markdown library)
  let html = displayContent.value;
  
  // Headers
  html = html.replace(/^### (.*$)/gim, '<h3>$1</h3>');
  html = html.replace(/^## (.*$)/gim, '<h2>$1</h2>');
  html = html.replace(/^# (.*$)/gim, '<h1>$1</h1>');
  
  // Bold
  html = html.replace(/\*\*(.*)\*\*/gim, '<strong>$1</strong>');
  
  // Italic
  html = html.replace(/\*(.*)\*/gim, '<em>$1</em>');
  
  // Code
  html = html.replace(/`(.*?)`/gim, '<code>$1</code>');
  
  // Line breaks
  html = html.replace(/\n/gim, '<br>');
  
  return html;
});

const formattedJson = computed(() => {
  if (!isJson.value) return displayContent.value;
  
  try {
    const parsed = JSON.parse(displayContent.value);
    return JSON.stringify(parsed, null, 2);
  } catch (error) {
    return displayContent.value;
  }
});

const csvHeaders = computed(() => {
  if (!isCsv.value || !displayContent.value) return [];
  
  const lines = displayContent.value.split('\n');
  if (lines.length === 0) return [];
  
  return parseCsvLine(lines[0]);
});

const csvRows = computed(() => {
  if (!isCsv.value || !displayContent.value) return [];
  
  const lines = displayContent.value.split('\n').slice(1); // Skip header
  return lines.filter(line => line.trim()).map(line => parseCsvLine(line));
});

// Methods
const getFileTypeIcon = (fileName) => {
  const extension = fileName?.split('.').pop()?.toLowerCase();
  const iconMap = {
    txt: 'mdi:file-document-outline',
    md: 'mdi:language-markdown',
    markdown: 'mdi:language-markdown',
    json: 'mdi:code-json',
    xml: 'mdi:file-xml',
    csv: 'mdi:file-table',
    log: 'mdi:file-document',
    conf: 'mdi:file-cog',
    ini: 'mdi:file-cog',
    default: 'mdi:file-document-outline'
  };
  return iconMap[extension] || iconMap.default;
};

const getFileTypeColor = (fileName) => {
  const extension = fileName?.split('.').pop()?.toLowerCase();
  const colorMap = {
    txt: 'text-gray-500',
    md: 'text-purple-500',
    markdown: 'text-purple-500',
    json: 'text-yellow-500',
    xml: 'text-orange-500',
    csv: 'text-green-500',
    log: 'text-gray-500',
    conf: 'text-blue-500',
    ini: 'text-blue-500',
    default: 'text-gray-500'
  };
  return colorMap[extension] || colorMap.default;
};

const getFileTypeName = (fileName) => {
  const extension = fileName?.split('.').pop()?.toLowerCase();
  const nameMap = {
    txt: 'Plain Text',
    md: 'Markdown',
    markdown: 'Markdown',
    json: 'JSON',
    xml: 'XML',
    csv: 'CSV',
    log: 'Log File',
    conf: 'Configuration',
    ini: 'INI File',
    default: 'Text File'
  };
  return nameMap[extension] || nameMap.default;
};

const getPlaceholderText = () => {
  const typeNames = {
    txt: 'Enter your text here...',
    md: 'Write your markdown content...',
    json: 'Enter valid JSON...',
    csv: 'Enter CSV data...',
    default: 'Enter content...'
  };
  return typeNames[fileExtension.value] || typeNames.default;
};

const parseCsvLine = (line) => {
  // Simple CSV parser (in real app, use a proper CSV library)
  const result = [];
  let current = '';
  let inQuotes = false;
  
  for (let i = 0; i < line.length; i++) {
    const char = line[i];
    
    if (char === '"') {
      inQuotes = !inQuotes;
    } else if (char === ',' && !inQuotes) {
      result.push(current.trim());
      current = '';
    } else {
      current += char;
    }
  }
  
  result.push(current.trim());
  return result;
};

const formatFileSize = (size) => {
  if (typeof size === 'string') return size;
  if (!size) return '0 B';
  
  const units = ['B', 'KB', 'MB', 'GB'];
  let index = 0;
  while (size >= 1024 && index < units.length - 1) {
    size /= 1024;
    index++;
  }
  return `${size.toFixed(1)} ${units[index]}`;
};

const handleContentChange = () => {
  emit('content-changed', editableContent.value);
};

const handleKeydown = (event) => {
  if (event.ctrlKey && event.key === 's') {
    event.preventDefault();
    saveDocument();
  }
  
  // Update cursor position for status bar
  nextTick(() => {
    updateCursorPosition(event.target);
  });
};

const updateCursorPosition = (textarea) => {
  if (!textarea) return;
  
  const text = textarea.value.substring(0, textarea.selectionStart);
  const lines = text.split('\n');
  const line = lines.length;
  const column = lines[lines.length - 1].length + 1;
  
  cursorPosition.value = { line, column };
};

const saveDocument = () => {
  emit('save-requested');
};

// Watchers
watch(() => props.content, (newContent) => {
  editableContent.value = newContent || '';
});

// Lifecycle
onMounted(() => {
  editableContent.value = props.content || '';
});
</script>

<style scoped>
.text-viewer {
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
}

/* Markdown prose styling */
:deep(.prose) {
  max-width: none;
}

:deep(.prose h1) {
  font-size: 2rem;
  font-weight: bold;
  margin: 1.5rem 0 1rem 0;
}

:deep(.prose h2) {
  font-size: 1.5rem;
  font-weight: bold;
  margin: 1.25rem 0 0.75rem 0;
}

:deep(.prose h3) {
  font-size: 1.25rem;
  font-weight: bold;
  margin: 1rem 0 0.5rem 0;
}

:deep(.prose p) {
  margin: 0.75rem 0;
}

:deep(.prose code) {
  background: #f3f4f6;
  padding: 0.125rem 0.25rem;
  border-radius: 0.25rem;
  font-size: 0.875rem;
}

:deep(.prose strong) {
  font-weight: bold;
}

:deep(.prose em) {
  font-style: italic;
}

/* Custom scrollbars */
.text-viewer ::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

.text-viewer ::-webkit-scrollbar-track {
  background: #f1f5f9;
}

.text-viewer ::-webkit-scrollbar-thumb {
  background: #cbd5e1;
  border-radius: 4px;
}

.text-viewer ::-webkit-scrollbar-thumb:hover {
  background: #94a3b8;
}

/* Dark mode scrollbars */
.dark .text-viewer ::-webkit-scrollbar-track {
  background: #334155;
}

.dark .text-viewer ::-webkit-scrollbar-thumb {
  background: #475569;
}

.dark .text-viewer ::-webkit-scrollbar-thumb:hover {
  background: #64748b;
}

/* Table styling for CSV */
table {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
}

/* Ensure text area has proper font */
textarea {
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  tab-size: 4;
}

pre {
  tab-size: 4;
}
</style> 