import React, { useEffect, useId, useState } from "react";
import classNames from "classnames";

import { ArcIconSocialLinkedin } from "@arc-ui/icons/ArcIconSocialLinkedin";
import { ArcIconSocialX } from "@arc-ui/icons/ArcIconSocialX";
import { BtIconLink } from "@arc-ui/icons/BtIconLink";
import { BtIconEmailUnread } from "@arc-ui/icons/BtIconEmailUnread";
import { Heading } from "@arc-ui/components/Heading";
import { Icon } from "@arc-ui/components/Icon";
import { Text } from "@arc-ui/components/Text";
import { Rule } from "@arc-ui/components/Rule";
import { Link } from "@arc-ui/components/Link";
import { Tag } from "@arc-ui/components/Tag";
import { Toast, ToastNotification } from "@arc-ui/components/Toast";
import { VerticalSpace } from "@arc-ui/components/VerticalSpace";
import { Author } from "../Author";
import { type TextSection } from "./types/text-section";
import { type LinkSection } from "./types/link-section";
import { type Topic } from "./types/topic";
import { type Share } from "./types/share";
import { type ShareButton } from "./types/share-button";
import { type SidebarAuthor } from "./types/sidebar-author";
import { filterAttrs } from "@arc-ui/community-utils/filter-attrs";
import styles from "./ArticleSidebar.module.css";

/**
 * Use `ArticleSidebar` to provide additional information about the article.
 */
export const ArticleSidebar: React.FC<ArticleSidebarProps> = ({
  author,
  aboutSection,
  topics,
  share,
  additionalContent,
  linkSection,
  url: providedUrl,
  ...props
}) => {
  const id = useId();
  const [showToast, setShowToast] = useState(false);
  const [clientUrl, setClientUrl] = useState("");

  useEffect(() => {
    if (!providedUrl) setClientUrl(window.location.href);
  }, [providedUrl]);

  const url = providedUrl ?? clientUrl;

  const copyTextToClipBoard = async () => {
    await navigator.clipboard.writeText(url);
    setShowToast(true);
  };

  const shareButtons: ShareButton[] = share
    ? [
        {
          isButton: true,
          onClick: copyTextToClipBoard,
          icon: BtIconLink,
          ariaLabel: share.clipboardAriaLabel || "Copy url to clipboard",
        },
        {
          href: `mailto:?subject=${encodeURIComponent(share.articleTitle)}&body=${encodeURIComponent(url)}`,
          icon: BtIconEmailUnread,
          ariaLabel: share.emailAriaLabel || "Share by email",
        },
        ...(share.linkedin
          ? [
              {
                href: `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(url)}`,
                icon: ArcIconSocialLinkedin,
                ariaLabel: share.linkedInAriaLabel || "Share on LinkedIn",
              },
            ]
          : []),
        ...(share.x
          ? [
              {
                href: `https://twitter.com/intent/tweet?url=${encodeURIComponent(url)}`,
                icon: ArcIconSocialX,
                ariaLabel: share.xAriaLabel || "Share on x",
              },
            ]
          : []),
      ]
    : [];

  const hasTopContent = Boolean(author || aboutSection || additionalContent);

  const showShare = share && url;
  const hasBottomContent = Boolean(linkSection || topics || showShare);

  return (
    <div {...filterAttrs(props)}>
      <div
        className={classNames({
          [styles.textContent]: hasTopContent,
        })}
      >
        {author && (
          <>
            <Author {...author} avatar={{ ...author.avatar, size: "xl" }} />
          </>
        )}

        {aboutSection && (
          <>
            {author && <VerticalSpace size="32" />}
            <Heading level={aboutSection.headingLevel}>
              {aboutSection.heading}
            </Heading>
            <VerticalSpace size="16" />

            <Text size="s">{aboutSection.content}</Text>
          </>
        )}

        {additionalContent && (
          <>
            {(author || aboutSection) && <VerticalSpace size="16" />}
            <div className={styles.additionalContentContainer}>
              {additionalContent.map(({ heading, headingLevel, content }) => (
                <div key={`${id}-${heading}`}>
                  <Heading level={headingLevel} size="xxs">
                    {heading}
                  </Heading>
                  <Text size="s">{content}</Text>
                </div>
              ))}
            </div>
          </>
        )}
      </div>

      {hasTopContent && hasBottomContent && (
        <div data-testid="text-content-rule">
          <VerticalSpace size="32" />
          <Rule />
          <VerticalSpace size="32" />
        </div>
      )}

      {linkSection && (
        <>
          <Heading level={linkSection.headingLevel}>
            {linkSection.heading}
          </Heading>

          {linkSection.links.map(({ text, url, ariaLabel }) => (
            <React.Fragment key={`${id}-${url}`}>
              <VerticalSpace size="8" />
              <div>
                <Link aria-label={ariaLabel} size="s" href={url}>
                  {text}
                </Link>
              </div>
            </React.Fragment>
          ))}
        </>
      )}

      {topics && (
        <>
          {linkSection && <VerticalSpace size="32" />}

          <Heading level={topics.headingLevel}>{topics.heading}</Heading>

          <VerticalSpace size="16" />

          <div className={styles.tagGroup}>
            {topics.tags.map((tag) => (
              <Tag key={`${id}-${tag.title}`} {...tag} />
            ))}
          </div>
        </>
      )}

      {showShare && (
        <>
          {(linkSection || topics) && (
            <div data-testid="links-topics-content-rule">
              <VerticalSpace size="32" />
              <Rule />
              <VerticalSpace size="32" />
            </div>
          )}

          <Heading level={share.headingLevel}>{share.heading}</Heading>

          <VerticalSpace size="16" />

          <div className={styles.shareButtonContainer}>
            {shareButtons.map(
              ({ isButton, ariaLabel, href, icon, onClick }) => (
                <a
                  key={`${id}-${ariaLabel}`}
                  role={isButton ? "button" : undefined}
                  target="_blank"
                  rel="noreferrer"
                  className={styles.shareButton}
                  aria-label={ariaLabel}
                  href={href}
                  onClick={isButton ? onClick : undefined}
                >
                  <Icon icon={icon} size={24} />
                </a>
              ),
            )}
          </div>
        </>
      )}

      <Toast>
        <ToastNotification
          status="success"
          title="Copied to clipboard"
          isOpen={showToast}
          onOpenChange={() => setShowToast(false)}
        />
      </Toast>
    </div>
  );
};

export interface ArticleSidebarProps {
  /**
   * Props for Author component.
   */
  author?: SidebarAuthor;

  /**
   * Content for the about section.
   */
  aboutSection?: TextSection;

  /**
   * Array of headings and text for additional text sections.
   */
  additionalContent?: TextSection[];

  /**
   * Links that are relevant to the article.
   */
  linkSection?: LinkSection;

  /**
   * Topics rendered as tags that are relevant to the article.
   */
  topics?: Topic;

  /**
   * Sharing options for the article.
   */
  share?: Share;

  /**
   * The article URL used by the share buttons.
   * If it is not provided, the component uses the current browser URL.
   */
  url?: string;
}
