import type { ReactNode, Ref } from "react";
import { cx } from "../../utils";

export type FoxAlertType =
  | "default"
  | "information"
  | "success"
  | "warning"
  | "danger";

export interface FoxAlertProps {
  /**
   * 알림의 성격. 아이콘·배경·테두리·제목 색이 여기서 갈린다.
   *
   * 계열이 바꾸는 것은 배경 · 테두리 · 제목 글자색과 아이콘이다. 본문 글자색은 계열과
   * 무관하게 같다.
   *
   * 아이콘은 계열이 정하고 굵기는 시안대로 `duotone`이며, 색은 제목 글자와 같은 계열색이다.
   */
  type?: FoxAlertType;
  /** 굵은 제목 줄. 넘기지 않으면 영역을 렌더링하지 않는다. */
  title?: ReactNode;
  /** 제목 아래 본문. 넘기지 않으면 영역을 렌더링하지 않는다. */
  message?: ReactNode;
  /**
   * 보조기술이 읽는 방식을 정한다(`FoxToast`와 같은 규칙).
   *
   * - `false`(기본): `role="status"` — 하던 말을 끊지 않는다. 화면과 함께 처음부터 놓여
   *   있는 알림은 이쪽이다.
   * - `true`: `role="alert"` — 읽던 것을 끊고 바로 읽는다. 사용자의 동작 결과로 **그 자리에
   *   나타난** 알림에만 쓴다.
   *
   * `type="danger"`가 자동으로 이걸 켜지 않는다 — 위험한 내용인 것과 지금 끼어들어야 하는
   * 것은 다른 문제이고, 페이지와 함께 그려지는 경고까지 낭독을 끊으면 방해만 된다.
   */
  urgent?: boolean;
  /** 참이면 렌더하지 않는다(DOM에 남지 않는다). */
  hidden?: boolean;
  id?: string;
  /** 배치 조정용. 시안의 폭(720px)을 바꿔야 할 때도 여기로 준다. */
  className?: string;
  ref?: Ref<HTMLDivElement>;
}

/** `Record`로 고정해 계열을 추가하면 항목 누락이 타입 에러가 되게 한다. */
const TYPE_CLASS: Record<FoxAlertType, string> = {
  default: "fox-alert--default",
  information: "fox-alert--information",
  success: "fox-alert--success",
  warning: "fox-alert--warning",
  danger: "fox-alert--danger",
};

/**
 * 계열이 정하는 아이콘. 호출부가 넘기지 않는다 — 무엇을 그릴지는 계열이 이미 답한다
 * (`FoxTag`와 같은 규칙).
 *
 * 시안 `ico/*`가 Phosphor 원본이라 이름이 그대로 붙는다(`ico/Prohibit` →
 * `FoxProhibitIcon`). 손으로 SVG를 그려 넣지 않는다 — 아이콘은 생성물이 단일 출처다.
 *
 * 굵기는 시안이 `Weight=Duotone`이라 다섯 개 모두 `duotone`이다. 기본값(`regular`)으로 두면
 * 속이 빈 선 그림이 되어 시안과 달라지므로 반드시 적는다.
 *
 * duotone은 연한 면(`opacity` 0.2)과 진한 선을 겹쳐 그리는데 **둘 다 `currentColor`다** —
 * 색은 스타일이 `.fox-alert__icon`에 준 하나를 쓰고, 연한 쪽만 알아서 흐려진다.
 */
const TYPE_ICON: Record<FoxAlertType, ReactNode> = {
  default: <i className="fox-ico fox-ico--duotone fox-ico-ChatDots" aria-hidden="true" />,
  information: <i className="fox-ico fox-ico--duotone fox-ico-Info" aria-hidden="true" />,
  success: <i className="fox-ico fox-ico--duotone fox-ico-CheckCircle" aria-hidden="true" />,
  warning: <i className="fox-ico fox-ico--duotone fox-ico-Warning" aria-hidden="true" />,
  danger: <i className="fox-ico fox-ico--duotone fox-ico-Prohibit" aria-hidden="true" />,
};

/**
 * @fox 알럿. 화면 안에 놓이는 띠 모양 알림이다 — 아이콘 상자 · 제목 · 본문이 한 줄로 선다.
 *
 * **모달이 아니다.** 화면을 덮지도, 포커스를 가두지도, 확인 버튼을 갖지도 않는다. 내용 흐름
 * 안에 그대로 놓이고, 언제 나타나고 사라질지는 호출부가 정한다(`FoxToast`와 같은 방식).
 *
 * 상호작용이 없어 `"use client"`가 아니다 — 서버 컴포넌트로 렌더된다.
 *
 * ⚠️ 시안 주석: **본문은 두 줄 이내**로 쓴다. 길이를 코드가 막지는 않는다 — 세 줄이 되면
 * 아이콘 상자만 가운데 남고 띠가 늘어난다.
 *
 * ⚠️ 스타일은 이 파일이 import하지 않는다 — 호스트 앱이 `@use "@fox/styles/components"`
 * (또는 개별 파티셜)로 한 번 불러와야 한다.
 */
export function FoxAlert({
  type = "default",
  title,
  message,
  urgent = false,
  hidden = false,
  id,
  className,
  ref,
}: FoxAlertProps) {
  if (hidden) {
    return null;
  }

  return (
    <div
      ref={ref}
      id={id}
      role={urgent ? "alert" : "status"}
      className={cx("fox-alert", TYPE_CLASS[type], className)}
    >
      {/* 아이콘이 정해지기 전에도 상자는 그린다 — 시안이 흰 판을 배치의 일부로 준다. */}
      <span className="fox-alert__icon" aria-hidden="true">
        {TYPE_ICON[type]}
      </span>

      <div className="fox-alert__content">
        {title === undefined ? null : (
          <strong className="fox-alert__title">{title}</strong>
        )}
        {message === undefined ? null : (
          <span className="fox-alert__message">{message}</span>
        )}
      </div>
    </div>
  );
}
