/* tdd-guard:skip — UI primitive, visual-tested via Vercel-Preview */
'use client'

// Sync indicator — small icon in app header. Click opens a popover with sync details.
// States: synced (green), pending (amber), syncing (blue spinner), failed (red).
// Popover rendert via React Portal (Header sticky+z-10 erzeugt eigenen Stacking-Context).

import { useRef, useState, useEffect } from 'react'
import { createPortal } from 'react-dom'
import { RefreshCw, Check, Clock, AlertCircle, Circle } from 'lucide-react'
import { useSyncStatus } from '@/lib/offline/sync-hooks'
import { useIsOnline } from '@/lib/offline/connection'

function formatRelative(iso: string): string {
  const diff = Math.round((Date.now() - new Date(iso).getTime()) / 1000)
  if (diff < 60) return 'gerade eben'
  if (diff < 3600) return `vor ${Math.round(diff / 60)} Min.`
  return `vor ${Math.round(diff / 3600)} Std.`
}

export default function SyncIndicator() {
  const { pendingCount, failedCount, isSyncing, lastSyncAt, triggerSync, triggerRetry } = useSyncStatus()
  const isOnline = useIsOnline()
  const [mounted, setMounted] = useState(false)
  const [open, setOpen] = useState(false)
  const [triggerRect, setTriggerRect] = useState<DOMRect | null>(null)
  const triggerRef = useRef<HTMLButtonElement>(null)
  const popoverRef = useRef<HTMLDivElement>(null)

  useEffect(() => setMounted(true), [])

  useEffect(() => {
    if (!open) return
    function updatePosition() {
      if (triggerRef.current) {
        setTriggerRect(triggerRef.current.getBoundingClientRect())
      }
    }
    updatePosition()
    window.addEventListener('resize', updatePosition)
    window.addEventListener('scroll', updatePosition, true)
    return () => {
      window.removeEventListener('resize', updatePosition)
      window.removeEventListener('scroll', updatePosition, true)
    }
  }, [open])

  useEffect(() => {
    function onOutside(e: MouseEvent) {
      const target = e.target as Node
      const insideTrigger = triggerRef.current?.contains(target)
      const insidePopover = popoverRef.current?.contains(target)
      if (!insideTrigger && !insidePopover) setOpen(false)
    }
    document.addEventListener('pointerdown', onOutside)
    return () => document.removeEventListener('pointerdown', onOutside)
  }, [])

  if (!mounted) {
    return (
      <div className="relative">
        <button className="w-8 h-8 flex items-center justify-center rounded-full hover:bg-muted transition-colors" title="Laden...">
          <Circle size={16} color="#94A3B8" />
        </button>
      </div>
    )
  }

  const hasFailed = failedCount > 0
  const hasPending = pendingCount > 0

  let iconColor = '#4ADE80'
  let statusLabel = 'Synchronisiert'
  type LucideIcon = typeof Check
  let IconComp: LucideIcon = Check

  if (!isOnline) {
    iconColor = '#94A3B8'
    statusLabel = 'Offline'
    IconComp = AlertCircle
  } else if (isSyncing) {
    iconColor = '#60A5FA'
    statusLabel = 'Wird synchronisiert…'
    IconComp = RefreshCw
  } else if (hasFailed) {
    iconColor = '#EF4444'
    statusLabel = `${failedCount} fehlgeschlagen`
    IconComp = AlertCircle
  } else if (hasPending) {
    iconColor = '#FBBF24'
    statusLabel = `${pendingCount} ausstehend`
    IconComp = Clock
  }

  const popover =
    open && triggerRect ? (
      <div
        ref={popoverRef}
        className="fixed w-64 bg-card border border-border rounded-sm shadow-lg z-[100] overflow-hidden text-foreground"
        style={{
          top: triggerRect.bottom + 8,
          right: Math.max(8, window.innerWidth - triggerRect.right),
        }}
      >
        <div className="px-4 py-3 border-b border-border flex items-center gap-2">
          <IconComp size={14} color={iconColor} className={isSyncing ? 'animate-spin' : ''} />
          <span className="text-sm font-semibold">{statusLabel}</span>
        </div>

        <div className="px-4 py-3 space-y-1.5 text-[12px]">
          <div className="flex justify-between">
            <span className="text-muted-foreground">Ausstehend</span>
            <span className="font-medium">{pendingCount}</span>
          </div>
          {hasFailed && (
            <div className="flex justify-between">
              <span className="text-muted-foreground">Fehlgeschlagen</span>
              <span className="font-medium text-[#EF4444]">{failedCount}</span>
            </div>
          )}
          <div className="flex justify-between">
            <span className="text-muted-foreground">Letzte Sync</span>
            <span className="font-medium">{lastSyncAt ? formatRelative(lastSyncAt) : '—'}</span>
          </div>
          {!isOnline && (
            <p className="text-[11px] text-amber-600 bg-amber-50 rounded-sm px-2 py-1 mt-1">
              Offline — Aenderungen werden gespeichert und synchronisiert, sobald Sie online sind.
            </p>
          )}
        </div>

        <div className="px-4 pb-3 pt-1 flex flex-col gap-1.5">
          <button
            onClick={() => { triggerSync(); setOpen(false) }}
            disabled={isSyncing || !isOnline}
            className="w-full h-8 bg-primary text-primary-foreground rounded-sm text-[12px] font-medium hover:bg-primary-dark disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
          >
            {isSyncing ? 'Wird synchronisiert…' : 'Jetzt synchronisieren'}
          </button>
          {hasFailed && isOnline && (
            <button
              onClick={() => { triggerRetry(); setOpen(false) }}
              className="w-full h-8 border border-[#EF4444]/30 text-[#EF4444] rounded-sm text-[12px] font-medium hover:bg-[#EF4444]/10 transition-colors"
            >
              Fehlgeschlagene wiederholen
            </button>
          )}
        </div>
      </div>
    ) : null

  return (
    <>
      <button
        ref={triggerRef}
        onClick={() => setOpen((v) => !v)}
        title={statusLabel}
        className="relative w-8 h-8 flex items-center justify-center rounded-full hover:bg-muted transition-colors"
      >
        <IconComp size={16} color={iconColor} className={isSyncing ? 'animate-spin' : ''} />
        {(hasPending || hasFailed) && !isSyncing && (
          <span
            className="absolute top-0.5 right-0.5 w-2 h-2 rounded-full border border-card"
            style={{ backgroundColor: hasFailed ? '#EF4444' : '#FBBF24' }}
          />
        )}
      </button>
      {popover && createPortal(popover, document.body)}
    </>
  )
}
