<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { useGitApi } from '@/composables/git'
import { DiffViewer, FileTree, CommitList, BranchSelector, ProjectTree, FileViewer } from '@/components/git'
import { endpoints } from '@/config/endpoints'

type TabName = 'status' | 'history' | 'compare' | 'files'

const {
  status,
  commits,
  branches,
  currentBranch,
  diff,
  compareResult,
  selectedCommit,
  fileTree,
  fileContent,
  loading,
  error,
  fetchStatus,
  fetchDiff,
  fetchLog,
  fetchCommit,
  fetchBranches,
  compare,
  clearDiff,
  clearCompare,
  fetchFileTree,
  fetchFileContent,
  clearFileContent
} = useGitApi()

const activeTab = ref<TabName>('status')
const selectedFile = ref<string | null>(null)
const selectedStaged = ref<boolean>(false)
const expandedFiles = ref<Set<string>>(new Set())

// Compare tab state
const compareBase = ref('')
const compareHead = ref('')

// Files tab state
const selectedFilePath = ref<string | null>(null)

// Realtime WebSocket connection
let gitSocket: WebSocket | null = null
const isRealtime = ref(false)

function connectGitWatcher() {
  if (gitSocket?.readyState === WebSocket.OPEN) return

  gitSocket = new WebSocket(endpoints.terminal)

  gitSocket.onopen = () => {
    isRealtime.value = true
    console.log('[Git] Realtime connected')
  }

  gitSocket.onmessage = (event) => {
    try {
      const msg = JSON.parse(event.data)
      if (msg.type === 'git-change') {
        console.log('[Git] Change detected, refreshing...')
        refreshCurrentTab()
      }
    } catch {
      // Ignore non-JSON messages
    }
  }

  gitSocket.onclose = () => {
    isRealtime.value = false
    console.log('[Git] Realtime disconnected, reconnecting...')
    setTimeout(connectGitWatcher, 2000)
  }

  gitSocket.onerror = () => {
    isRealtime.value = false
  }
}

function disconnectGitWatcher() {
  if (gitSocket) {
    gitSocket.close()
    gitSocket = null
  }
}

async function refreshCurrentTab() {
  if (activeTab.value === 'status') {
    await fetchStatus()
    if (selectedFile.value) {
      await fetchDiff({ file: selectedFile.value, staged: selectedStaged.value })
    }
  } else if (activeTab.value === 'history') {
    await fetchLog(30)
  } else if (activeTab.value === 'files') {
    await fetchFileTree()
  }
}

// Load initial data
onMounted(async () => {
  await Promise.all([
    fetchStatus(),
    fetchLog(30),
    fetchBranches()
  ])
  // Load initial diff
  await fetchDiff()
  // Connect realtime watcher
  connectGitWatcher()
})

onUnmounted(() => {
  disconnectGitWatcher()
})

// Refresh when tab changes
watch(activeTab, async (tab) => {
  if (tab === 'status') {
    await fetchStatus()
    await fetchDiff()
  } else if (tab === 'history') {
    await fetchLog(30)
  } else if (tab === 'files') {
    await fetchFileTree()
  }
})

// Handle file selection in status tab
async function handleFileSelect(path: string, staged: boolean) {
  selectedFile.value = path
  selectedStaged.value = staged
  await fetchDiff({ file: path, staged })
}

// Select file from list
async function selectFile(path: string, staged: boolean) {
  selectedFile.value = path
  selectedStaged.value = staged
  await fetchDiff({ file: path, staged })
}

// Clear selection
function clearSelection() {
  selectedFile.value = null
  clearDiff()
}

// Handle commit selection in history tab
async function handleCommitSelect(sha: string) {
  await fetchCommit(sha)
}

// Load more commits
async function handleLoadMore() {
  await fetchLog(30, commits.value.length, true)
}

// Toggle file expansion in diff viewer
function toggleFile(path: string) {
  if (expandedFiles.value.has(path)) {
    expandedFiles.value.delete(path)
  } else {
    expandedFiles.value.add(path)
  }
  expandedFiles.value = new Set(expandedFiles.value)
}

// Run comparison
async function runCompare() {
  if (compareBase.value && compareHead.value) {
    await compare(compareBase.value, compareHead.value)
  }
}

// Refresh status
async function refresh() {
  await fetchStatus()
  await fetchDiff()
}

// Handle file selection in files tab
async function handleFileTreeSelect(path: string) {
  selectedFilePath.value = path
  await fetchFileContent(path)
}

// Close file viewer
function closeFileViewer() {
  selectedFilePath.value = null
  clearFileContent()
}

// Total changes count
const totalChanges = computed(() => {
  if (!status.value) return 0
  return status.value.staged.length + status.value.unstaged.length + status.value.untracked.length
})
</script>

<template>
  <div class="git-page">
    <!-- Sidebar -->
    <aside class="sidebar">
      <div class="sidebar-header">
        <h2>Git</h2>
        <div class="header-actions">
          <span :class="['realtime-indicator', { connected: isRealtime }]" :title="isRealtime ? 'Realtime: connected' : 'Realtime: disconnected'">
            <svg width="8" height="8" viewBox="0 0 8 8"><circle cx="4" cy="4" r="4" fill="currentColor"/></svg>
          </span>
          <button class="refresh-btn" @click="refresh" :disabled="loading" title="Refresh">
            <svg :class="{ spinning: loading }" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <path d="M21 12a9 9 0 1 1-6.219-8.56" />
            </svg>
          </button>
        </div>
      </div>

      <div class="branch-info">
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <line x1="6" y1="3" x2="6" y2="15" />
          <circle cx="18" cy="6" r="3" />
          <circle cx="6" cy="18" r="3" />
          <path d="M18 9a9 9 0 0 1-9 9" />
        </svg>
        <span class="branch-name">{{ currentBranch || 'No branch' }}</span>
        <span v-if="status?.ahead" class="ahead-behind">
          ↑{{ status.ahead }}
        </span>
        <span v-if="status?.behind" class="ahead-behind">
          ↓{{ status.behind }}
        </span>
      </div>

      <div v-if="activeTab === 'status' && status" class="file-tree-container">
        <FileTree
          :staged="status.staged"
          :unstaged="status.unstaged"
          :untracked="status.untracked"
          :selected-file="selectedFile"
          @select="handleFileSelect"
        />
      </div>
    </aside>

    <!-- Main content -->
    <main class="main-content">
      <!-- Tab bar -->
      <div class="tab-bar">
        <button
          :class="['tab', { active: activeTab === 'status' }]"
          @click="activeTab = 'status'"
        >
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
            <polyline points="14 2 14 8 20 8" />
          </svg>
          Status
          <span v-if="totalChanges > 0" class="tab-badge">{{ totalChanges }}</span>
        </button>
        <button
          :class="['tab', { active: activeTab === 'history' }]"
          @click="activeTab = 'history'"
        >
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <circle cx="12" cy="12" r="10" />
            <polyline points="12 6 12 12 16 14" />
          </svg>
          History
        </button>
        <button
          :class="['tab', { active: activeTab === 'compare' }]"
          @click="activeTab = 'compare'"
        >
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <line x1="18" y1="20" x2="18" y2="10" />
            <line x1="12" y1="20" x2="12" y2="4" />
            <line x1="6" y1="20" x2="6" y2="14" />
          </svg>
          Compare
        </button>
        <button
          :class="['tab', { active: activeTab === 'files' }]"
          @click="activeTab = 'files'"
        >
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" />
          </svg>
          Files
        </button>
      </div>

      <!-- Tab content -->
      <div class="tab-content">
        <!-- Status Tab -->
        <div v-if="activeTab === 'status'" class="status-tab">
          <div v-if="loading && !diff" class="loading-state">
            <div class="spinner"></div>
            Cargando...
          </div>
          <template v-else-if="status">
            <!-- Staged files -->
            <div v-if="status.staged.length > 0" class="file-section">
              <div class="section-header staged">
                <span class="section-dot"></span>
                <span class="section-label">Staged</span>
                <span class="section-count">{{ status.staged.length }}</span>
              </div>
              <div class="file-list">
                <div
                  v-for="file in status.staged"
                  :key="'staged-' + file.path"
                  :class="['file-row', { selected: selectedFile === file.path && selectedStaged }]"
                  @click="selectFile(file.path, true)"
                >
                  <span :class="['file-badge', file.status]">{{ file.status[0].toUpperCase() }}</span>
                  <span class="file-name">{{ file.path }}</span>
                </div>
              </div>
            </div>

            <!-- Unstaged files -->
            <div v-if="status.unstaged.length > 0" class="file-section">
              <div class="section-header unstaged">
                <span class="section-dot"></span>
                <span class="section-label">Unstaged</span>
                <span class="section-count">{{ status.unstaged.length }}</span>
              </div>
              <div class="file-list">
                <div
                  v-for="file in status.unstaged"
                  :key="'unstaged-' + file.path"
                  :class="['file-row', { selected: selectedFile === file.path && !selectedStaged }]"
                  @click="selectFile(file.path, false)"
                >
                  <span :class="['file-badge', file.status]">{{ file.status[0].toUpperCase() }}</span>
                  <span class="file-name">{{ file.path }}</span>
                </div>
              </div>
            </div>

            <!-- Untracked files -->
            <div v-if="status.untracked.length > 0" class="file-section">
              <div class="section-header untracked">
                <span class="section-dot"></span>
                <span class="section-label">Untracked</span>
                <span class="section-count">{{ status.untracked.length }}</span>
              </div>
              <div class="file-list">
                <div
                  v-for="file in status.untracked"
                  :key="'untracked-' + file"
                  class="file-row untracked-file"
                >
                  <span class="file-badge untracked">?</span>
                  <span class="file-name">{{ file }}</span>
                </div>
              </div>
            </div>

            <!-- Diff viewer for selected file -->
            <div v-if="selectedFile" class="diff-section">
              <div class="diff-header">
                <span class="diff-file-name">{{ selectedFile }}</span>
                <span class="diff-type">{{ selectedStaged ? '(staged)' : '(unstaged)' }}</span>
                <button class="close-diff" @click="clearSelection">✕</button>
              </div>
              <div v-if="loading" class="diff-loading">
                <div class="spinner"></div>
                Cargando diff...
              </div>
              <div v-else-if="diff?.files?.length">
                <DiffViewer
                  :files="diff.files"
                  :expanded-files="expandedFiles"
                  @toggle-file="toggleFile"
                />
              </div>
              <div v-else class="diff-empty">
                No hay cambios para mostrar
              </div>
            </div>

            <!-- Empty state when no changes -->
            <div v-if="!status.staged.length && !status.unstaged.length && !status.untracked.length" class="empty-state">
              <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
                <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" />
                <polyline points="22 4 12 14.01 9 11.01" />
              </svg>
              <p>Working directory clean</p>
              <span>No hay cambios pendientes</span>
            </div>
          </template>
          <div v-else class="empty-state">
            <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
              <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" />
              <polyline points="22 4 12 14.01 9 11.01" />
            </svg>
            <p>Working directory clean</p>
            <span>No hay cambios pendientes</span>
          </div>
        </div>

        <!-- History Tab -->
        <div v-if="activeTab === 'history'" class="history-tab">
          <div class="history-layout">
            <div class="commit-list-container">
              <CommitList
                :commits="commits"
                :selected-sha="selectedCommit?.sha"
                :loading="loading"
                @select="handleCommitSelect"
                @load-more="handleLoadMore"
              />
            </div>
            <div v-if="selectedCommit" class="commit-detail">
              <div class="commit-header">
                <h3>{{ selectedCommit.message }}</h3>
                <div class="commit-meta">
                  <span class="sha">{{ selectedCommit.shortSha }}</span>
                  <span>{{ selectedCommit.author }}</span>
                  <span>{{ new Date(selectedCommit.timestamp * 1000).toLocaleString() }}</span>
                </div>
                <p v-if="selectedCommit.body" class="commit-body">{{ selectedCommit.body }}</p>
              </div>
              <DiffViewer
                v-if="selectedCommit.files?.length"
                :files="selectedCommit.files"
                :expanded-files="expandedFiles"
                @toggle-file="toggleFile"
              />
            </div>
            <div v-else class="select-commit-hint">
              <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
                <circle cx="12" cy="12" r="10" />
                <line x1="12" y1="8" x2="12" y2="12" />
                <line x1="12" y1="16" x2="12.01" y2="16" />
              </svg>
              <p>Selecciona un commit para ver los detalles</p>
            </div>
          </div>
        </div>

        <!-- Compare Tab -->
        <div v-if="activeTab === 'compare'" class="compare-tab">
          <div class="compare-header">
            <BranchSelector
              :branches="branches"
              :selected="compareBase"
              label="Base"
              @select="compareBase = $event"
            />
            <span class="compare-arrow">→</span>
            <BranchSelector
              :branches="branches"
              :selected="compareHead"
              label="Head"
              @select="compareHead = $event"
            />
            <button
              class="compare-btn"
              :disabled="!compareBase || !compareHead || loading"
              @click="runCompare"
            >
              Comparar
            </button>
          </div>

          <div v-if="compareResult" class="compare-result">
            <div class="compare-stats">
              <span class="stat">
                <strong>{{ compareResult.stats.filesChanged }}</strong> archivos
              </span>
              <span class="stat additions">
                +{{ compareResult.stats.additions }}
              </span>
              <span class="stat deletions">
                -{{ compareResult.stats.deletions }}
              </span>
            </div>
            <DiffViewer
              :files="compareResult.files"
              :expanded-files="expandedFiles"
              @toggle-file="toggleFile"
            />
          </div>

          <div v-else-if="!compareBase || !compareHead" class="compare-hint">
            <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
              <line x1="18" y1="20" x2="18" y2="10" />
              <line x1="12" y1="20" x2="12" y2="4" />
              <line x1="6" y1="20" x2="6" y2="14" />
            </svg>
            <p>Selecciona dos ramas o commits para comparar</p>
          </div>
        </div>

        <!-- Files Tab -->
        <div v-if="activeTab === 'files'" class="files-tab">
          <div class="files-layout">
            <div class="file-tree-panel">
              <div class="panel-header">
                <span>Project Files</span>
                <button class="refresh-tree-btn" @click="fetchFileTree" :disabled="loading" title="Refresh">
                  <svg :class="{ spinning: loading }" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                    <path d="M21 12a9 9 0 1 1-6.219-8.56" />
                  </svg>
                </button>
              </div>
              <div class="tree-container">
                <ProjectTree
                  :nodes="fileTree"
                  :selected-path="selectedFilePath"
                  :loading="loading && !fileTree.length"
                  @select="handleFileTreeSelect"
                />
              </div>
            </div>
            <div class="file-content-panel">
              <FileViewer
                :file="fileContent"
                :loading="loading && selectedFilePath !== null"
                @close="closeFileViewer"
              />
            </div>
          </div>
        </div>
      </div>

      <!-- Error message -->
      <div v-if="error" class="error-message">
        {{ error }}
      </div>
    </main>
  </div>
</template>

<style scoped>
.git-page {
  display: flex;
  flex: 1;
  overflow: hidden;
  background: var(--bg-primary);
  color: var(--text-primary);
}

/* Sidebar */
.sidebar {
  width: 280px;
  background: var(--bg-secondary);
  border-right: 1px solid var(--border-color);
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
}

.sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem;
  border-bottom: 1px solid var(--border-color);
}

.sidebar-header h2 {
  font-size: 16px;
  font-weight: 600;
  margin: 0;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.realtime-indicator {
  color: var(--text-muted);
  opacity: 0.5;
  transition: all 0.3s;
}

.realtime-indicator.connected {
  color: #22c55e;
  opacity: 1;
  animation: pulse-glow 2s infinite;
}

@keyframes pulse-glow {
  0%, 100% { filter: drop-shadow(0 0 2px currentColor); }
  50% { filter: drop-shadow(0 0 6px currentColor); }
}

.refresh-btn {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  color: var(--text-secondary);
  cursor: pointer;
  transition: all 0.15s;
}

.refresh-btn:hover {
  background: var(--bg-hover);
  color: var(--text-primary);
}

.refresh-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.refresh-btn svg.spinning {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.branch-info {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 1rem;
  background: var(--bg-hover);
  font-size: 13px;
}

.branch-name {
  font-weight: 500;
}

.ahead-behind {
  font-size: 11px;
  color: var(--text-muted);
}

.file-tree-container {
  flex: 1;
  overflow-y: auto;
  padding: 0.5rem;
}

/* Main content */
.main-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* Tab bar */
.tab-bar {
  display: flex;
  gap: 0.25rem;
  padding: 0.5rem 1rem;
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border-color);
}

.tab {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  background: transparent;
  border: none;
  border-radius: 6px;
  color: var(--text-secondary);
  font-size: 13px;
  cursor: pointer;
  transition: all 0.15s;
}

.tab:hover {
  background: var(--bg-hover);
  color: var(--text-primary);
}

.tab.active {
  background: var(--accent);
  color: white;
}

.tab-badge {
  background: rgba(255, 255, 255, 0.2);
  padding: 0.1rem 0.4rem;
  border-radius: 10px;
  font-size: 11px;
}

.tab.active .tab-badge {
  background: rgba(255, 255, 255, 0.3);
}

/* Tab content */
.tab-content {
  flex: 1;
  overflow-y: auto;
  padding: 1rem;
}

/* File sections */
.file-section {
  margin-bottom: 1rem;
}

.section-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0;
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-secondary);
  border-bottom: 1px solid var(--border-color);
  margin-bottom: 0.25rem;
}

.section-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

.section-header.staged .section-dot {
  background: #22c55e;
}

.section-header.unstaged .section-dot {
  background: #eab308;
}

.section-header.untracked .section-dot {
  background: #6b7280;
}

.section-count {
  background: var(--bg-hover);
  padding: 0.1rem 0.4rem;
  border-radius: 10px;
  font-size: 11px;
}

.file-list {
  display: flex;
  flex-direction: column;
}

.file-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.5rem;
  cursor: pointer;
  border-radius: 4px;
  transition: background 0.15s;
}

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

.file-row.selected {
  background: rgba(99, 102, 241, 0.15);
}

.file-row.untracked-file {
  cursor: default;
  opacity: 0.7;
}

.file-badge {
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 3px;
  font-size: 11px;
  font-weight: 600;
  flex-shrink: 0;
}

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

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

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

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

.file-badge.untracked {
  background: rgba(107, 114, 128, 0.2);
  color: #6b7280;
}

.file-name {
  font-size: 13px;
  font-family: 'SF Mono', 'Fira Code', monospace;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Diff section */
.diff-section {
  margin-top: 1rem;
  border: 1px solid var(--border-color);
  border-radius: 8px;
  overflow: hidden;
}

.diff-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 0.75rem;
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border-color);
}

.diff-file-name {
  font-size: 13px;
  font-family: 'SF Mono', 'Fira Code', monospace;
  color: var(--text-primary);
}

.close-diff {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0.25rem;
  font-size: 14px;
}

.close-diff:hover {
  color: var(--text-primary);
}

.diff-type {
  font-size: 11px;
  color: var(--text-muted);
  flex: 1;
}

.diff-loading,
.diff-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 2rem;
  color: var(--text-muted);
  font-size: 13px;
}

/* Loading and empty states */
.loading-state,
.empty-state,
.select-commit-hint,
.compare-hint {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  padding: 3rem;
  color: var(--text-muted);
  text-align: center;
}

.empty-state svg,
.select-commit-hint svg,
.compare-hint svg {
  opacity: 0.5;
}

.empty-state p,
.select-commit-hint p,
.compare-hint p {
  font-size: 15px;
  color: var(--text-secondary);
  margin: 0;
}

.empty-state span {
  font-size: 13px;
}

.spinner {
  width: 24px;
  height: 24px;
  border: 2px solid var(--border-color);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

/* History tab */
.history-layout {
  display: grid;
  grid-template-columns: 350px 1fr;
  gap: 1rem;
  height: 100%;
}

.commit-list-container {
  border: 1px solid var(--border-color);
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg-secondary);
}

.commit-detail {
  overflow-y: auto;
}

.commit-header {
  padding: 1rem;
  border-bottom: 1px solid var(--border-color);
  margin-bottom: 1rem;
}

.commit-header h3 {
  margin: 0 0 0.5rem 0;
  font-size: 16px;
}

.commit-meta {
  display: flex;
  gap: 1rem;
  font-size: 12px;
  color: var(--text-muted);
}

.commit-meta .sha {
  font-family: 'SF Mono', 'Fira Code', monospace;
  color: var(--accent);
}

.commit-body {
  margin-top: 0.75rem;
  color: var(--text-secondary);
  font-size: 13px;
  white-space: pre-wrap;
}

/* Compare tab */
.compare-header {
  display: flex;
  align-items: flex-end;
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.compare-arrow {
  padding-bottom: 0.5rem;
  color: var(--text-muted);
  font-size: 18px;
}

.compare-btn {
  padding: 0.5rem 1.5rem;
  background: var(--accent);
  border: none;
  border-radius: 6px;
  color: white;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.15s;
}

.compare-btn:hover:not(:disabled) {
  filter: brightness(1.1);
}

.compare-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.compare-stats {
  display: flex;
  gap: 1.5rem;
  padding: 0.75rem 1rem;
  background: var(--bg-secondary);
  border-radius: 8px;
  margin-bottom: 1rem;
  font-size: 13px;
}

.stat {
  color: var(--text-secondary);
}

.stat.additions {
  color: #22c55e;
}

.stat.deletions {
  color: #ef4444;
}

/* Files tab */
.files-tab {
  height: 100%;
}

.files-layout {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: 1rem;
  height: 100%;
}

.file-tree-panel {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border-color);
  border-radius: 8px;
  background: var(--bg-secondary);
  overflow: hidden;
}

.panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border-color);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
}

.refresh-tree-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  background: transparent;
  border: none;
  border-radius: 4px;
  color: var(--text-muted);
  cursor: pointer;
  transition: all 0.15s;
}

.refresh-tree-btn:hover {
  background: var(--bg-hover);
  color: var(--text-primary);
}

.refresh-tree-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.refresh-tree-btn svg.spinning {
  animation: spin 1s linear infinite;
}

.tree-container {
  flex: 1;
  overflow-y: auto;
  padding: 0.5rem;
}

.file-content-panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* Error message */
.error-message {
  padding: 0.75rem 1rem;
  background: rgba(239, 68, 68, 0.1);
  border: 1px solid rgba(239, 68, 68, 0.3);
  border-radius: 6px;
  color: #ef4444;
  font-size: 13px;
  margin: 1rem;
}

/* Responsive */
@media (max-width: 1024px) {
  .sidebar {
    width: 240px;
  }

  .history-layout {
    grid-template-columns: 280px 1fr;
  }

  .files-layout {
    grid-template-columns: 240px 1fr;
  }
}

@media (max-width: 768px) {
  .git-page {
    flex-direction: column;
  }

  .sidebar {
    width: 100%;
    flex-shrink: 0;
    border-right: none;
    border-bottom: 1px solid var(--border-color);
  }

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

  .sidebar-header h2 {
    font-size: 14px;
  }

  .branch-info {
    padding: 0.4rem 0.75rem;
    font-size: 12px;
  }

  .file-tree-container {
    display: none;
  }

  .main-content {
    flex: 1;
    min-height: 0;
    overflow: hidden;
  }

  .tab-bar {
    padding: 0.4rem 0.5rem;
    gap: 0.25rem;
    flex-shrink: 0;
  }

  .tab {
    padding: 0.4rem 0.6rem;
    font-size: 11px;
    gap: 0.35rem;
  }

  .tab svg {
    width: 12px;
    height: 12px;
  }

  .tab-badge {
    padding: 0 0.3rem;
    font-size: 10px;
  }

  .file-section {
    margin-bottom: 0.75rem;
  }

  .section-header {
    padding: 0.4rem 0;
    font-size: 11px;
  }

  .file-row {
    padding: 0.35rem 0.4rem;
  }

  .file-badge {
    width: 16px;
    height: 16px;
    font-size: 10px;
  }

  .file-name {
    font-size: 12px;
  }

  .diff-header {
    padding: 0.4rem 0.5rem;
  }

  .diff-file-name {
    font-size: 11px;
  }

  .tab-content {
    flex: 1;
    padding: 0.5rem;
    overflow-y: auto;
    min-height: 0;
  }

  .history-layout {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    height: 100%;
  }

  .commit-list-container {
    max-height: 200px;
    flex-shrink: 0;
  }

  .commit-detail {
    flex: 1;
    overflow-y: auto;
    min-height: 0;
  }

  .commit-header {
    padding: 0.5rem;
  }

  .commit-header h3 {
    font-size: 13px;
    margin-bottom: 0.25rem;
  }

  .commit-meta {
    gap: 0.5rem;
    font-size: 11px;
  }

  .compare-header {
    flex-direction: column;
    gap: 0.5rem;
    align-items: stretch;
  }

  .compare-arrow {
    display: none;
  }

  .compare-btn {
    width: 100%;
    padding: 0.5rem;
  }

  .compare-stats {
    padding: 0.5rem;
    gap: 0.5rem;
    font-size: 12px;
  }

  .empty-state,
  .select-commit-hint,
  .compare-hint {
    padding: 1.5rem 0.75rem;
  }

  .empty-state svg,
  .select-commit-hint svg,
  .compare-hint svg {
    width: 32px;
    height: 32px;
  }

  .empty-state p,
  .select-commit-hint p,
  .compare-hint p {
    font-size: 13px;
  }

  .empty-state span {
    font-size: 12px;
  }

  .error-message {
    margin: 0.5rem;
    padding: 0.5rem;
    font-size: 12px;
  }

  .files-layout {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    height: 100%;
  }

  .file-tree-panel {
    max-height: 250px;
    flex-shrink: 0;
  }

  .panel-header {
    padding: 0.5rem 0.75rem;
    font-size: 12px;
  }

  .tree-container {
    padding: 0.25rem;
  }

  .file-content-panel {
    flex: 1;
    min-height: 0;
  }
}
</style>
