import { useRef, useState } from 'react';
import { Card, CardContent, Text, Button, Popover, useElement, useOuterEvent, Flex, useI18n } from '@pega/cosmos-react-core';
import { ConditionBuilder, FieldCondition, AtomicCondition, getInitConditionForLhs, isValidCondition, formatCondition } from '@pega/cosmos-react-condition-builder';
import { demoFields, demoCondition, demoComparators, demoDateFunctions } from './props.mock';
import { StyledCodeBlock, StyledGrid, StyledList } from './ConditionBuilder.styles';
import { convertRhsTypes } from './ConditionBuilder.mocks';
export default {
    title: 'Condition Builder/ConditionBuilder',
    component: ConditionBuilder
};
export const DefaultBuilder = (args) => {
    const translate = useI18n();
    const [condition, setCondition] = useState(() => {
        const prevCondition = sessionStorage.getItem('CBDemoCondition');
        if (prevCondition !== null) {
            if (prevCondition === 'undefined') {
                return undefined;
            }
            return JSON.parse(prevCondition);
        }
        return demoCondition;
    });
    const buttonRef = useRef(null);
    const [isOpen, setIsOpen] = useState(false);
    const [popoverEl, setPopoverEl] = useElement(null);
    const hidePopover = () => {
        if (isOpen) {
            setIsOpen(false);
        }
    };
    useOuterEvent('mousedown', [popoverEl, buttonRef.current], hidePopover);
    const hideOnEscape = (e) => {
        if (e.key === 'Escape')
            hidePopover();
    };
    const handle = useRef(null);
    const builderJsx = (<>
      <ConditionBuilder fields={demoFields} condition={condition} validComparators={args.validComparators ? demoComparators : undefined} validRhsTypes={new Set(['LITERAL', 'FIELD', 'DATE_FUNCTION', 'RELATIVE_DATE', 'PARAMETER'])} dateFunctions={args.dateFunctions ? demoDateFunctions : undefined} disallowNOT={args.disallowNOT} handle={handle}/>
      <Flex container={{ justify: 'end' }}>
        <Button variant='primary' onClick={() => {
            if (handle?.current) {
                const [valid, newCondition] = handle.current.getCondition();
                if (valid) {
                    setCondition(newCondition);
                    hidePopover();
                    sessionStorage.setItem('CBDemoCondition', JSON.stringify(newCondition));
                }
            }
        }}>
          Submit
        </Button>
      </Flex>
    </>);
    return (<StyledGrid container={{
            cols: '1fr',
            rowGap: 3
        }}>
      {!args.renderInPopover && builderJsx}

      {args.renderInPopover && (<>
          <Button ref={buttonRef} aria-haspopup aria-expanded={isOpen} onClick={() => setIsOpen(!isOpen)} onKeyDown={hideOnEscape}>
            Open Condition builder
          </Button>

          <Popover show={isOpen} ref={setPopoverEl} target={buttonRef.current} placement='bottom-start'>
            <Flex container={{ pad: 1, direction: 'column' }}>{builderJsx}</Flex>
          </Popover>
        </>)}

      <div>
        <Text variant='h4'>Output:</Text>
        <StyledCodeBlock>
          {condition ? JSON.stringify(condition, null, 2) : '(No condition)'}
        </StyledCodeBlock>
      </div>

      <div>
        <Text variant='h4'>Formatted Output:</Text>
        <StyledCodeBlock>
          {condition ? formatCondition(condition, demoFields, translate) : '(No condition)'}
        </StyledCodeBlock>
      </div>
    </StyledGrid>);
};
DefaultBuilder.args = {
    validComparators: false,
    disallowNOT: false,
    renderInPopover: false,
    dateFunctions: true
};
DefaultBuilder.argTypes = {
    validComparators: { control: { type: 'boolean' } },
    disallowNOT: { control: { type: 'boolean' } },
    renderInPopover: { control: { type: 'boolean' } },
    dateFunctions: { control: { type: 'boolean' } }
};
export const FieldConditionDemo = (args) => {
    const translate = useI18n();
    const [condition, setCondition] = useState(undefined);
    const buttonRef = useRef(null);
    const [isOpen, setIsOpen] = useState(false);
    const [popoverEl, setPopoverEl] = useElement(null);
    const hidePopover = () => {
        if (isOpen) {
            setIsOpen(false);
        }
    };
    useOuterEvent('mousedown', [popoverEl, buttonRef.current], hidePopover);
    const hideOnEscape = (e) => {
        if (e.key === 'Escape')
            hidePopover();
    };
    const handle = useRef(null);
    const builderJsx = (<Flex container={{ direction: 'column', gap: 2 }}>
      <FieldCondition targetField='technicalDetails.lastActivityAt' fields={demoFields} condition={condition} validComparators={args.validComparators ? demoComparators : undefined} validRhsTypes={new Set(['LITERAL', 'FIELD', 'DATE_FUNCTION', 'RELATIVE_DATE'])} dateFunctions={args.dateFunctions ? demoDateFunctions : undefined} handle={handle}/>

      <Flex container={{ justify: 'end' }}>
        <Button name='field-condition-submit' variant='primary' onClick={() => {
            if (!handle.current)
                return;
            const [isValid, c] = handle.current.getCondition();
            if (!isValid)
                return;
            hidePopover();
            setCondition(c);
        }}>
          Submit
        </Button>
      </Flex>
    </Flex>);
    return (<StyledGrid container={{
            cols: 'repeat(2, minmax(0, 1fr))',
            justifyItems: 'stretch',
            alignItems: 'start',
            colGap: 4
        }}>
      {!args.renderInPopover && builderJsx}

      {args.renderInPopover && (<>
          <Button ref={buttonRef} aria-haspopup aria-expanded={isOpen} onClick={() => setIsOpen(!isOpen)} onKeyDown={hideOnEscape}>
            Open Condition builder
          </Button>

          <Popover show={isOpen} ref={setPopoverEl} target={buttonRef.current} placement='bottom-start'>
            <Flex container={{ pad: 1 }}>{builderJsx}</Flex>
          </Popover>
        </>)}

      <div>
        <Text variant='h4'>Output:</Text>
        <StyledCodeBlock>
          {condition ? JSON.stringify(condition, null, 2) : '(No condition)'}
        </StyledCodeBlock>

        <Text variant='h4'>Formatted Output:</Text>
        <StyledCodeBlock>
          {condition ? formatCondition({ condition }, demoFields, translate) : '(No condition)'}
        </StyledCodeBlock>
      </div>
    </StyledGrid>);
};
FieldConditionDemo.args = {
    validComparators: false,
    renderInPopover: false,
    dateFunctions: true
};
FieldConditionDemo.argTypes = {
    validComparators: { control: { type: 'boolean' } },
    renderInPopover: { control: { type: 'boolean' } },
    dateFunctions: { control: { type: 'boolean' } }
};
export const AtomicConditionDemo = (args) => {
    const translate = useI18n();
    const validRHSTypes = convertRhsTypes(!!args.useLiteralRHSType, !!args.useFieldRHSType, !!args.useRelativeDatesRHSType, !!args.useParameterRHSType, args.dateFunctions ? demoDateFunctions : undefined);
    const [submitCondition, setSubmitCondition] = useState(undefined);
    const buttonRef = useRef(null);
    const [isOpen, setIsOpen] = useState(false);
    const [popoverEl, setPopoverEl] = useElement(null);
    const hidePopover = () => {
        if (isOpen) {
            setIsOpen(false);
        }
    };
    useOuterEvent('mousedown', [popoverEl, buttonRef.current], hidePopover);
    const hideOnEscape = (e) => {
        if (e.key === 'Escape')
            hidePopover();
    };
    const [showErrorIndicators, setShowErrorIndicators] = useState(false);
    const [condition, setCondition] = useState(() => submitCondition ||
        getInitConditionForLhs({ field: 'details.age' }, demoFields, validRHSTypes, args.validComparators ? demoComparators : undefined, args.dateFunctions ? demoDateFunctions : undefined));
    const handleSubmission = () => {
        setShowErrorIndicators(false);
        if (isValidCondition(condition, demoFields, true)) {
            if (args.renderInPopover)
                setIsOpen(false);
            setSubmitCondition(condition);
        }
        else {
            setShowErrorIndicators(true);
        }
    };
    const atomicConditionJSX = (<Flex container={{ direction: 'column', gap: 2 }}>
      <AtomicCondition condition={condition} fields={demoFields} indicateErrors={showErrorIndicators} validComparators={args.validComparators ? demoComparators : undefined} dateFunctions={args.dateFunctions ? demoDateFunctions : undefined} onChange={c => setCondition(c)} itemDirection={args.itemDirection} lhsMode={args.lhsMode} validRhsTypes={validRHSTypes}/>
      <Flex container={{ justify: 'end' }}>
        <Button variant='primary' onClick={handleSubmission}>
          Submit
        </Button>
      </Flex>
    </Flex>);
    return (<StyledGrid container={{
            cols: 'repeat(2, minmax(0, 1fr))',
            justifyItems: 'stretch',
            alignItems: 'start',
            colGap: 4
        }}>
      {!args.renderInPopover && atomicConditionJSX}

      {args.renderInPopover && (<>
          <Button ref={buttonRef} aria-haspopup aria-expanded={isOpen} onClick={() => setIsOpen(!isOpen)} onKeyDown={hideOnEscape}>
            {`${isOpen ? 'Close' : 'Open'} Atomic Condition`}
          </Button>

          <Popover show={isOpen} ref={setPopoverEl} target={buttonRef.current} placement='bottom-start'>
            <Flex container={{ pad: 1 }}>{atomicConditionJSX}</Flex>
          </Popover>
        </>)}
      <Card>
        <CardContent>
          <Text variant='h4'>Output:</Text>
          <StyledCodeBlock>
            {submitCondition ? JSON.stringify(submitCondition, null, 2) : '(No condition)'}
          </StyledCodeBlock>

          <Text variant='h4'>Formatted Output:</Text>
          <StyledCodeBlock>
            {submitCondition
            ? formatCondition({ condition: submitCondition }, demoFields, translate)
            : '(No condition)'}
          </StyledCodeBlock>
          <Flex container={{ gap: 1, direction: 'column' }}>
            <Flex container={{ gap: 1, direction: 'column' }}>
              <Text variant='h2' status='error'>
                validRhsTypes Prop Warning
              </Text>
              <Text>
                There are LHS(Left Hand Side Field)/Comparator pairings that <u>require</u> specific
                RHS(Right Hand Side Value) types. Please be mindful of these incompatibilities when
                limiting RHS value types using this prop. We <b>do not</b> support limiting RHS
                field types to incompatible types and it will result in a validation error if you do
                so. The pairings referred to here are as follows:
              </Text>
            </Flex>
            <StyledList>
              <li>
                BOOLEAN LHS Fields coupled with "EQ" or "NEQ" comparators, will <u>always yield</u>{' '}
                a Field RHS
              </li>
              <li>
                Any LHS Fields coupled with "IN" or "NOT_IN" comparators, will <u>always yield</u> a
                Literal RHS (Comma separated list)
              </li>
            </StyledList>
            <Flex container={{ direction: 'column' }}>
              <Text>
                If you would like to limit RHS value types and avoid these incompatibilities, you
                will need to exclude these comparators using the <b>validComparators</b> prop.
              </Text>
            </Flex>
          </Flex>
        </CardContent>
      </Card>
    </StyledGrid>);
};
AtomicConditionDemo.args = {
    validComparators: false,
    renderInPopover: false,
    dateFunctions: true,
    itemDirection: 'column',
    useLiteralRHSType: true,
    useParameterRHSType: true,
    useFieldRHSType: true,
    useRelativeDatesRHSType: true,
    lhsMode: 'input'
};
AtomicConditionDemo.argTypes = {
    validComparators: { control: { type: 'boolean' } },
    renderInPopover: { control: { type: 'boolean' } },
    dateFunctions: { control: { type: 'boolean' } },
    itemDirection: { options: ['column', 'row'], control: { type: 'select' } },
    useLiteralRHSType: { control: { type: 'boolean' } },
    useParameterRHSType: { control: { type: 'boolean' } },
    useFieldRHSType: { control: { type: 'boolean' } },
    useRelativeDatesRHSType: { control: { type: 'boolean' } },
    lhsMode: { options: ['input', 'label', 'hidden'], control: { type: 'select' } }
};
//# sourceMappingURL=ConditionBuilder.stories.jsx.map