import { __rest } from "tslib";
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { Button, CardActions, Icon, IconButton, Typography } from '@mui/material';
import { styled } from '@mui/material/styles';
import { Box, useThemeProps } from '@mui/system';
import { Endpoints, EventService, http } from '@selfcommunity/api-services';
import { SCCache, SCPreferences, SCRoutes, useSCPreferences, useSCRouting, useSCUser } from '@selfcommunity/react-core';
import { SCEventSubscriptionStatusType, SCFeatureName } from '@selfcommunity/types';
import { Logger } from '@selfcommunity/utils';
import { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react';
import { FormattedMessage } from 'react-intl';
import { SCOPE_SC_UI } from '../../constants/Errors';
import { DEFAULT_PAGINATION_LIMIT, DEFAULT_PAGINATION_OFFSET } from '../../constants/Pagination';
import HiddenPlaceholder from '../../shared/HiddenPlaceholder';
import { SCEventTemplateType } from '../../types/event';
import { actionWidgetTypes, dataWidgetReducer, stateWidgetInitializer } from '../../utils/widget';
import Event from '../Event';
import Widget from '../Widget';
import { PREFIX } from './constants';
import Skeleton from './Skeleton';
import PubSub from 'pubsub-js';
import { SCGroupEventType, SCTopicType } from '../../constants/PubSub';
const classes = {
    root: `${PREFIX}-root`,
    titleWrapper: `${PREFIX}-title-wrapper`,
    imageWrapper: `${PREFIX}-image-wrapper`,
    image: `${PREFIX}-image`,
    content: `${PREFIX}-content`,
    nameWrapper: `${PREFIX}-name-wrapper`,
    name: `${PREFIX}-name`,
    user: `${PREFIX}-user`,
    firstDivider: `${PREFIX}-first-divider`,
    secondDivider: `${PREFIX}-second-divider`,
    actions: `${PREFIX}-actions`,
    actionButton: `${PREFIX}-action-button`,
    arrows: `${PREFIX}-arrows`
};
const Root = styled(Widget, {
    name: PREFIX,
    slot: 'Root',
    overridesResolver: (_props, styles) => styles.root
})(() => ({}));
export default function MyEventsWidget(inProps) {
    // PROPS
    const props = useThemeProps({
        props: inProps,
        name: PREFIX
    });
    // CONST
    const { endpointQueryParams = {
        limit: DEFAULT_PAGINATION_LIMIT,
        offset: DEFAULT_PAGINATION_OFFSET,
        subscription_status: SCEventSubscriptionStatusType.GOING
    }, cacheStrategy } = props, rest = __rest(props, ["endpointQueryParams", "cacheStrategy"]);
    // STATE
    const [state, dispatch] = useReducer(dataWidgetReducer, {
        isLoadingNext: false,
        next: null,
        cacheKey: SCCache.getWidgetStateCacheKey(SCCache.USER_EVENTS_STATE_CACHE_PREFIX_KEY),
        cacheStrategy,
        visibleItems: 1
    }, stateWidgetInitializer);
    const [eventIndex, setEventIndex] = useState(0);
    // CONTEXT
    const scUserContext = useSCUser();
    const scRoutingContext = useSCRouting();
    const { preferences, features } = useSCPreferences();
    const eventsEnabled = useMemo(() => preferences &&
        features &&
        features.includes(SCFeatureName.TAGGING) &&
        SCPreferences.CONFIGURATIONS_EVENTS_ENABLED in preferences &&
        preferences[SCPreferences.CONFIGURATIONS_EVENTS_ENABLED].value, [preferences, features]);
    // REFS
    const updatesSubscription = useRef(null);
    /**
     * Initialize component
     * Fetch data only if the component is not initialized and it is not loading data
     */
    const _initComponent = useCallback(() => {
        if (!state.initialized && !state.isLoadingNext) {
            dispatch({ type: actionWidgetTypes.LOADING_NEXT });
            EventService.getUserEvents(Object.assign({}, endpointQueryParams))
                .then((payload) => {
                dispatch({ type: actionWidgetTypes.LOAD_NEXT_SUCCESS, payload: Object.assign(Object.assign({}, payload), { initialized: true }) });
            })
                .catch((error) => {
                dispatch({ type: actionWidgetTypes.LOAD_NEXT_FAILURE, payload: { errorLoadNext: error } });
                Logger.error(SCOPE_SC_UI, error);
            });
        }
    }, [state.isLoadingNext, state.initialized, dispatch]);
    const _fetchNext = useCallback(() => {
        dispatch({ type: actionWidgetTypes.LOADING_NEXT });
        http
            .request({
            url: state.next,
            method: Endpoints.GetUserEvents.method
        })
            .then((res) => {
            dispatch({ type: actionWidgetTypes.LOAD_NEXT_SUCCESS, payload: res.data });
            setEventIndex((index) => index + 1);
        })
            .catch((error) => {
            dispatch({ type: actionWidgetTypes.LOAD_NEXT_FAILURE, payload: { errorLoadNext: error } });
            Logger.error(SCOPE_SC_UI, error);
        });
    }, [dispatch, state.next]);
    // EFFECTS
    useEffect(() => {
        let _t;
        if (eventsEnabled && scUserContext.user) {
            _t = setTimeout(_initComponent);
            return () => {
                clearTimeout(_t);
            };
        }
    }, [scUserContext.user, eventsEnabled]);
    const handlePrev = useCallback(() => {
        setEventIndex(eventIndex - 1);
    }, [eventIndex]);
    const handleNext = useCallback(() => {
        if (eventIndex < state.results.length - 1) {
            setEventIndex(eventIndex + 1);
        }
        else {
            _fetchNext();
        }
    }, [eventIndex, state.results]);
    /**
     * Subscriber for pubsub callback
     */
    const onDeleteEventHandler = useCallback((_msg, deleted) => {
        const _events = [...state.results];
        if (_events.some((e) => e.id === deleted)) {
            const updatedEvents = _events.filter((e) => e.id !== deleted);
            dispatch({
                type: actionWidgetTypes.SET_RESULTS,
                payload: { results: updatedEvents }
            });
        }
    }, [state.results]);
    /**
     * On mount, subscribe to receive event updates (only delete)
     */
    useEffect(() => {
        if (state.results) {
            updatesSubscription.current = PubSub.subscribe(`${SCTopicType.EVENT}.${SCGroupEventType.DELETE}`, onDeleteEventHandler);
        }
        return () => {
            updatesSubscription.current && PubSub.unsubscribe(updatesSubscription.current);
        };
    }, [state.results]);
    // RENDER
    if (!eventsEnabled || (state.initialized && state.count === 0)) {
        return _jsx(HiddenPlaceholder, {});
    }
    if (!state.initialized || state.isLoadingNext) {
        return _jsx(Skeleton, {});
    }
    return (_jsxs(Root, Object.assign({ className: classes.root }, rest, { children: [_jsx(Box, Object.assign({ className: classes.titleWrapper }, { children: _jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.myEventsWidget.title", defaultMessage: "ui.myEventsWidget.title" }) })) })), _jsx(Event, { event: state.results[eventIndex], template: SCEventTemplateType.DETAIL, actions: _jsx(_Fragment, {}), elevation: 0, square: true }), _jsxs(CardActions, Object.assign({ className: classes.actions }, { children: [_jsx(IconButton, Object.assign({ size: "small", disabled: eventIndex === 0, className: classes.arrows, onClick: handlePrev }, { children: _jsx(Icon, { children: "chevron_left" }) })), _jsx(Button, Object.assign({ href: scRoutingContext.url(SCRoutes.EVENTS_ROUTE_NAME, {}), className: classes.actionButton }, { children: _jsx(Typography, Object.assign({ variant: "caption" }, { children: _jsx(FormattedMessage, { id: "ui.myEventsWidget.showAll", defaultMessage: "ui.myEventsWidget.showAll" }) })) })), _jsx(IconButton, Object.assign({ size: "small", disabled: eventIndex === state.count - 1, className: classes.arrows, onClick: handleNext }, { children: _jsx(Icon, { children: "chevron_right" }) }))] }))] })));
}
