/**
 * Storefront announcement bar — fully driven by the merchant's dashboard.
 *
 * The merchant configures announcements in the Brainerce dashboard under
 *   Sell → Content → Announcement
 *
 * Everything below is generic rendering logic — it adapts automatically to
 * any announcement shape returned by the API, so **you should not hardcode
 * the message or severity here**.
 *
 * API contract:
 *   GET → client.content.announcement.list(locale) → Content<'ANNOUNCEMENT'>[]
 *   Empty array → renders nothing (page layout stays intact).
 *
 * Time-bounded: each announcement may have `startsAt` / `endsAt` ISO
 * timestamps. We filter client-side so the cached server response can be
 * shared across visitors regardless of the current time.
 */
'use client';

import * as React from 'react';
import { X } from 'lucide-react';
import type { Content } from 'brainerce';

interface AnnouncementBarProps {
  /** Pre-fetched list from the server. Pass `[]` to render nothing. */
  announcements: Content<'ANNOUNCEMENT'>[];
}

const SEVERITY_STYLES: Record<'info' | 'warning' | 'success', string> = {
  info: 'bg-blue-600 text-white',
  warning: 'bg-amber-500 text-amber-950',
  success: 'bg-emerald-600 text-white',
};

const STORAGE_KEY = 'brainerce_dismissed_announcements';

export function AnnouncementBar({ announcements }: AnnouncementBarProps) {
  const [dismissed, setDismissed] = React.useState<Set<string>>(() => new Set());

  // Hydrate dismissals from localStorage on mount (avoids SSR/CSR mismatch).
  React.useEffect(() => {
    if (typeof window === 'undefined') return;
    try {
      const raw = window.localStorage.getItem(STORAGE_KEY);
      if (raw) setDismissed(new Set(JSON.parse(raw) as string[]));
    } catch {
      // ignore malformed storage
    }
  }, []);

  const dismiss = (id: string) => {
    setDismissed((prev) => {
      const next = new Set(prev);
      next.add(id);
      if (typeof window !== 'undefined') {
        try {
          window.localStorage.setItem(STORAGE_KEY, JSON.stringify([...next]));
        } catch {
          // ignore quota errors
        }
      }
      return next;
    });
  };

  const now = Date.now();
  const visible = announcements.filter((a) => {
    if (dismissed.has(a.id)) return false;
    const startOk = !a.data.startsAt || new Date(a.data.startsAt).getTime() <= now;
    const endOk = !a.data.endsAt || new Date(a.data.endsAt).getTime() >= now;
    return startOk && endOk;
  });

  if (visible.length === 0) return null;

  return (
    <div role="region" aria-label="Site announcements">
      {visible.map((announcement) => {
        const severity = announcement.data.severity;
        const tone = SEVERITY_STYLES[severity] ?? SEVERITY_STYLES.info;
        return (
          <div
            key={announcement.id}
            className={`flex items-center justify-center gap-3 px-4 py-2 text-sm ${tone}`}
          >
            <span className="flex-1 text-center">
              {announcement.data.message}
              {announcement.data.ctaHref && announcement.data.ctaLabel ? (
                <>
                  {' '}
                  <a
                    href={announcement.data.ctaHref}
                    className="underline underline-offset-2"
                  >
                    {announcement.data.ctaLabel}
                  </a>
                </>
              ) : null}
            </span>
            {announcement.data.dismissible ? (
              <button
                type="button"
                onClick={() => dismiss(announcement.id)}
                aria-label="Dismiss announcement"
                className="text-current opacity-80 transition-opacity hover:opacity-100"
              >
                <X className="h-4 w-4" aria-hidden="true" />
              </button>
            ) : null}
          </div>
        );
      })}
    </div>
  );
}
