import PropTypes from 'prop-types';
import React, { useState, useRef } from 'react';
import { COLORPICKER, GROUP_HEADER, SLIDER, TOGGLE } from '../../constants/schemaComponentTypes';
import { darken, lighten } from '../../tools/colorHelper';
import { upperFirst, normalizeString } from '../../tools/stringTools';
import { createNamespace } from '../../tools/namingTools';
import { useResponsive } from '../../tools/widths/useResponsive';
import { navBorderColorLightenValue, navBgColorHoverDarkenValue } from '../../constants/components/faq';
import withListener from '../withListener';
import Collapsible from '../../atoms/collapsible-text/CollapsibleText';
import DesktopNav from './atoms/desktop-nav/DesktopNav';
import MobileNav from './atoms/mobile-nav/MobileNav';

import './styles/Faq.scss';

const n = createNamespace('Faq');

export const FaqComponent = ({
    data: {
        faqGroups
    },
    settings
}) => {
    const { items, i18n: i18nProp } = faqGroups;
    const i18n = { ...FaqComponent.defaultProps.data.faqGroups.i18n, ...i18nProp };
    const settingsWithDefaults = { ...FaqComponent.defaultProps.settings, ...settings };
    const {
        navBackgroundColor,
        navBorderColor,
        navSelectedColor,
        navDividerVisible,
        navPadding,
        qAndABackgroundColor,
        qAndASelectedColor,
        isExpandable,
        qAndADividerVisible,
        listPadding
    } = settingsWithDefaults;
    const panelsRefs = useRef([]);

    const faqItems = items && items.length ? items.map(item => ({
        ...item,
        panelId: `panel${upperFirst(normalizeString(item.name))}`,
        tabId: `tab${upperFirst(normalizeString(item.name))}`
    })) : [];

    const [activeCollapsibleIndex, setActiveCollapsibleIndex] = useState(0);
    const [activeFaqGroup, setActiveFaqGroup] = useState(faqItems[0] || {});

    const changeQuestionList = index => {
        setActiveFaqGroup(faqItems[index]);
        setActiveCollapsibleIndex(0);
    };

    const focusOnPanel = panelIndex => {
        panelsRefs.current[panelIndex].focus();
    };

    const componentVariables = {
        'faq-bgcolor': qAndABackgroundColor,
        'nav-border-color': navBorderColor,
        'nav-bgcolor': navBackgroundColor,
        'nav-button-border-color': navDividerVisible ? lighten(navBorderColor, navBorderColorLightenValue) : 'transparent',
        'nav-button-bgcolor-hover': navBackgroundColor && darken(navBackgroundColor, navBgColorHoverDarkenValue),
        'nav-button-bgcolor-active': navSelectedColor,
        'nav-button-padding-x': navPadding && `${navPadding}px`
    };

    const { largeDown: isMobile } = useResponsive();
    const currentQuestionIndex = faqItems.map(item => item.panelId).indexOf(activeFaqGroup.panelId);

    return (
        <section {...n('mainContainer').withVariables(componentVariables).withTestId().props}>
            <div {...n('row').props}>
                <div {...n('col', 'nav').props}>
                    {isMobile ? (
                        <MobileNav
                            {...n('navMobile').props}
                            items={faqItems.map((item, index) => ({ label: item.name, value: String(index) }))}
                            changeQuestionList={changeQuestionList}
                            label={i18n.categoryLabel}
                            currentIndex={currentQuestionIndex}
                        />
                    ) : (
                        <DesktopNav
                            changeQuestionList={changeQuestionList}
                            items={faqItems.map(({ name, tabId, panelId }) => ({
                                name,
                                id: tabId,
                                ariaControls: panelId
                            }))}
                            currentQuestionIndex={currentQuestionIndex}
                            focusOnPanel={focusOnPanel}
                            i18n={{
                                menuLabel: i18n.categoryLabel
                            }}
                        />
                    )}
                </div>
                <div {...n('col', 'faq').withTestId().props}>
                    {faqItems.map((faqGroup, panelIndex) => {
                        const { name = '', faqs = [], tabId, panelId } = faqGroup;
                        const faqGroupIsActive = activeFaqGroup.panelId === faqGroup.panelId;

                        return (
                            <div
                                {...n('faqGroup').withTestId().props}
                                id={panelId}
                                key={panelId}
                                role="tabpanel"
                                aria-labelledby={tabId}
                                hidden={!faqGroupIsActive}
                                ref={r => { panelsRefs.current[panelIndex] = r; }}
                                tabIndex="0"
                            >
                                <h2 {...n('faqHeader').withTestId().props}>{name}</h2>
                                {faqs.map((faq, faqIndex) => (
                                    <div {...n('collapsibleWrapper').withTestId().props} key={faq.question}>
                                        <Collapsible
                                            focusable={faqGroupIsActive}
                                            setActiveCollapsibleIndex={setActiveCollapsibleIndex}
                                            index={faqIndex}
                                            isActive={activeCollapsibleIndex === faqIndex}
                                            faqData={faq}
                                            listPadding={listPadding}
                                            selectedBackgroundColor={qAndASelectedColor}
                                            isExpandable={isExpandable}
                                        />
                                        {qAndADividerVisible && <hr aria-hidden="true" {...n('divider').withTestId().props} />}
                                    </div>
                                ))}
                            </div>
                        );
                    })}
                </div>
            </div>
        </section>
    );
};

FaqComponent.schema = () => ({
    name: 'FAQ',
    title: 'uieditor.sfbComponent.faq.title',
    iconName: 'quote',
    form: {
        spacer: {
            type: GROUP_HEADER,
            title: 'uieditor.sfbComponent.faq.menuSettings.title',
            symbol: 'menu'
        },
        navBackgroundColor: {
            title: 'uieditor.sfbComponent.faq.navBackgroundColor.title',
            defaultValue: '#ffffff',
            type: COLORPICKER,
            removeMarginBottom: true,
            removePaddingBottom: true
        },
        navBorderColor: {
            title: 'uieditor.sfbComponent.faq.navBorderColor.title',
            defaultValue: '#C3C3C3',
            type: COLORPICKER,
            removeMarginBottom: true,
            removePaddingBottom: true
        },
        navSelectedColor: {
            title: 'uieditor.sfbComponent.faq.navSelectedColor.title',
            defaultValue: '#338099',
            type: COLORPICKER
        },
        navDividerVisible: {
            labelOn: 'uieditor.sfbComponent.faq.navDividerVisible.labelOn',
            labelOff: 'uieditor.sfbComponent.faq.navDividerVisible.labelOff',
            defaultValue: true,
            type: TOGGLE
        },
        navPadding: {
            title: 'uieditor.sfbComponent.faq.navPadding.title',
            type: SLIDER,
            defaultValue: 10,
            options: {
                min: 0,
                max: 35,
                step: 1,
                unit: 'px'
            }
        },
        spacer2: {
            type: GROUP_HEADER,
            title: 'uieditor.sfbComponent.faq.q&aSettings.title',
            symbol: 'settings'
        },
        qAndABackgroundColor: {
            title: 'uieditor.sfbComponent.faq.qAndABackgroundColor.title',
            defaultValue: '#ffffff',
            type: COLORPICKER,
            removeMarginBottom: true,
            removePaddingBottom: true
        },
        qAndASelectedColor: {
            title: 'uieditor.sfbComponent.faq.qAndASelectedColor.title',
            defaultValue: '#F7F7F7',
            type: COLORPICKER
        },
        isExpandable: {
            labelOn: 'uieditor.sfbComponent.faq.isExpandable.labelOn',
            labelOff: 'uieditor.sfbComponent.faq.isExpandable.labelOff',
            defaultValue: true,
            type: TOGGLE
        },
        qAndADividerVisible: {
            labelOn: 'uieditor.sfbComponent.faq.navDividerVisible.labelOn',
            labelOff: 'uieditor.sfbComponent.faq.navDividerVisible.labelOff',
            defaultValue: true,
            type: TOGGLE
        },
        listPadding: {
            title: 'uieditor.sfbComponent.faq.listPadding.title',
            defaultValue: 10,
            type: SLIDER,
            options: {
                min: 0,
                max: 35,
                step: 1,
                unit: 'px'
            }
        }
    },
    marketplaceData: {
        faqGroups: 'faqGroups'
    }
});

const SETTINGS = FaqComponent.schema().form;

FaqComponent.propTypes = {
    data: PropTypes.shape({
        faqGroups: PropTypes.shape({
            items: PropTypes.arrayOf(PropTypes.shape({
                name: PropTypes.string,
                faqs: PropTypes.arrayOf(PropTypes.shape({
                    answer: PropTypes.string,
                    question: PropTypes.string
                }))
            })),
            i18n: PropTypes.shape({
                title: PropTypes.string,
                categoryLabel: PropTypes.string
            })
        })
    }),
    settings: PropTypes.shape({
        navBackgroundColor: PropTypes.string,
        navBorderColor: PropTypes.string,
        navSelectedColor: PropTypes.string,
        navDividerVisible: PropTypes.bool,
        navPadding: PropTypes.number,
        qAndABackgroundColor: PropTypes.string,
        qAndASelectedColor: PropTypes.string,
        isExpandable: PropTypes.bool,
        qAndADividerVisible: PropTypes.bool,
        listPadding: PropTypes.number
    })
};
FaqComponent.defaultProps = {
    data: {
        faqGroups: {
            items: [],
            i18n: {
                title: 'Frequently asked questions',
                categoryLabel: 'Question categories'
            }
        }
    },
    settings: {
        navBackgroundColor: SETTINGS.navBackgroundColor.defaultValue,
        navBorderColor: SETTINGS.navBorderColor.defaultValue,
        navSelectedColor: SETTINGS.navSelectedColor.defaultValue,
        navDividerVisible: SETTINGS.navDividerVisible.defaultValue,
        navPadding: SETTINGS.navPadding.defaultValue,
        qAndABackgroundColor: SETTINGS.qAndABackgroundColor.defaultValue,
        qAndASelectedColor: SETTINGS.qAndASelectedColor.defaultValue,
        isExpandable: SETTINGS.isExpandable.defaultValue,
        qAndADividerVisible: SETTINGS.qAndADividerVisible.defaultValue,
        listPadding: SETTINGS.listPadding.defaultValue
    }
};

export default withListener(FaqComponent);
