import { useEffect, useState } from 'react';
import { Cloud, CloudOff, RefreshCw, WifiOff, AlertTriangle } from 'lucide-react';
import { cloudUsername, pushBackup, pullBackup } from '@/lib/cloud/client';
import { useConnectivityStore } from '@/stores/connectivityStore';
import { Button } from '@/components/ui/Button';
import { cn } from '@/lib/cn';

/**
 * Compact shell indicator for connectivity + cloud sync. Shows "Offline" when
 * the browser is offline, otherwise the autosave state (saving / saved / failed)
 * while signed into the cloud. Renders nothing when online and not using cloud,
 * to keep the bar quiet. Also owns the online/offline event wiring.
 */
export function SyncStatusIndicator() {
  const online = useConnectivityStore((s) => s.online);
  const cloudSync = useConnectivityStore((s) => s.cloudSync);
  const setOnline = useConnectivityStore((s) => s.setOnline);
  const signedIn = !!cloudUsername();

  useEffect(() => {
    const on = () => setOnline(true);
    const off = () => setOnline(false);
    window.addEventListener('online', on);
    window.addEventListener('offline', off);
    setOnline(navigator.onLine);
    return () => { window.removeEventListener('online', on); window.removeEventListener('offline', off); };
  }, [setOnline]);

  if (!online) {
    return (
      <span className="flex items-center gap-1 rounded-md px-2 py-1 text-xs text-warning" title="You're offline — changes are saved locally and will sync when you reconnect." role="status">
        <WifiOff size={14} aria-hidden /> <span className="hidden sm:inline">Offline</span>
      </span>
    );
  }

  if (!signedIn) return null;

  if (cloudSync === 'conflict') return <ConflictResolver />;

  const map = {
    idle: null,
    conflict: null, // handled above
    saving: { Icon: RefreshCw, text: 'Saving…', cls: 'text-muted', spin: true, title: 'Saving your campaign to the cloud…' },
    saved: { Icon: Cloud, text: 'Saved', cls: 'text-success', spin: false, title: 'Your campaign is backed up to the cloud.' },
    error: { Icon: CloudOff, text: 'Sync failed', cls: 'text-danger', spin: false, title: 'Cloud sync failed — your data is safe locally and will retry on the next change.' },
  } as const;
  const s = map[cloudSync];
  if (!s) return null;

  return (
    <span className={cn('flex items-center gap-1 rounded-md px-2 py-1 text-xs', s.cls)} title={s.title} role="status" aria-live="polite">
      <s.Icon size={14} aria-hidden className={s.spin ? 'animate-spin' : undefined} />
      <span className="hidden sm:inline">{s.text}</span>
    </span>
  );
}

/**
 * Cloud changed on another device since this one last synced — resolve in one
 * click rather than silently clobbering. "Use cloud" pulls (overwrites local),
 * "Keep this device" force-pushes (overwrites cloud).
 */
function ConflictResolver() {
  const [open, setOpen] = useState(false);
  const [busy, setBusy] = useState(false);
  const setCloudSync = useConnectivityStore((s) => s.setCloudSync);

  const useCloud = async () => {
    setBusy(true);
    try { if (await pullBackup()) { setCloudSync('saved'); setTimeout(() => location.reload(), 400); } }
    finally { setBusy(false); setOpen(false); }
  };
  const keepMine = async () => {
    setBusy(true);
    try { await pushBackup({ force: true }); setCloudSync('saved'); }
    finally { setBusy(false); setOpen(false); }
  };

  return (
    <div className="relative">
      <button onClick={() => setOpen((o) => !o)} className="flex items-center gap-1 rounded-md px-2 py-1 text-xs text-warning hover:bg-elevated" title="The cloud copy changed on another device — click to resolve.">
        <AlertTriangle size={14} aria-hidden /> <span className="hidden sm:inline">Sync conflict</span>
      </button>
      {open && (
        <div className="absolute right-0 top-9 z-50 w-64 rounded-xl border border-line bg-panel p-3 text-sm shadow-xl">
          <p className="mb-2 text-muted">The cloud copy was changed on another device since this one last synced.</p>
          <div className="flex flex-col gap-1.5">
            <Button size="sm" variant="secondary" disabled={busy} onClick={() => void useCloud()}>Use cloud version (reload)</Button>
            <Button size="sm" variant="ghost" disabled={busy} onClick={() => void keepMine()}>Keep this device (overwrite cloud)</Button>
          </div>
        </div>
      )}
    </div>
  );
}
