import PropTypes from "prop-types";
import React, { ReactElement } from "react";

import HelpPopover from "../HelpPopover";
import Row from "../Form/Row";
import Item from "../Form/Item";

import classNames from "classnames";

export interface FieldsetProps {
    /** Adds spacing at the bottom. If used in a Form, make this to true. */
    bottomSpacing?: boolean;
    /** Children components. Should be Fieldset.Row or Fieldset.Item for proper spacing */
    children: ReactElement | ReactElement[];
    /** CSS class names. */
    className?: string;
    /** Description for Fieldset */
    description?: string;
    /** Indicates whether to include a help popover */
    helpIcon?: boolean;
    /** Indicates whether to include the "optional" tag to the fieldset */
    isOptional?: boolean;
    /** Indicates whether to include a required asterisk */
    isRequired?: boolean;
    /** Text for popover */
    popoverText?: string;
    /** Title for popover */
    popoverTitle?: string;
    testSection?: string;
    /** Title for Fieldset */
    title?: string;
    /** Size of Fieldset title*/
    titleSize?: "small" | "large";
}

const Fieldset = ({ // eslint-disable-line @typescript-eslint/explicit-function-return-type
    bottomSpacing,
    children,
    className,
    description,
    helpIcon,
    isOptional,
    isRequired,
    popoverText,
    popoverTitle,
    testSection,
    title,
    titleSize,
    ...props
}: FieldsetProps) => {
    const headerClasses = classNames({
        "push--bottom": titleSize === "large",
        "push-half--bottom": titleSize === "small",
        gamma: titleSize === "large",
        epsilon: titleSize === "small",
        "oui-label--required": isRequired,
    });
    const fieldsetClasses = classNames({
        "push-triple--bottom": bottomSpacing,
        "flush--bottom": !bottomSpacing,
    }, className);
    return (
        <fieldset data-test-section={testSection} className={fieldsetClasses} {...props}>
            {title && (
                <legend className={headerClasses}>
                    {title}
                    {isOptional && <label className="oui-label__optional">(Optional)</label>}
                    {helpIcon && (
                        <HelpPopover
                            popoverTitle={popoverTitle}
                            horizontalAttachment="left"
                            verticalAttachment="middle"
                        >
                            <p>{popoverText}</p>
                        </HelpPopover>
                    )}
                </legend>
            )}

            {description && <div className="push--bottom">{description}</div>}
            {children}
        </fieldset>
    );
};

Fieldset.Row = Row;
Fieldset.Item = Item;

Fieldset.propTypes = {
    /** Adds spacing at the bottom. If used in a Form, make this to true. */
    bottomSpacing: PropTypes.bool,
    /** Children components. Should be Fieldset.Row or Fieldset.Item for proper spacing */
    children: PropTypes.node.isRequired,
    /** CSS class names. */
    className: PropTypes.string,
    /** Description for Fieldset */
    description: PropTypes.node,
    /** Indicates whether to include a help popover */
    helpIcon: PropTypes.bool,
    /** Indicates whether to include the "optional" tag to the fieldset */
    isOptional: PropTypes.bool,
    /** Indicates whether to include a required asterisk */
    isRequired: PropTypes.bool,
    /** Text for popover */
    popoverText: PropTypes.string,
    /** Title for popover */
    popoverTitle: PropTypes.string,
    testSection: PropTypes.string,
    /** Title for Fieldset */
    title: PropTypes.string,
    /** Size of Fieldset title*/
    titleSize: PropTypes.oneOf(["small", "large"]),
};

Fieldset.defaultProps = {
    bottomSpacing: true,
    titleSize: "large",
};

export default Fieldset;
