import {Store} from 'redux';

import {GlobalState} from 'mattermost-redux/types/store';

import {GenericAction} from 'mattermost-redux/types/actions';

import {getConfig} from 'mattermost-redux/selectors/entities/general';

import {getCurrentUser} from 'mattermost-redux/selectors/entities/common';

import React from 'react';

import {IntlProvider} from 'react-intl';

import {useSelector} from 'react-redux';

import {openAddSubscription, openCreateBadge, openCreateType, openRemoveSubscription, setRHSView, setShowRHSAction} from 'actions/actions';

import RHSComponent from 'components/rhs';
import BadgeModal from 'components/badge_modal';
import TypeModal from 'components/type_modal';
import GrantModal from 'components/grant_modal';
import SubscriptionModal from 'components/subscription_modal';

import ChannelHeaderButton from 'components/channel_header_button';

import Reducer from './reducers';

import manifest from './manifest';

// eslint-disable-next-line import/no-unresolved
import {PluginRegistry} from './types/mattermost-webapp';
import BadgeListConnected from './components/user_popover/';
import {RHS_STATE_ALL} from './constants';
import {getTranslations} from './utils/i18n';
import BadgesAdminSetting from './components/admin/badges_admin_setting';

function withIntl(Component: React.ElementType): React.ElementType {
    const Wrapped: React.FC<any> = (props) => {
        const currentUser = useSelector(getCurrentUser);
        const locale = currentUser?.locale || 'ru';
        return (
            <IntlProvider
                locale={locale}
                messages={getTranslations(locale)}
            >
                <Component {...props}/>
            </IntlProvider>
        );
    };
    return Wrapped;
}

const WrappedRHS = withIntl(RHSComponent);
const WrappedBadgeList = withIntl(BadgeListConnected as unknown as React.ElementType);

export default class Plugin {
    public async initialize(registry: PluginRegistry, store: Store<GlobalState, GenericAction>) {
        registry.registerReducer(Reducer);

        registry.registerTranslations(getTranslations);

        registry.registerAdminConsoleCustomSetting('BadgesAdmin', withIntl(BadgesAdminSetting));

        registry.registerPopoverUserAttributesComponent(WrappedBadgeList);

        registry.registerRootComponent(withIntl(BadgeModal));
        registry.registerRootComponent(withIntl(TypeModal));
        registry.registerRootComponent(withIntl(GrantModal));
        registry.registerRootComponent(withIntl(SubscriptionModal));

        const locale = getCurrentUser(store.getState())?.locale || 'ru';
        const messages = getTranslations(locale);

        const {showRHSPlugin, toggleRHSPlugin} = registry.registerRightHandSidebarComponent(WrappedRHS, messages['badges.sidebar.title']);
        store.dispatch(setShowRHSAction(() => store.dispatch(showRHSPlugin)));

        const toggleRHS = () => {
            store.dispatch(setRHSView(RHS_STATE_ALL));
            store.dispatch(toggleRHSPlugin);
        };
        registry.registerChannelHeaderButtonAction(
            <ChannelHeaderButton/>,
            toggleRHS,
            messages['badges.sidebar.title'],
            messages['badges.menu.open_list'],
        );

        if (registry.registerAppBarComponent) {
            const siteUrl = getConfig(store.getState())?.SiteURL || '';
            const iconURL = `${siteUrl}/plugins/${manifest.id}/public/app-bar-icon.png`;
            registry.registerAppBarComponent(
                iconURL,
                toggleRHS,
                messages['badges.menu.open_list'],
            );
        }

        registry.registerMainMenuAction(
            messages['badges.menu.create_badge'],
            () => {
                store.dispatch(openCreateBadge() as any);
            },
            null,
        );
        registry.registerMainMenuAction(
            messages['badges.menu.create_type'],
            () => {
                store.dispatch(openCreateType() as any);
            },
            null,
        );

        registry.registerChannelHeaderMenuAction(
            messages['badges.menu.add_subscription'],
            () => {
                store.dispatch(openAddSubscription() as any);
            },
        );
        registry.registerChannelHeaderMenuAction(
            messages['badges.menu.remove_subscription'],
            () => {
                store.dispatch(openRemoveSubscription() as any);
            },
        );
    }
}

declare global {
    interface Window {
        registerPlugin(id: string, plugin: Plugin): void;
    }
}

window.registerPlugin(manifest.id, new Plugin());
