"use client";

import {
  isEffectivelyBlocking,
  validAnnouncementCtas,
} from "@enode/core/announcements/rules";
import type { Announcement } from "@enode/core/announcements/types";
import { useTranslation } from "@enode/core/translations/hooks";
import { BottomSheetCard } from "../bottom-sheet-card";
import { Button } from "../button";
import { AlertIcon, InfoIcon } from "../feedback/icons";

type Props = {
  /** The announcement to render. Keep passing it while `open` turns false so the slide-out still has content. */
  announcement: Announcement | null;
  open: boolean;
  /** The user closed a dismissible announcement (button, backdrop, Escape, Back). */
  onDismiss: () => void;
};

// Opens a CTA outside the app: a new tab in a browser. On a Capacitor build
// `window.open` is handed to the OS — like iOS `UIApplication.open` — so a
// store link lands in the App Store / Play Store (the notifications drawer
// opens its external links the same way). `mailto:` goes through
// `location.href`, which a browser hands to the mail client without leaving
// the page.
function openOutsideApp(url: string): void {
  if (url.startsWith("mailto:")) {
    window.location.href = url;
    return;
  }
  window.open(url, "_blank", "noopener,noreferrer");
}

/**
 * The one presentation for backend announcements (maintenance notices,
 * version and feature deprecations) in both apps — the web counterpart of the
 * native app's alert. Title, message, the CTA links, and a dismiss button.
 *
 * @remarks
 * - Copy is server-localized and rendered as-is; line breaks in the message
 *   are kept.
 * - A blocking announcement has no dismiss button and ignores backdrop,
 *   Escape and Back, and stays open after a CTA — the user has to act.
 *   A "blocking" one without a working CTA is shown dismissible instead
 *   (see `isEffectivelyBlocking`).
 * - Sits below `BlockingErrorDialog`, so an app-level failure still wins.
 */
export function AnnouncementDialog({ announcement, open, onDismiss }: Props) {
  const { t } = useTranslation();
  if (!announcement) return null;

  const blocking = isEffectivelyBlocking(announcement);
  const ctas = validAnnouncementCtas(announcement);

  const onCta = (url: string) => {
    openOutsideApp(url);
    if (!blocking) onDismiss();
  };

  return (
    <BottomSheetCard
      open={open}
      onClose={onDismiss}
      ariaLabel={announcement.title}
      zIndex={240}
      onDismissAttempt={blocking ? () => false : undefined}
      innerClassName="max-w-sm"
    >
      <div className="px-6 pb-2 pt-6 text-center">
        <div
          className={`mx-auto mb-4 flex size-12 items-center justify-center rounded-full ${
            blocking
              ? "bg-feedback-warning/10 text-feedback-warning"
              : "bg-foreground-default/10 text-foreground-default"
          }`}
        >
          {blocking ? (
            <AlertIcon className="size-6" />
          ) : (
            <InfoIcon className="size-6" />
          )}
        </div>
        <h2 className="heading-large">{announcement.title}</h2>
        <p className="body-normal mt-2 whitespace-pre-line text-foreground-muted">
          {announcement.message}
        </p>
        <div className="mt-6 flex flex-col gap-3">
          {ctas.map((cta, index) => (
            <Button
              key={`${index}-${cta.url}`}
              variant={index === 0 ? "primary" : "neutral"}
              size="large"
              onClick={() => onCta(cta.url)}
            >
              {cta.label}
            </Button>
          ))}
          {!blocking && (
            <Button
              variant={ctas.length > 0 ? "ghost" : "neutral"}
              size="large"
              onClick={onDismiss}
            >
              {announcement.dismissLabel.trim() || t("OK")}
            </Button>
          )}
        </div>
      </div>
    </BottomSheetCard>
  );
}
