import type { ReactNode } from "react";
import "./activityFeed.css";

const defaultAvatarSrc = new URL("../assets/activity-feed-avatar.png", import.meta.url).href;

export type ActivityFeedItemType = "caption" | "slot";
export type ActivityFeedActionVariant = "primary" | "secondary";

export type ActivityFeedAction = {
  ariaLabel?: string;
  disabled?: boolean;
  href?: string;
  label: string;
  onClick?: () => void;
  variant?: ActivityFeedActionVariant;
};

export type ActivityFeedItemProps = {
  actions?: ActivityFeedAction[] | false;
  avatarAlt?: string;
  avatarSrc?: string;
  caption?: ReactNode;
  className?: string;
  hasActionButtons?: boolean;
  hasCaption?: boolean;
  hasLink?: boolean;
  hasStatus?: boolean;
  hasSupportText?: boolean;
  hasTimestamp?: boolean;
  hasTwoActionButtons?: boolean;
  label?: ReactNode;
  link?: ReactNode;
  dir?: "ltr" | "rtl";
  showLine?: boolean;
  showPaddingBottom?: boolean;
  slotContent?: ReactNode;
  supportText?: ReactNode;
  timestamp?: ReactNode;
  type?: ActivityFeedItemType;
};

export type ActivityFeedProps = {
  ariaLabel?: string;
  avatarSrc?: string;
  className?: string;
  dir?: "ltr" | "rtl";
  items?: ActivityFeedItemProps[];
};

function classes(...names: Array<string | false | undefined>) {
  return names.filter(Boolean).join(" ");
}

function StatusDot() {
  return (
    <span className="ds-activity-feed-item__status" aria-hidden="true" data-node-id="188:64134">
      <span data-node-id="188:64135" />
    </span>
  );
}

function Indicator({
  avatarAlt,
  avatarSrc,
  rtl,
  showLine,
  type,
}: {
  avatarAlt: string;
  avatarSrc: string;
  rtl: boolean;
  showLine: boolean;
  type: ActivityFeedItemType;
}) {
  const avatarNodeId = rtl ? (type === "caption" ? "587:18722" : "587:18703") : type === "caption" ? "584:18593" : "584:10955";

  return (
    <span className="ds-activity-feed-item__indicator" aria-hidden={avatarAlt ? undefined : "true"}>
      <span className="ds-activity-feed-item__avatar" data-node-id={avatarNodeId}>
        <img alt={avatarAlt} src={avatarSrc} />
      </span>
      {showLine && <span className="ds-activity-feed-item__line" />}
    </span>
  );
}

function ActionButton({ action }: { action: ActivityFeedAction }) {
  const className = classes("ds-activity-feed-item__button", `ds-activity-feed-item__button--${action.variant ?? "secondary"}`);

  if (action.href) {
    return (
      <a aria-label={action.ariaLabel} className={className} href={action.href}>
        {action.label}
      </a>
    );
  }

  return (
    <button
      aria-label={action.ariaLabel}
      className={className}
      disabled={action.disabled}
      onClick={action.onClick}
      type="button"
    >
      {action.label}
    </button>
  );
}

export function ActivityFeedItem({
  actions,
  avatarAlt = "",
  avatarSrc = defaultAvatarSrc,
  caption,
  className,
  hasActionButtons = true,
  hasCaption = true,
  hasLink = true,
  hasStatus = true,
  hasSupportText = true,
  hasTimestamp = true,
  hasTwoActionButtons = true,
  label,
  link,
  dir = "ltr",
  showLine = true,
  showPaddingBottom = true,
  slotContent,
  supportText,
  timestamp,
  type = "caption",
}: ActivityFeedItemProps) {
  const actionItems = actions === false || !hasActionButtons ? [] : (actions ?? []).slice(0, hasTwoActionButtons ? 2 : 1);
  const rtl = dir === "rtl";
  const nodeId = rtl ? (type === "caption" ? "587:18720" : "587:18701") : type === "caption" ? "584:18591" : "584:10411";

  const textParts = rtl
    ? [
        hasLink && link && <span className="ds-activity-feed-item__link" key="link">{link}</span>,
        hasSupportText && supportText && <span className="ds-activity-feed-item__support" key="support">{supportText}</span>,
        label && <strong key="label">{label}</strong>,
      ]
    : [
        label && <strong key="label">{label}</strong>,
        hasSupportText && supportText && <span className="ds-activity-feed-item__support" key="support">{supportText}</span>,
        hasLink && link && <span className="ds-activity-feed-item__link" key="link">{link}</span>,
      ];

  return (
    <article
      className={classes(
        "ds-activity-feed-item",
        `ds-activity-feed-item--${type}`,
        rtl ? "ds-activity-feed-item--rtl" : "ds-activity-feed-item--ltr",
        className,
      )}
      data-node-id={nodeId}
      dir={rtl ? "rtl" : "ltr"}
    >
      {!rtl && <Indicator avatarAlt={avatarAlt} avatarSrc={avatarSrc} rtl={rtl} showLine={showLine} type={type} />}

      <div className="ds-activity-feed-item__content">
        <div className="ds-activity-feed-item__container">
          <div className="ds-activity-feed-item__topline">
            {rtl && hasStatus && <StatusDot />}
            <div className="ds-activity-feed-item__text">{textParts}</div>
            {!rtl && hasStatus && <StatusDot />}
          </div>

          {type === "slot" ? (
            slotContent ? <div className="ds-activity-feed-item__slot">{slotContent}</div> : null
          ) : (
            hasCaption && caption && (
              <div className="ds-activity-feed-item__caption">{caption}</div>
            )
          )}
        </div>

        {hasTimestamp && timestamp && (
          <div className="ds-activity-feed-item__timestamp">{timestamp}</div>
        )}

        {actionItems.length > 0 && (
          <div className="ds-activity-feed-item__actions">
            {actionItems.map((action, index) => (
              <ActionButton action={action} key={`${action.label}-${index}`} />
            ))}
          </div>
        )}

        {showPaddingBottom && <div className="ds-activity-feed-item__bottom-space" aria-hidden="true" />}
      </div>

      {rtl && <Indicator avatarAlt={avatarAlt} avatarSrc={avatarSrc} rtl={rtl} showLine={showLine} type={type} />}
    </article>
  );
}

export function ActivityFeed({
  ariaLabel,
  avatarSrc = defaultAvatarSrc,
  className,
  dir = "ltr",
  items = [],
}: ActivityFeedProps) {
  const rtl = dir === "rtl";

  return (
    <section
      aria-label={ariaLabel}
      className={classes("ds-activity-feed", rtl ? "ds-activity-feed--rtl" : "ds-activity-feed--ltr", className)}
      data-node-id={rtl ? "587:19711" : "587:19381"}
      dir={rtl ? "rtl" : "ltr"}
    >
      {items.map((item, index) => (
        <ActivityFeedItem
          {...item}
          avatarSrc={item.avatarSrc ?? avatarSrc}
          key={index}
          dir={item.dir ?? dir}
        />
      ))}
    </section>
  );
}
