// SPDX-License-Identifier: GPL-3.0-or-later

import { AlertTriangle, Download, X } from 'lucide-react';
import { useState } from 'react';
import { useUpdates } from '../contexts/UpdateContext';

/**
 * UpdateBanner is a persistent app-wide banner shown when:
 *
 *   1. The user has opted out of automatic updates. Falling behind on
 *      updates eventually breaks compatibility with the server, so we
 *      surface the consequence prominently rather than letting the user
 *      forget.
 *   2. The daemon has detected an update is available but auto-install
 *      has not yet completed (e.g. it ran while disabled). The user can
 *      click through to install on demand.
 *
 * It does not render at all when auto-updates are on AND no update is
 * pending — the common case is a silent banner-free experience.
 */
export default function UpdateBanner() {
  const { state, install } = useUpdates();
  const [busy, setBusy] = useState(false);
  const [dismissed, setDismissed] = useState(false);
  const [error, setError] = useState<string | null>(null);

  if (!state) return null;
  if (dismissed) return null;

  const optedOut = !state.auto_update;
  const hasUpdate = state.update_available;

  if (!optedOut && !hasUpdate) {
    return null;
  }

  const onInstall = async () => {
    setBusy(true);
    setError(null);
    try {
      await install();
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e));
    } finally {
      setBusy(false);
    }
  };

  if (optedOut) {
    return (
      <div className="bg-yellow-50 border-b border-yellow-200 dark:bg-yellow-900/30 dark:border-yellow-800">
        <div className="max-w-screen-xl mx-auto px-4 py-2.5 flex items-start gap-3 text-sm">
          <AlertTriangle className="h-5 w-5 text-yellow-600 dark:text-yellow-400 flex-shrink-0 mt-0.5" />
          <div className="flex-1 text-yellow-900 dark:text-yellow-100">
            <span className="font-medium">Automatic updates are disabled.</span>{' '}
            Older clients may be rejected by the server when the protocol changes,
            which can break backups and restores until you install a newer release.
            {hasUpdate && state.latest_version && (
              <span> A newer version ({state.latest_version}) is available now.</span>
            )}
            {error && <div className="mt-1 text-red-700 dark:text-red-400">{error}</div>}
          </div>
          {hasUpdate && (
            <button
              onClick={onInstall}
              disabled={busy}
              className="inline-flex items-center gap-1.5 px-3 py-1 rounded-md bg-yellow-600 text-white text-xs font-medium hover:bg-yellow-700 disabled:opacity-60"
            >
              <Download className="h-3.5 w-3.5" />
              {busy ? 'Installing…' : 'Install now'}
            </button>
          )}
          <button
            onClick={() => setDismissed(true)}
            aria-label="Dismiss"
            className="text-yellow-700 dark:text-yellow-300 opacity-60 hover:opacity-100"
          >
            <X className="h-4 w-4" />
          </button>
        </div>
      </div>
    );
  }

  // auto-update enabled but an update is pending (rare: usually applied silently)
  return (
    <div className="bg-blue-50 border-b border-blue-200 dark:bg-blue-900/30 dark:border-blue-800">
      <div className="max-w-screen-xl mx-auto px-4 py-2.5 flex items-start gap-3 text-sm">
        <Download className="h-5 w-5 text-blue-600 dark:text-blue-400 flex-shrink-0 mt-0.5" />
        <div className="flex-1 text-blue-900 dark:text-blue-100">
          <span className="font-medium">Update {state.latest_version} is ready to install.</span>{' '}
          The daemon will install it on its next poll, or you can apply it now.
          {error && <div className="mt-1 text-red-700 dark:text-red-400">{error}</div>}
        </div>
        <button
          onClick={onInstall}
          disabled={busy}
          className="inline-flex items-center gap-1.5 px-3 py-1 rounded-md bg-blue-600 text-white text-xs font-medium hover:bg-blue-700 disabled:opacity-60"
        >
          <Download className="h-3.5 w-3.5" />
          {busy ? 'Installing…' : 'Install now'}
        </button>
        <button
          onClick={() => setDismissed(true)}
          aria-label="Dismiss"
          className="text-blue-700 dark:text-blue-300 opacity-60 hover:opacity-100"
        >
          <X className="h-4 w-4" />
        </button>
      </div>
    </div>
  );
}
