import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
import { Children, createContext, forwardRef, isValidElement, useContext, useEffect, useRef, useState, } from 'react';
import styled from 'styled-components';
import { spacing, Stack, Wrap } from '../../spacing';
import { convertRemToPixels } from '../../utils';
import { Box } from '../box/Box';
import { Icon } from '../icon/Icon.component';
import { IconHelp } from '../IconHelper';
import { ScrollbarWrapper } from '../scrollbarwrapper/ScrollbarWrapper.component';
import { Text } from '../text/Text.component';
const DESCRIPTION_PREFIX = 'describe-';
const LABEL_PREFIX = 'label-';
const maxWidthTooltip = { maxWidth: '20rem' };
const StyledForm = styled.form `
  display: flex;
  flex-direction: column;
  align-items: stretch;
  height: 100%;
  background-color: ${(props) => props.layout.kind === 'page' && props.theme.backgroundLevel4};
`;
const BasicPageLayout = styled.div `
  margin: 0 auto;
  ${(props) => props.layoutKind === 'page'
    ? `
  width: 45rem;
  padding-right: ${spacing.f16};
  `
    : `
  width: 100%;
  padding-bottom: ${spacing.r24};`}
`;
const FixedHeader = styled(BasicPageLayout) `
  ${(props) => props.layoutKind === 'page'
    ? `
  border-bottom: 1px solid ${props.theme.border};
  `
    : ``}
`;
const FixedFooter = styled(BasicPageLayout) `
  border-top: 1px solid ${(props) => props.theme.border};
`;
const PaddedContent = styled.div `
  padding: ${spacing.f16} 0 ${spacing.f16} ${spacing.f16};
`;
const PaddedForHeaderAndFooterContent = styled.div `
  padding: ${spacing.f16};
`;
const ScrollArea = styled(BasicPageLayout) `
  flex-grow: 1;
  align-self: stretch;
  overflow-y: auto;
`;
const LabelContext = createContext(null);
const RequireModeContext = createContext('partial');
const FormGroup = ({ direction = 'horizontal', label, id, labelHelpTooltip, content, help, error, required, helpErrorPosition = 'right', disabled, }) => {
    const ctxt = useContext(LabelContext);
    if (!ctxt) {
        //intentionaly breaking rules of hooks here
        throw new Error('FormGroup cannot be used outside of Form');
    }
    const { maxLabelWidth, setMaxLabelWidth } = ctxt;
    const requireMode = useContext(RequireModeContext);
    const labelRef = useRef(null);
    useEffect(() => {
        if (labelRef.current) {
            const width = labelRef.current.getBoundingClientRect().width;
            setMaxLabelWidth((currentMaxLabelWidth) => {
                const additionalWdth = labelHelpTooltip ? convertRemToPixels(2) : 0;
                if (width + additionalWdth > currentMaxLabelWidth) {
                    return width + additionalWdth;
                }
                return currentMaxLabelWidth;
            });
        }
    }, [labelRef]);
    const value = {
        disabled: disabled || false,
        error: error || undefined,
    };
    return (_jsx(FieldContext.Provider, { value: value, children: _jsxs(Box, { display: "flex", flexDirection: direction === 'horizontal' ? 'row' : 'column', alignItems: "baseline", gap: direction === 'horizontal' ? spacing['r32'] : spacing['r4'], children: [_jsx("div", { style: {
                        width: maxLabelWidth === 0 ? 'max-content' : `${maxLabelWidth}px`,
                        flex: 'none',
                    }, children: _jsxs(Stack, { children: [_jsx("label", { htmlFor: id, id: `${LABEL_PREFIX}${id}`, ref: labelRef, style: { opacity: disabled ? 0.5 : 1 }, children: _jsxs(Text, { children: [label, requireMode !== 'all' && required && ' *', requireMode === 'all' && !required && ' (optional)'] }) }), labelHelpTooltip && (_jsx(IconHelp, { tooltipMessage: labelHelpTooltip, overlayStyle: maxWidthTooltip }))] }) }), _jsxs(Stack, { direction: helpErrorPosition === 'right' ? 'horizontal' : 'vertical', gap: helpErrorPosition === 'right' ? 'r8' : 'r4', children: [content, error ? (_jsx(Text, { variant: "Smaller", color: "statusCritical", isEmphazed: true, id: `${DESCRIPTION_PREFIX}${id}`, children: error })) : help ? (_jsx("div", { style: {
                                opacity: disabled ? 0.5 : 1,
                            }, children: _jsx(Text, { variant: "Smaller", color: "textSecondary", isEmphazed: true, id: `${DESCRIPTION_PREFIX}${id}`, children: help }) })) : (_jsx(Text, { variant: "Smaller", isEmphazed: true, children: "\u00A0" }))] })] }) }));
};
const FormSection = ({ children, title, forceLabelWidth, rightActions, }) => {
    const [maxLabelWidth, setMaxLabelWidth] = useState(forceLabelWidth || 0);
    //If all the formgroup are not required, add `(optional)` next to form section title.
    const groupNotOptional = Children.toArray(children).find((child) => isValidElement(child) ? child.props.required === true : false);
    return (_jsx(LabelContext.Provider, { value: { maxLabelWidth, setMaxLabelWidth }, children: _jsxs(Stack, { direction: "vertical", gap: "r12", children: [title && (_jsxs(Wrap, { children: [_jsxs(Stack, { direction: "horizontal", gap: "r8", children: [title.icon && _jsx(Icon, { name: title.icon, color: "textPrimary" }), _jsx(Text, { isEmphazed: true, children: groupNotOptional
                                        ? `${title.name}`
                                        : `${title.name} (optional)` }), title.helpTooltip && (_jsx(IconHelp, { tooltipMessage: title.helpTooltip, overlayStyle: maxWidthTooltip }))] }), _jsx("div", { children: rightActions })] })), children] }) }));
};
const PageForm = forwardRef(({ layout, leftActions, rightActions, children, banner, ...formProps }, ref) => {
    const requireMode = useContext(RequireModeContext);
    return (_jsx(ScrollbarWrapper, { children: _jsxs(StyledForm, { ...formProps, noValidate: true, ref: ref, layout: layout, children: [_jsx(FixedHeader, { layoutKind: "page", children: _jsx(PaddedForHeaderAndFooterContent, { children: _jsxs(Wrap, { children: [_jsxs(Stack, { direction: "vertical", children: [_jsxs(Text, { variant: "Larger", children: [layout.icon && (_jsx(Icon, { name: layout.icon, color: "textSecondary" })), ' ', layout.title] }), layout.subTitle && (_jsx(Text, { variant: "Large", isEmphazed: true, children: layout.subTitle }))] }), requireMode === 'partial' && (_jsx(Text, { color: "textSecondary", variant: "Smaller", style: { alignSelf: 'flex-end' }, isGentleEmphazed: true, children: "* are required fields" }))] }) }) }), _jsx(ScrollArea, { layoutKind: "page", children: _jsxs(PaddedContent, { children: [_jsx("div", { style: {
                                    paddingBottom: `${spacing.r16}`,
                                }, children: banner }), _jsx(Stack, { direction: "vertical", withSeparators: true, gap: "r24", children: Children.toArray(children) })] }) }), _jsx(FixedFooter, { layoutKind: "page", children: _jsx(PaddedForHeaderAndFooterContent, { children: _jsxs(Wrap, { children: [_jsx("div", { children: leftActions }), _jsx("div", { children: rightActions })] }) }) })] }) }));
});
const TabForm = forwardRef(({ leftActions, rightActions, children, banner, ...formProps }, ref) => {
    return (_jsx(ScrollbarWrapper, { children: _jsxs(StyledForm, { ...formProps, noValidate: true, ref: ref, children: [_jsx(FixedHeader, { layoutKind: "tab", children: _jsxs(Wrap, { children: [_jsx("div", { children: leftActions }), _jsx("div", { children: rightActions })] }) }), _jsx(ScrollArea, { layoutKind: "tab", children: _jsxs(Stack, { direction: "vertical", gap: "r24", children: [banner, _jsx(Stack, { direction: "vertical", withSeparators: true, gap: "r24", children: Children.toArray(children) })] }) })] }) }));
});
const Form = forwardRef(({ layout, requireMode, ...formProps }, ref) => {
    return (_jsx(RequireModeContext.Provider, { value: requireMode || 'partial', children: layout.kind === 'page' ? (_jsx(PageForm, { layout: layout, ...formProps, ref: ref })) : (_jsx(TabForm, { layout: layout, ...formProps, ref: ref })) }));
});
const FieldContext = createContext(null);
const useFieldContext = () => {
    const fieldContext = useContext(FieldContext);
    if (!fieldContext) {
        return { isContextAvailable: false };
    }
    return { ...fieldContext, isContextAvailable: true };
};
export { Form, FormSection, FormGroup, useFieldContext, DESCRIPTION_PREFIX, LABEL_PREFIX, };
