import { Fragment, useState } from "react";

import { extendCommonStylesheet } from "@devowl-wp/web-cookie-banner";

import { useStylesheet } from "../../contexts/stylesheet.js";
import { useA11yId } from "../../hooks/useA11yId.js";

import type { DetailedHTMLProps, FC, HTMLAttributes, ReactNode } from "react";

const LinkToggle: FC<
    {
        onToggle?: (isOpen: boolean) => any;
        showMore: ReactNode;
        hideMore: ReactNode;
        /**
         * If the link is used multiple times with the same showMore and hideMore, you need to provide a group label
         * for better accessibility to make the group of links distinguishable for screen reader users (accessibility feature).
         */
        groupLabel?: string;
        bullets?: boolean;
        forceRender?: boolean;
    } & DetailedHTMLProps<HTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>
> = ({ onToggle, children, showMore, hideMore, groupLabel, bullets, forceRender, ...rest }) => {
    const { Link } = useStylesheet().extend(...extendCommonStylesheet);
    const [isOpen, setIsOpen] = useState(false);
    const a11yExpanded = useA11yId();

    return (
        <Fragment>
            {bullets && <span aria-hidden>&nbsp;&nbsp;&bull;&nbsp;&nbsp;</span>}
            <Link
                href="#"
                onClick={(e) => {
                    const newOpen = !isOpen;
                    setIsOpen(newOpen);
                    onToggle?.(newOpen);
                    e.preventDefault();
                }}
                onKeyDown={(e) => {
                    if (e.code.toLowerCase() === "space") {
                        (e.target as HTMLElement).click();
                    }
                }}
                {...(groupLabel
                    ? {
                          "aria-label": `${isOpen ? hideMore : showMore}: ${groupLabel}`,
                      }
                    : {})}
                {...(children
                    ? {
                          "aria-expanded": isOpen,
                          "aria-controls": a11yExpanded,
                          role: "button",
                      }
                    : {})}
                {...rest}
            >
                {isOpen ? hideMore : showMore}
            </Link>
            {children && (
                <div hidden={!isOpen} id={a11yExpanded}>
                    {(isOpen || forceRender) && children}
                </div>
            )}
        </Fragment>
    );
};

export { LinkToggle };
