<template>
  <div class="status-box" v-if="isReady">
    <div class="status-actions">
      <!-- Linker Button -->
      <button 
        v-if="leftButton" 
        class="btn btn-small"
        :class="leftButton.class"
        @click="handleAction(leftButton.action)"
        :disabled="loading"
      >
        {{ leftButton.label }}
      </button>
      
      <!-- Rechter Button -->
      <button 
        v-if="rightButton" 
        class="btn btn-small btn-secondary"
        @click="handleAction(rightButton.action)"
        :disabled="loading"
      >
        {{ rightButton.label }}
      </button>
    </div>
    
    <div class="status-grid">
      <div class="row" v-for="(value, key) in displayRows" :key="key" :class="{ 'heading-row': value === null }">
        <span class="label">{{ key }}{{ value === null ? '' : ':' }}</span>
        <span class="value" v-if="value !== null">{{ value || '—' }}</span>
      </div>
    </div>
  </div>
  <div class="status-box loading" v-else>
    Lädt…
  </div>
</template>

<script setup>
import { onMounted, onBeforeUnmount, ref, computed } from 'vue'
import { useTimeStore } from '../stores/timeStore'
import { useAuthStore } from '../stores/authStore'
import { API_BASE_URL } from '@/config/api'

const API_URL = API_BASE_URL
const timeStore = useTimeStore()
const authStore = useAuthStore()
const stats = ref({})
const currentState = ref(null) // 'null', 'start work', 'start pause', 'stop pause'
const isReady = ref(false)
const loading = ref(false)
const workStartTime = ref(null) // Timestamp wann die Arbeit begonnen hat
const lastPauseStartTime = ref(null) // Timestamp der aktuellen Pause
const pauseDurations = ref([]) // Array von Pausen-Dauern in Millisekunden
const currentlyWorkedTime = ref('—') // Berechnete Arbeitszeit
const openTime = ref('—') // Berechnete offene Zeit
const regularEndTime = ref('—') // Berechnetes normales Arbeitsende
const serverWorkedTime = ref(null) // Vom Server berechnete Zeit
const serverOpenTime = ref(null) // Vom Server berechnete offene Zeit
const serverTimestamp = ref(null) // Wann die Server-Daten berechnet wurden
const missingBreakMinutes = ref(0) // Fehlende Pausenminuten
let dataFetchInterval = null // Daten vom Server laden
let displayUpdateInterval = null // Anzeige aktualisieren

const fetchStats = async () => {
  const data = await timeStore.fetchStats()
  stats.value = data || {}
  
  // Hole vom Server berechnete Arbeitszeit, offene Zeit und Timestamp
  if (data?.currentlyWorked) {
    serverWorkedTime.value = data.currentlyWorked
  } else {
    serverWorkedTime.value = null
  }
  
  if (data?.open) {
    serverOpenTime.value = data.open
  } else {
    serverOpenTime.value = null
  }
  
  if (data?.timestamp) {
    serverTimestamp.value = new Date(data.timestamp).getTime()
  }
  
  // Hole fehlende Pausenminuten
  if (data?.missingBreakMinutes !== undefined) {
    missingBreakMinutes.value = data.missingBreakMinutes
  } else {
    missingBreakMinutes.value = 0
  }
  
  isReady.value = true
}

/** Lädt Zustand, laufende Zeiten und Tages-Stats neu (z. B. nach Stempeln oder Zeitkorrektur). */
const refreshStatusData = async () => {
  await fetchCurrentState()
  await fetchWorklogData()
  await fetchStats()
}

const onWorklogUpdated = (e) => {
  // Nach Stempeln in dieser Komponente wurde bereits refreshStatusData ausgeführt
  if (e.detail?.fromStatusBoxClock) return
  void refreshStatusData()
}

const fetchCurrentState = async () => {
  try {
    const response = await fetch(`${API_URL}/time-entries/current-state`, {
      headers: authStore.getAuthHeaders()
    })
    
    if (response.ok) {
      const result = await response.json()
      currentState.value = result.state || null
    }
  } catch (error) {
    console.error('Fehler beim Laden des aktuellen Zustands:', error)
  }
}

// Lade die aktuellen Worklog-Daten (nur einmal pro Minute)
const fetchWorklogData = async () => {
  try {
    const response = await fetch(`${API_URL}/time-entries/running`, {
      headers: authStore.getAuthHeaders()
    })
    
    if (response.ok) {
      const result = await response.json()
      
      // Das Backend gibt direkt das Entry-Objekt zurück, nicht { entry: ... }
      if (result && result.startTime && (currentState.value === 'start work' || currentState.value === 'stop pause')) {
        // Arbeit läuft
        workStartTime.value = new Date(result.startTime).getTime()
        pauseDurations.value = result.pauses || []
        lastPauseStartTime.value = null
      } else if (result && result.startTime && currentState.value === 'start pause') {
        // In Pause
        workStartTime.value = new Date(result.startTime).getTime()
        pauseDurations.value = result.pauses || []
        // Hole letzten Pause-Start
        if (result.currentPauseStart) {
          lastPauseStartTime.value = new Date(result.currentPauseStart).getTime()
        }
      } else {
        // Nicht am Arbeiten
        workStartTime.value = null
        lastPauseStartTime.value = null
        pauseDurations.value = []
      }
    }
  } catch (error) {
    console.error('Fehler beim Laden der Worklog-Daten:', error)
  }
}

// Berechne die aktuell gearbeitete Zeit (2x pro Sekunde)
const updateCurrentlyWorkedTime = () => {
  // Wenn nicht am Arbeiten
  if (currentState.value === null || currentState.value === 'stop work') {
    currentlyWorkedTime.value = '—'
    return
  }
  
  // Verwende Server-Werte nur, wenn NICHT gearbeitet wird (oder kein laufender Start vorhanden)
  const shouldUseServerSummary = !workStartTime.value

  if (shouldUseServerSummary && serverWorkedTime.value && serverTimestamp.value) {
    // Parse Server-Zeit (HH:MM:SS)
    const parts = serverWorkedTime.value.split(':')
    const serverSeconds = parseInt(parts[0]) * 3600 + parseInt(parts[1]) * 60 + parseInt(parts[2])
    
    // Berechne vergangene Zeit seit Server-Timestamp
    const now = Date.now()
    const elapsedMs = now - serverTimestamp.value
    let elapsedSeconds = Math.floor(elapsedMs / 1000)
    
    // Wenn in Pause, zähle die Zeit nicht hoch
    if (currentState.value === 'start pause') {
      elapsedSeconds = 0
    }
    
    // Addiere vergangene Zeit
    const totalSeconds = serverSeconds + elapsedSeconds
    const hours = Math.floor(totalSeconds / 3600)
    const minutes = Math.floor((totalSeconds % 3600) / 60)
    const seconds = totalSeconds % 60
    
    currentlyWorkedTime.value = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
  } else {
    // Fallback/Standard: Aus Startzeit berechnen (bevorzugt bei laufender Arbeit)
    if (!workStartTime.value) {
      currentlyWorkedTime.value = '—'
      return
    }
    
    const now = Date.now()
    let totalWorkedMs = now - workStartTime.value
    
    // Ziehe abgeschlossene Pausen ab
    const totalPauseMs = pauseDurations.value.reduce((sum, duration) => sum + duration, 0)
    totalWorkedMs -= totalPauseMs
    
    // Wenn aktuell in Pause, ziehe die laufende Pause ab
    if (currentState.value === 'start pause' && lastPauseStartTime.value) {
      const currentPauseMs = now - lastPauseStartTime.value
      totalWorkedMs -= currentPauseMs
    }
    
    // Formatiere als HH:MM:SS
    const totalSeconds = Math.floor(totalWorkedMs / 1000)
    const hours = Math.floor(totalSeconds / 3600)
    const minutes = Math.floor((totalSeconds % 3600) / 60)
    const seconds = totalSeconds % 60
    
    currentlyWorkedTime.value = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
  }
}

// Berechne die offene Zeit (2x pro Sekunde)
const updateOpenTime = () => {
  // Wenn nicht am Arbeiten
  if (currentState.value === null || currentState.value === 'stop work') {
    openTime.value = '—'
    regularEndTime.value = '—'
    return
  }
  
  // Wenn wir einen Server-Wert haben, nutze diesen als Basis
  if (serverOpenTime.value && serverTimestamp.value) {
    // Parse Server-Zeit (HH:MM:SS)
    const parts = serverOpenTime.value.split(':')
    const serverSeconds = parseInt(parts[0]) * 3600 + parseInt(parts[1]) * 60 + parseInt(parts[2])
    
    // Berechne vergangene Zeit seit Server-Timestamp
    const now = Date.now()
    const elapsedMs = now - serverTimestamp.value
    let elapsedSeconds = Math.floor(elapsedMs / 1000)
    
    // Wenn in Pause, zähle die Zeit nicht runter (bleibt gleich)
    if (currentState.value === 'start pause') {
      elapsedSeconds = 0
    }
    
    // Subtrahiere vergangene Zeit (Offen wird weniger)
    const remainingSeconds = serverSeconds - elapsedSeconds
    
    if (remainingSeconds > 0) {
      const hours = Math.floor(remainingSeconds / 3600)
      const minutes = Math.floor((remainingSeconds % 3600) / 60)
      const seconds = remainingSeconds % 60
      
      openTime.value = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
      
      // Berechne "Normales Arbeitsende" = Jetzt + Offen (Pausen sind bereits in Offen enthalten)
      const totalRemainingSeconds = remainingSeconds
      const endTimestamp = now + (totalRemainingSeconds * 1000)
      const endDate = new Date(endTimestamp)
      const endHours = endDate.getHours()
      const endMinutes = endDate.getMinutes()
      const endSeconds = endDate.getSeconds()
      
      // Ausgabe ohne zusätzlichen Pausen-Hinweis; Zeit stammt bereits inkl. Pausen aus Backend
      regularEndTime.value = `${endHours.toString().padStart(2, '0')}:${endMinutes.toString().padStart(2, '0')}:${endSeconds.toString().padStart(2, '0')} Uhr`

      // Override: Berechne Normales Arbeitsende aus Server "open" Zeit
      // Nur überschreiben wenn wir Server-Daten haben
      if (serverOpenTime.value && serverTimestamp.value) {
        // Parse Server-Offen-Zeit
        const openParts = serverOpenTime.value.split(':')
        const openSeconds = parseInt(openParts[0]) * 3600 + parseInt(openParts[1]) * 60 + parseInt(openParts[2] || 0)
        
        // Berechne vergangene Zeit seit Server-Timestamp
        const now = Date.now()
        const elapsedMs = now - serverTimestamp.value
        let elapsedSeconds = Math.floor(elapsedMs / 1000)
        
        // Wenn in Pause, zähle die Zeit nicht
        if (currentState.value === 'start pause') {
          elapsedSeconds = 0
        }
        
        const remainingSeconds = openSeconds - elapsedSeconds
        
        if (remainingSeconds > 0) {
          const endTs = now + (remainingSeconds * 1000)
          const endDt = new Date(endTs)
          const eh = endDt.getHours()
          const em = endDt.getMinutes()
          const es = endDt.getSeconds()
          regularEndTime.value = `${eh.toString().padStart(2, '0')}:${em.toString().padStart(2, '0')}:${es.toString().padStart(2, '0')} Uhr`
        } else {
          regularEndTime.value = 'Erreicht'
        }
      }
    } else {
      openTime.value = 'Arbeitsende erreicht'
      
      // Auch wenn Arbeitsende erreicht ist, können noch Pausen fehlen
      if (missingBreakMinutes.value > 0) {
        regularEndTime.value = `Erreicht (+${missingBreakMinutes.value}min Pause)`
      } else {
        regularEndTime.value = 'Erreicht'
      }
    }
  } else {
    openTime.value = '—'
    regularEndTime.value = '—'
  }
}

const handleAction = async (action) => {
  try {
    loading.value = true
    
    const response = await fetch(`${API_URL}/time-entries/clock`, {
      method: 'POST',
      headers: {
        ...authStore.getAuthHeaders(),
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ action })
    })
    
    if (!response.ok) {
      const error = await response.json()
      alert(error.error || 'Fehler beim Stempeln')
      return
    }
    
    await refreshStatusData()
    window.dispatchEvent(
      new CustomEvent('worklog-updated', { detail: { fromStatusBoxClock: true } })
    )
    
  } catch (error) {
    console.error('Fehler beim Stempeln:', error)
    alert('Fehler beim Stempeln')
  } finally {
    loading.value = false
  }
}

// Button-Konfiguration basierend auf dem aktuellen Zustand
const leftButton = computed(() => {
  switch (currentState.value) {
    case null:
    case 'stop work':
      return { label: 'Arbeit beginnen', action: 'start work', class: 'btn-success' }
    case 'start work':
    case 'stop pause':
      return { label: 'Arbeit beenden', action: 'stop work', class: 'btn-danger' }
    case 'start pause':
      return null // Nicht sichtbar
    default:
      return null
  }
})

const rightButton = computed(() => {
  switch (currentState.value) {
    case null:
    case 'stop work':
      return null // Nicht sichtbar
    case 'start work':
    case 'stop pause':
      return { label: 'Pause beginnen', action: 'start pause' }
    case 'start pause':
      return { label: 'Pause beenden', action: 'stop pause' }
    default:
      return null
  }
})

// Event-Handler für Login
const handleLoginCompleted = async () => {
  await refreshStatusData()
}

onMounted(async () => {
  // Initiales Laden
  await refreshStatusData()
  window.addEventListener('worklog-updated', onWorklogUpdated)

  // Server-Daten alle 60 Sekunden neu laden
  dataFetchInterval = setInterval(async () => {
    await refreshStatusData()
  }, 60000)
  
  // Anzeige 2x pro Sekunde aktualisieren (nur Berechnung, keine Server-Requests)
  displayUpdateInterval = setInterval(() => {
    updateCurrentlyWorkedTime()
    updateOpenTime()
  }, 500)
  
  // Event-Listener für Login
  window.addEventListener('login-completed', handleLoginCompleted)
})

onBeforeUnmount(() => {
  if (dataFetchInterval) clearInterval(dataFetchInterval)
  if (displayUpdateInterval) clearInterval(displayUpdateInterval)
  window.removeEventListener('login-completed', handleLoginCompleted)
  window.removeEventListener('worklog-updated', onWorklogUpdated)
})

const displayRows = computed(() => {
  // Verwende Server-Wert für "Derzeit gearbeitet" wenn verfügbar (zeigt gesamte Tagesarbeitszeit)
  const workedDisplay = (stats.value?.currentlyWorked && stats.value.currentlyWorked !== '—') 
    ? stats.value.currentlyWorked + ' h'
    : (currentlyWorkedTime.value === '—' ? currentlyWorkedTime.value : currentlyWorkedTime.value + ' h');
  
  const rows = {
    'Derzeit gearbeitet': workedDisplay,
    'Offen': openTime.value === '—' || openTime.value.includes('erreicht') ? openTime.value : openTime.value + ' h',
    'Normales Arbeitsende': regularEndTime.value // Verwende berechneten Wert (hat bereits "Uhr")
  }
  
  // Füge andere Stats hinzu
  const map = [
    ['overtime', 'overtime'], // Label wird dynamisch gesetzt
    ['totalOvertime', 'totalOvertime'], // Label wird dynamisch gesetzt
    ['Wochenarbeitszeit', 'weekWorktime'],
    ['Arbeitsfreie Stunden', 'nonWorkingHours'],
    ['Offen für Woche', 'openForWeek'],
    ['Bereinigtes Arbeitsende (heute)', null], // Nur Überschrift, kein Wert
    ['- Generell', 'adjustedEndTodayGeneral'],
    ['- Woche', 'adjustedEndTodayWeek']
  ]

  for (const [label, key] of map) {
    // Spezialbehandlung für Überschrift ohne Wert
    if (key === null) {
      rows[label] = null // Überschrift ohne Wert (wird im Template speziell behandelt)
      continue
    }
    
    const val = stats.value?.[key]
    
    if (val !== undefined && val !== null && val !== '') {
      // Spezialbehandlung für Überstunden/Fehlzeit Labels
      if (key === 'overtime') {
        const isNegative = val.startsWith('-');
        const displayLabel = isNegative ? 'Fehlzeit (Woche)' : 'Überstunden (Woche)';
        const displayValue = isNegative ? val.substring(1) + ' h' : val + ' h'; // Entferne Minus-Zeichen, füge " h" hinzu
        rows[displayLabel] = displayValue;
      } else if (key === 'totalOvertime') {
        const isNegative = val.startsWith('-');
        const displayLabel = isNegative ? 'Fehlzeit (Gesamt)' : 'Überstunden (Gesamt)';
        const displayValue = isNegative ? val.substring(1) + ' h' : val + ' h'; // Entferne Minus-Zeichen, füge " h" hinzu
        rows[displayLabel] = displayValue;
      } else if (key === 'adjustedEndTodayGeneral' || key === 'adjustedEndTodayWeek') {
        // Füge " Uhr" zu Uhrzeiten hinzu (außer bei "Arbeitsende erreicht")
        rows[label] = val.includes('erreicht') ? val : val + ' Uhr';
      } else if (key === 'weekWorktime' || key === 'openForWeek' || key === 'nonWorkingHours') {
        // Füge " h" zu Zeiten hinzu (außer bei "—")
        rows[label] = val === '—' ? val : val + ' h';
      } else {
        rows[label] = val;
      }
    } else {
      rows[label] = '—'
    }
  }
  
  return rows
})
</script>

<style scoped>
.status-box {
  background: #ffffff;
  border: 1px solid #e0e0e0;
  border-radius: 6px;
  padding: 8px 10px;
  box-shadow: 0 2px 6px rgba(0,0,0,0.06);
  position: fixed;
  top: 58px;
  right: 24px;
  max-width: 560px;
  min-width: 280px;
  width: auto;
  height: auto;
  box-sizing: border-box;
  z-index: 1000;
}

.status-box.loading {
  min-width: 120px;
  text-align: center;
}

.status-actions {
  display: flex;
  gap: 6px;
  margin-bottom: 6px;
}

.btn {
  border: 1px solid #d0d0d0;
  background: #f8f8f8;
  color: #333;
  border-radius: 4px;
  padding: 6px 12px;
  cursor: pointer;
  font-size: 13px;
  transition: all 0.2s;
  flex: 1;
}

.btn:hover:not(:disabled) {
  background: #e8e8e8;
}

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

.btn-success {
  background: #d4edda;
  border-color: #c3e6cb;
  color: #155724;
  font-weight: 500;
}

.btn-success:hover:not(:disabled) {
  background: #c3e6cb;
}

.btn-danger {
  background: #f8d7da;
  border-color: #f5c6cb;
  color: #721c24;
  font-weight: 500;
}

.btn-danger:hover:not(:disabled) {
  background: #f5c6cb;
}

.btn-secondary {
  background: #e7f1ff;
  border-color: #b8daff;
  color: #004085;
}

.btn-secondary:hover:not(:disabled) {
  background: #b8daff;
}

.btn-small {
  padding: 6px 12px;
}

.status-grid { 
  font-size: 12px; 
  column-gap: 16px; 
}

.row { 
  display: grid; 
  grid-template-columns: 1fr auto; 
  align-items: baseline; 
  padding: 2px 0;
}

.row.heading-row {
  grid-template-columns: 1fr;
}

.row.heading-row .label {
  font-weight: 600;
  color: #333;
}

.label { 
  color: #555; 
}

.value { 
  color: #000; 
  font-weight: 500; 
}
</style>
