import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';

import {
  checkForUpdate,
  IDLE_UPDATE_STATE,
  installUpdate,
  type UpdateState,
} from '../lib/appUpdates';
import { SparklesIcon, SpinnerIcon, XIcon } from './icons';

// Light-weight update UX: check once on mount, then every hour while the
// app is open. When an update exists show a toast with "Install & Restart"
// and a dismiss button. Dismiss is session-scoped — on next launch we check
// again.
export function UpdateToast() {
  const { t } = useTranslation(['app']);
  const [state, setState] = useState<UpdateState>(IDLE_UPDATE_STATE);
  const [dismissed, setDismissed] = useState(false);
  const [installing, setInstalling] = useState(false);
  const [progressPct, setProgressPct] = useState<number | null>(null);

  useEffect(() => {
    let cancelled = false;
    const run = async () => {
      const next = await checkForUpdate();
      if (!cancelled) setState(next);
    };
    void run();
    const id = window.setInterval(run, 60 * 60 * 1000);
    return () => {
      cancelled = true;
      window.clearInterval(id);
    };
  }, []);

  if (!state.available || dismissed) return null;

  const handleInstall = async () => {
    setInstalling(true);
    setProgressPct(0);
    try {
      await installUpdate((downloaded, total) => {
        if (total && total > 0) setProgressPct((downloaded / total) * 100);
      });
    } catch (err: unknown) {
      setState((s) => ({
        ...s,
        error: err instanceof Error ? err.message : 'install failed',
      }));
      setInstalling(false);
      setProgressPct(null);
    }
  };

  return (
    <div
      role="status"
      aria-live="polite"
      className="fixed bottom-6 left-6 z-50 w-80 overflow-hidden rounded-2xl border border-line bg-surface-3 p-4 shadow-2xl"
    >
      <div className="flex items-start gap-3">
        <div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-accent/20 text-accent">
          <SparklesIcon className="h-4 w-4" />
        </div>
        <div className="min-w-0 flex-1">
          <p className="text-sm font-semibold text-fg">
            {t('app:update.available', { defaultValue: 'Update verfügbar' })}
            {state.version ? ' · v' + state.version : ''}
          </p>
          {state.notes && (
            <p className="mt-0.5 line-clamp-6 whitespace-pre-line text-xs text-fg-muted">
              {state.notes}
            </p>
          )}
          {state.error && (
            <p className="mt-1 text-xs text-rose-500 dark:text-rose-300">{state.error}</p>
          )}
        </div>
        {!installing && (
          <button
            type="button"
            onClick={() => setDismissed(true)}
            aria-label={t('common:close', { defaultValue: 'Schließen' })}
            className="inline-flex h-6 w-6 cursor-pointer items-center justify-center rounded-md text-fg-muted transition hover:bg-surface-2 hover:text-fg"
          >
            <XIcon className="h-3.5 w-3.5" />
          </button>
        )}
      </div>
      <button
        type="button"
        onClick={() => void handleInstall()}
        disabled={installing}
        className="mt-3 inline-flex w-full cursor-pointer items-center justify-center gap-2 rounded-lg bg-accent px-3 py-2 text-sm font-semibold text-accent-fg transition hover:brightness-110 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent/60 disabled:cursor-not-allowed disabled:opacity-60"
      >
        {installing ? (
          <>
            <SpinnerIcon className="h-3.5 w-3.5" />
            <span>
              {progressPct != null
                ? t('app:update.downloading', { defaultValue: 'Lade…' }) +
                  ' ' +
                  Math.round(progressPct) +
                  '%'
                : t('app:update.installing', { defaultValue: 'Installiere…' })}
            </span>
          </>
        ) : (
          <span>{t('app:update.install', { defaultValue: 'Installieren & Neustarten' })}</span>
        )}
      </button>
    </div>
  );
}
