import { __awaiter, __rest } from "tslib";
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useMemo, useState } from 'react';
import { Accordion, AccordionDetails, AccordionSummary, Box, Button, CardContent, CardMedia, Checkbox, Chip, Fade, Icon, IconButton, List, ListItem, ListItemButton, ListItemIcon, ListItemText, Typography, useMediaQuery, useTheme } from '@mui/material';
import { FormattedMessage } from 'react-intl';
import { styled } from '@mui/material/styles';
import classNames from 'classnames';
import { useThemeProps } from '@mui/system';
import Category from './Steps/Category';
import { PREFIX } from './constants';
import { getTheme, SCPreferences, usePreviousValue, UserUtils, useSCContext, useSCFetchCategories, useSCPreferences, useSCTheme, useSCUser } from '@selfcommunity/react-core';
import Appearance from './Steps/Appearance';
import Profile from './Steps/Profile';
import Invite from './Steps/Invite';
import App from './Steps/App';
import HiddenPlaceholder from '../../shared/HiddenPlaceholder';
import Widget from '../Widget';
import Content from './Steps/Content';
import { SCOPE_SC_UI } from '../../constants/Errors';
import { Endpoints, http, OnBoardingService, PreferenceService } from '@selfcommunity/api-services';
import { Logger } from '@selfcommunity/utils';
import { SCOnBoardingStepStatusType, SCOnBoardingStepType, SCOnBoardingStepIdType } from '@selfcommunity/types';
import OnBoardingWidgetSkeleton from './Skeleton';
import { closeSnackbar, useSnackbar } from 'notistack';
import HeaderPlaceholder from '../../assets/onBoarding/header';
import BaseDialog from '../../shared/BaseDialog';
import PubSub from 'pubsub-js';
import { SCCategoryEventType, SCTopicType } from '../../constants/PubSub';
import OnBoardingActionsButton from './ActionsButton';
const classes = {
    root: `${PREFIX}-root`,
    content: `${PREFIX}-content`,
    accordionRoot: `${PREFIX}-accordion-root`,
    logo: `${PREFIX}-logo`,
    intro: `${PREFIX}-intro`,
    steps: `${PREFIX}-steps`,
    stepsMobile: `${PREFIX}-steps-mobile`,
    stepContent: `${PREFIX}-step-content`,
    dialogRoot: `${PREFIX}-dialog-root`,
    dialogContent: `${PREFIX}-dialog-content`
};
const Root = styled(Widget, {
    name: PREFIX,
    slot: 'Root',
    overridesResolver: (props, styles) => styles.root
})(() => ({}));
const AccordionRoot = styled(Accordion, {
    name: PREFIX,
    slot: 'AccordionRoot',
    overridesResolver: (props, styles) => styles.accordionRoot
})(() => ({}));
const DialogRoot = styled(BaseDialog, {
    name: PREFIX,
    slot: 'Root',
    overridesResolver: (props, styles) => styles.dialogRoot
})(({ theme }) => ({}));
const OnBoardingWidget = (inProps) => {
    // PROPS
    const props = useThemeProps({
        props: inProps,
        name: PREFIX
    });
    const { className, GenerateContentsParams = {}, onGeneratedContent = null, onHeightChange, onStateChange, forceExpanded = false, initialStep } = props, rest = __rest(props, ["className", "GenerateContentsParams", "onGeneratedContent", "onHeightChange", "onStateChange", "forceExpanded", "initialStep"]);
    // STATE
    const [loading, setLoading] = useState(true);
    const [initialized, setInitialized] = useState(false);
    const [steps, setSteps] = useState([]);
    const nextStep = useMemo(() => {
        const step = steps === null || steps === void 0 ? void 0 : steps.find((step) => (initialStep ? step.step === initialStep : step.status === 'in_progress' || step.status === 'not_started'));
        return step || (steps === null || steps === void 0 ? void 0 : steps[0]);
    }, [steps]);
    const allStepsDone = useMemo(() => {
        return steps === null || steps === void 0 ? void 0 : steps.every((step) => step.status === SCOnBoardingStepStatusType.COMPLETED);
    }, [steps]);
    const [expanded, setExpanded] = useState(!allStepsDone || forceExpanded);
    const [_step, setStep] = useState(nextStep);
    const currentContentsStep = steps === null || steps === void 0 ? void 0 : steps.find((s) => s.step === SCOnBoardingStepType.CONTENTS);
    const prevContentsStep = usePreviousValue(currentContentsStep);
    const currentCategoriesStep = steps === null || steps === void 0 ? void 0 : steps.find((s) => s.step === SCOnBoardingStepType.CATEGORIES);
    const prevCategoriesStep = usePreviousValue(currentCategoriesStep);
    const [showNoCategoriesModal, setShowNoCategoriesModal] = useState(false);
    const [showCategoriesWarningModal, setShowWarningCategoriesModal] = useState(false);
    const [isGenerating, setIsGenerating] = useState(false);
    // CONTEXT
    const scUserContext = useSCUser();
    const isAdmin = useMemo(() => UserUtils.isCommunityCreator(scUserContext.user), [scUserContext.user]);
    const scContext = useSCContext();
    const scPreferencesContext = useSCPreferences();
    const scThemeContext = useSCTheme();
    const { enqueueSnackbar } = useSnackbar();
    const showOnBoarding = useMemo(() => scPreferencesContext.preferences &&
        SCPreferences.CONFIGURATIONS_ONBOARDING_ENABLED in scPreferencesContext.preferences &&
        SCPreferences.CONFIGURATIONS_ONBOARDING_HIDDEN in scPreferencesContext.preferences &&
        scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_ONBOARDING_ENABLED].value &&
        !scPreferencesContext.preferences[SCPreferences.CONFIGURATIONS_ONBOARDING_HIDDEN].value, [scPreferencesContext.preferences]);
    // HOOKS
    const theme = useTheme();
    const isMobile = useMediaQuery(theme.breakpoints.down('md'));
    const { categories, isLoading } = useSCFetchCategories();
    // HANDLERS
    /**
     * Notify changes to Feed if the Widget is contained
     */
    const notifyLayoutChanges = useMemo(() => (state) => {
        if (onStateChange && state) {
            onStateChange(state);
        }
        onHeightChange && onHeightChange();
    }, [onStateChange, onHeightChange]);
    const completeStep = (s) => __awaiter(void 0, void 0, void 0, function* () {
        if (s.status !== SCOnBoardingStepStatusType.COMPLETED) {
            yield OnBoardingService.completeAStep(s.id)
                .then(() => {
                setSteps((prev) => prev.map((item) => {
                    if (item.id === s.id) {
                        return Object.assign(Object.assign({}, item), { status: SCOnBoardingStepStatusType.COMPLETED, completion_percentage: 100 });
                    }
                    return item;
                }));
            })
                .catch((error) => {
                Logger.error(SCOPE_SC_UI, error);
            });
        }
        s.step === SCOnBoardingStepType.APPEARANCE && handlePreferencesUpdate();
    });
    /**
     * Fetches platform url
     */
    function fetchPlatform(query) {
        http
            .request({
            url: Endpoints.Platform.url(),
            method: Endpoints.Platform.method,
            params: {
                next: query
            }
        })
            .then((res) => {
            const platformUrl = res.data.platform_url;
            window.open(platformUrl, '_blank').focus();
        })
            .catch((error) => {
            console.log(error);
        });
    }
    const showSuccessAlert = (step) => {
        setIsGenerating(false);
        enqueueSnackbar(_jsx(FormattedMessage, { id: `ui.onBoardingWidget.step.${step.step}.success`, defaultMessage: `ui.onBoardingWidget.step.${step.step}.success` }), {
            action: (snackbarId) => (_jsxs(_Fragment, { children: [step.step === SCOnBoardingStepType.CATEGORIES && (_jsx(Button, Object.assign({ sx: { textTransform: 'uppercase', color: 'white' }, size: "small", variant: "text", onClick: () => fetchPlatform('/contents/interests/') }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.step.categories.success.link", defaultMessage: "ui.onBoardingWidget.step.categories.success.link" }) }))), _jsx(IconButton, Object.assign({ sx: { color: 'white' }, onClick: () => closeSnackbar(snackbarId) }, { children: _jsx(Icon, { children: "close" }) }))] })),
            variant: 'success',
            autoHideDuration: 7000
        });
    };
    const getSteps = () => __awaiter(void 0, void 0, void 0, function* () {
        yield OnBoardingService.getAllSteps()
            .then((res) => {
            const contentStep = res.results.find((step) => step.step === SCOnBoardingStepType.CONTENTS);
            setIsGenerating(res.results.some((step) => step.status === 'in_progress'));
            setSteps(res.results);
            setLoading(false);
            if (contentStep.status === SCOnBoardingStepStatusType.IN_PROGRESS && contentStep.results.length !== 0 && onGeneratedContent) {
                onGeneratedContent(contentStep.results);
            }
        })
            .catch((error) => {
            Logger.error(SCOPE_SC_UI, error);
            setLoading(false);
        });
    });
    const handleChange = (newStep) => {
        setStep(newStep);
    };
    const handleExpand = () => {
        const _expanded = !expanded;
        setExpanded(_expanded);
        notifyLayoutChanges({ forceExpanded: _expanded });
    };
    const generateContent = (stepId) => __awaiter(void 0, void 0, void 0, function* () {
        if (!isLoading && !categories.length) {
            setShowNoCategoriesModal(true);
        }
        else if (stepId === SCOnBoardingStepIdType.CATEGORIES) {
            setShowWarningCategoriesModal(true);
        }
        else {
            yield startStep(stepId);
        }
    });
    const startStep = (stepId) => __awaiter(void 0, void 0, void 0, function* () {
        showCategoriesWarningModal && setShowWarningCategoriesModal(false);
        try {
            yield OnBoardingService.startAStep(stepId, GenerateContentsParams);
            setIsGenerating(true);
        }
        catch (error) {
            Logger.error(SCOPE_SC_UI, error);
            enqueueSnackbar(_jsx(FormattedMessage, { id: "ui.common.error.action", defaultMessage: "ui.common.error.action" }), {
                variant: 'error',
                autoHideDuration: 3000
            });
        }
    });
    const handlePreferencesUpdate = () => {
        PreferenceService.getAllPreferences().then((preferences) => {
            const prefs = preferences['results'].reduce((obj, p) => (Object.assign(Object.assign({}, obj), { [`${p.section}.${p.name}`]: p })), {});
            scPreferencesContext.setPreferences(prefs);
            scThemeContext.setTheme(getTheme(scContext.settings.theme, prefs));
        });
    };
    const handleCategoriesClick = () => {
        fetchPlatform('/contents/interests/');
        setShowNoCategoriesModal(false);
    };
    /**
     * Notify when a category info changes
     * @param data
     */
    function notifyCategoryChanges(data) {
        data && PubSub.publish(`${SCTopicType.CATEGORY}.${SCCategoryEventType.EDIT}`, data);
    }
    // EFFECTS
    useEffect(() => {
        if (prevContentsStep &&
            prevContentsStep.status === SCOnBoardingStepStatusType.IN_PROGRESS &&
            (currentContentsStep === null || currentContentsStep === void 0 ? void 0 : currentContentsStep.status) === SCOnBoardingStepStatusType.COMPLETED) {
            showSuccessAlert(currentContentsStep);
        }
    }, [currentContentsStep, prevContentsStep]);
    useEffect(() => {
        if (prevCategoriesStep &&
            prevCategoriesStep.status === SCOnBoardingStepStatusType.IN_PROGRESS &&
            (currentCategoriesStep === null || currentCategoriesStep === void 0 ? void 0 : currentCategoriesStep.status) === SCOnBoardingStepStatusType.COMPLETED) {
            showSuccessAlert(currentCategoriesStep);
        }
    }, [currentCategoriesStep, prevCategoriesStep]);
    useEffect(() => {
        if (!initialized && nextStep) {
            setStep(nextStep);
            setInitialized(true);
            notifyLayoutChanges({ forceExpanded: expanded });
        }
    }, [initialized, nextStep]);
    useEffect(() => {
        const _expanded = !allStepsDone;
        setExpanded(_expanded);
        notifyLayoutChanges({ forceExpanded: _expanded });
    }, [allStepsDone]);
    useEffect(() => {
        if (isAdmin) {
            getSteps();
            // eslint-disable-next-line @typescript-eslint/no-misused-promises
            const intervalId = setInterval(getSteps, isGenerating ? 6000 : 3 * 60 * 1000);
            return () => clearInterval(intervalId);
        }
    }, [scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user, isGenerating, isAdmin]);
    /**
     * updates categories info when generating category content
     */
    useEffect(() => {
        const categoryStep = steps.find((step) => step.step === SCOnBoardingStepType.CATEGORIES);
        if ((categoryStep === null || categoryStep === void 0 ? void 0 : categoryStep.status) === SCOnBoardingStepStatusType.IN_PROGRESS && categoryStep.results.length !== 0) {
            categoryStep.results.forEach((c) => {
                // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
                // @ts-ignore
                const isAlreadyNotified = prevCategoriesStep === null || prevCategoriesStep === void 0 ? void 0 : prevCategoriesStep.results.some((result) => result.id === c.id);
                if (!isAlreadyNotified) {
                    notifyCategoryChanges(c);
                }
            });
        }
    }, [steps, prevCategoriesStep]);
    /**
     * Render _step content section
     */
    const getStepContent = () => {
        const stepObj = steps === null || steps === void 0 ? void 0 : steps.find((obj) => obj.step === (_step === null || _step === void 0 ? void 0 : _step.step));
        let content;
        switch (stepObj === null || stepObj === void 0 ? void 0 : stepObj.step) {
            case SCOnBoardingStepType.CONTENTS:
                content = _jsx(Content, { step: stepObj, handleContentCreation: () => generateContent(stepObj.id) });
                break;
            case SCOnBoardingStepType.CATEGORIES:
                content = _jsx(Category, { step: stepObj, handleCategoriesCreation: () => generateContent(stepObj.id) });
                break;
            case SCOnBoardingStepType.APPEARANCE:
                content = _jsx(Appearance, { onCompleteAction: () => completeStep(stepObj) });
                break;
            case SCOnBoardingStepType.PROFILE:
                content = _jsx(Profile, { onCompleteAction: () => completeStep(stepObj) });
                break;
            case SCOnBoardingStepType.INVITE:
                content = _jsx(Invite, { onCompleteAction: () => completeStep(stepObj) });
                break;
            case SCOnBoardingStepType.APP:
                content = _jsx(App, { step: stepObj, onCompleteAction: () => completeStep(stepObj) });
                break;
            default:
                break;
        }
        return content;
    };
    if (!isAdmin || !showOnBoarding) {
        return _jsx(HiddenPlaceholder, {});
    }
    return (_jsx(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { children: _jsxs(AccordionRoot, Object.assign({ defaultExpanded: true, className: classes.accordionRoot, expanded: expanded }, { children: [_jsx(AccordionSummary, Object.assign({ expandIcon: _jsx(OnBoardingActionsButton, { isExpanded: expanded, onExpandChange: handleExpand, onHideOnBoarding: handlePreferencesUpdate }), "aria-controls": "accordion", id: "onBoarding-accordion" }, { children: _jsx(_Fragment, { children: expanded ? (_jsxs(_Fragment, { children: [!isMobile ? (_jsx(CardMedia, { className: classes.logo, component: "img", src: HeaderPlaceholder })) : (_jsxs(Typography, Object.assign({ variant: "h4" }, { children: [_jsx(Icon, Object.assign({ color: "secondary", fontSize: "medium" }, { children: "ai_stars" })), _jsx(FormattedMessage, { id: "ui.onBoardingWidget.accordion.expanded.title.mobile", defaultMessage: "ui.onBoardingWidget.accordion.expanded.title.mobile", values: {
                                                // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
                                                // @ts-ignore
                                                b: (chunks) => _jsx("strong", { children: chunks })
                                            } })] }))), _jsxs(Box, Object.assign({ className: classes.intro }, { children: [!isMobile && (_jsx(Typography, Object.assign({ variant: "h4" }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.accordion.expanded.title", defaultMessage: "ui.onBoardingWidget.accordion.expanded.title" }) }))), _jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.accordion.expanded.subtitle", defaultMessage: "ui.onBoardingWidget.accordion.expanded.subtitle" }) })), _jsx(Typography, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.accordion.expanded.summary", defaultMessage: "ui.onBoardingWidget.accordion.expanded.summary", values: {
                                                    // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
                                                    // @ts-ignore
                                                    b: (chunks) => _jsx("strong", { children: chunks }),
                                                    // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
                                                    // @ts-ignore
                                                    icon: (...chunks) => _jsx(Icon, { children: chunks })
                                                } }) })] }))] })) : (_jsx(Typography, Object.assign({ variant: "body1" }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.accordion.collapsed", defaultMessage: "ui.onBoardingWidget.accordion.collapsed", values: {
                                    // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
                                    // @ts-ignore
                                    b: (chunks) => _jsx("strong", { children: chunks }),
                                    // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
                                    // @ts-ignore
                                    // eslint-disable-next-line prettier/prettier
                                    icon: (...chunks) => _jsx(Icon, Object.assign({ color: "secondary", fontSize: "medium" }, { children: chunks }))
                                } }) }))) }) })), _jsx(AccordionDetails, { children: _jsx(Widget, Object.assign({ className: classes.content, elevation: 0 }, { children: loading ? (_jsx(OnBoardingWidgetSkeleton, {})) : (_jsxs(CardContent, { children: [_jsx(List, Object.assign({ className: isMobile ? classes.stepsMobile : classes.steps }, { children: steps === null || steps === void 0 ? void 0 : steps.map((step) => (_jsx(ListItem, { children: isMobile ? (_jsx(Chip, { size: "small", label: _jsxs(_Fragment, { children: [_jsx(FormattedMessage, { id: `ui.onBoardingWidget.${step.step}`, defaultMessage: `ui.onBoardingWidget.${step.step}` }), ' ', step.status === SCOnBoardingStepStatusType.COMPLETED && (_jsx(Icon, Object.assign({ color: (step === null || step === void 0 ? void 0 : step.status) === SCOnBoardingStepStatusType.COMPLETED && (step === null || step === void 0 ? void 0 : step.step) !== (_step === null || _step === void 0 ? void 0 : _step.step) ? 'success' : 'inherit' }, { children: "check" })))] }), onClick: () => handleChange(step), variant: step.step === (_step === null || _step === void 0 ? void 0 : _step.step) ? 'filled' : 'outlined', color: step.status === SCOnBoardingStepStatusType.COMPLETED ? 'success' : 'default' })) : (_jsxs(ListItemButton, Object.assign({ onClick: () => handleChange(step), selected: (step === null || step === void 0 ? void 0 : step.step) === (_step === null || _step === void 0 ? void 0 : _step.step) }, { children: [_jsx(ListItemIcon, { children: _jsx(Checkbox, { edge: "start", checked: step.status === SCOnBoardingStepStatusType.COMPLETED, tabIndex: -1, disableRipple: true, inputProps: { 'aria-labelledby': step.step }, size: 'small' }) }), _jsx(ListItemText, { primary: _jsx(FormattedMessage, { id: `ui.onBoardingWidget.${step.step}`, defaultMessage: `ui.onBoardingWidget.${step.step}` }) })] }))) }, step.id))) })), _jsxs(Box, Object.assign({ className: classes.stepContent }, { children: [_jsx(Fade, Object.assign({ in: true, timeout: 2400 }, { children: _jsx(Box, { children: getStepContent() }) })), showNoCategoriesModal && (_jsx(BaseDialog, Object.assign({ title: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.no.categories", defaultMessage: "ui.onBoardingWidget.ai.no.categories" }), DialogContentProps: { dividers: false }, open: showNoCategoriesModal, onClose: () => setShowNoCategoriesModal(false), actions: _jsx(Button, Object.assign({ color: "secondary", onClick: () => setShowNoCategoriesModal(false) }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.no.categories.cancel", defaultMessage: "ui.onBoardingWidget.ai.no.categories.cancel" }) })) }, { children: _jsx(Button, Object.assign({ color: "primary", onClick: handleCategoriesClick, startIcon: _jsx(Icon, Object.assign({ fontSize: "small" }, { children: "edit" })) }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.no.categories.link", defaultMessage: "ui.onBoardingWidget.ai.no.categories.link" }) })) }))), showCategoriesWarningModal && (_jsx(DialogRoot, Object.assign({ className: classes.dialogRoot, title: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.categories.warning.title", defaultMessage: "ui.onBoardingWidget.ai.categories.warning.title" }), DialogContentProps: { dividers: false }, open: showCategoriesWarningModal, onClose: () => setShowWarningCategoriesModal(false), actions: _jsxs(_Fragment, { children: [_jsx(Button, Object.assign({ size: "small", variant: "outlined", color: "primary", onClick: () => setShowWarningCategoriesModal(false) }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.categories.warning.button.close", defaultMessage: "ui.onBoardingWidget.ai.categories.warning.button.close" }) })), _jsx(Button, Object.assign({ size: "small", variant: "contained", color: "secondary", onClick: () => startStep(SCOnBoardingStepIdType.CATEGORIES), endIcon: _jsx(Icon, Object.assign({ fontSize: "small" }, { children: "magic_wand" })) }, { children: _jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.categories.warning.button.generate", defaultMessage: "ui.onBoardingWidget.ai.categories.warning.button.generate" }) }))] }) }, { children: _jsxs(Typography, Object.assign({ className: classes.dialogContent }, { children: [_jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.categories.warning.info", defaultMessage: "ui.onBoardingWidget.ai.categories.warning.info" }), _jsx(FormattedMessage, { id: "ui.onBoardingWidget.ai.categories.warning.confirm", defaultMessage: "ui.onBoardingWidget.ai.categories.warning.confirm", values: {
                                                            // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
                                                            // @ts-ignore
                                                            b: (chunks) => _jsx("b", { children: chunks })
                                                        } })] })) })))] }))] })) })) })] })) })));
};
export default OnBoardingWidget;
