import React, {useCallback, useEffect, useRef, useState} from 'react';

import {useDispatch, useSelector} from 'react-redux';
import {FormattedMessage, useIntl} from 'react-intl';

import {getCurrentChannelId} from 'mattermost-redux/selectors/entities/common';
import {GlobalState} from 'mattermost-redux/types/store';

import {closeSubscriptionModal} from 'actions/actions';
import {getSubscriptionModalData} from 'selectors';
import {BadgeTypeDefinition} from 'types/badges';
import Client from 'client/api';
import {getServerErrorId} from 'utils/helpers';
import CloseIcon from 'components/icons/close_icon';

const SubscriptionModal: React.FC = () => {
    const dispatch = useDispatch();
    const intl = useIntl();
    const modalData = useSelector(getSubscriptionModalData);
    const channelId = useSelector((state: GlobalState) => getCurrentChannelId(state));
    const isOpen = modalData !== null;
    const isDeleteMode = modalData?.mode === 'delete';

    const [selectedTypeId, setSelectedTypeId] = useState('');
    const [types, setTypes] = useState<BadgeTypeDefinition[]>([]);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const [closing, setClosing] = useState(false);
    const [typeDropdownOpen, setTypeDropdownOpen] = useState(false);
    const typeDropdownRef = useRef<HTMLDivElement>(null);

    // Закрытие дропдауна при клике снаружи
    useEffect(() => {
        const handleClickOutside = (e: MouseEvent) => {
            if (typeDropdownRef.current && !typeDropdownRef.current.contains(e.target as Node)) {
                setTypeDropdownOpen(false);
            }
        };
        document.addEventListener('mousedown', handleClickOutside);
        return () => document.removeEventListener('mousedown', handleClickOutside);
    }, []);

    useEffect(() => {
        if (!isOpen) {
            return;
        }
        const fetchTypes = async () => {
            const client = new Client();
            const subs = await client.getChannelSubscriptions(channelId);
            if (isDeleteMode) {
                setTypes(subs);
            } else {
                const resp = await client.getTypes();
                const subscribedIds = new Set(subs.map((s) => String(s.id)));
                setTypes(resp.types.filter((t) => !subscribedIds.has(String(t.id))));
            }
        };
        fetchTypes();
        setSelectedTypeId('');
        setError(null);
        setLoading(false);
        setTypeDropdownOpen(false);
    }, [isOpen]); // eslint-disable-line react-hooks/exhaustive-deps

    const doClose = useCallback(() => {
        dispatch(closeSubscriptionModal());
        setClosing(false);
    }, [dispatch]);

    const handleClose = useCallback(() => {
        setClosing(true);
        setTimeout(doClose, 150);
    }, [doClose]);

    const handleSubmit = useCallback(async () => {
        if (!selectedTypeId) {
            return;
        }
        setLoading(true);
        setError(null);
        try {
            const client = new Client();
            const req = {type_id: selectedTypeId, channel_id: channelId};
            if (isDeleteMode) {
                await client.deleteSubscription(req);
            } else {
                await client.createSubscription(req);
            }
            handleClose();
        } catch (err) {
            setError(intl.formatMessage({id: 'badges.error.' + (getServerErrorId(err) || 'unknown'), defaultMessage: 'Произошла ошибка'}));
        } finally {
            setLoading(false);
        }
    }, [selectedTypeId, channelId, isDeleteMode, handleClose, intl]);

    if (!isOpen && !closing) {
        return null;
    }

    const title = isDeleteMode
        ? intl.formatMessage({id: 'badges.subscription.title_delete', defaultMessage: 'Удалить подписку'})
        : intl.formatMessage({id: 'badges.subscription.title_create', defaultMessage: 'Добавить подписку'});
    const submitLabel = isDeleteMode
        ? intl.formatMessage({id: 'badges.subscription.btn_delete', defaultMessage: 'Удалить'})
        : intl.formatMessage({id: 'badges.subscription.btn_create', defaultMessage: 'Добавить'});

    const selectedType = types.find((t) => String(t.id) === selectedTypeId);

    return (
        <div className={'BadgeModal BadgeModal--compact' + (closing ? ' BadgeModal--closing' : '')}>
            <div
                className='BadgeModal__backdrop'
                onClick={handleClose}
            />
            <div className='BadgeModal__dialog'>
                <div className='BadgeModal__header'>
                    <h4>{title}</h4>
                    <button
                        className='close-btn'
                        onClick={handleClose}
                    >
                        <CloseIcon/>
                    </button>
                </div>
                <div className='BadgeModal__body'>
                    <div className='form-group'>
                        <label>
                            <FormattedMessage
                                id='badges.subscription.field_type'
                                defaultMessage='Тип достижений'
                            />
                            <span className='required'>{'*'}</span>
                        </label>
                        <div
                            className='type-select'
                            ref={typeDropdownRef}
                        >
                            <button
                                type='button'
                                className='type-select__trigger'
                                onClick={() => setTypeDropdownOpen(!typeDropdownOpen)}
                            >
                                <span className='type-select__value'>
                                    {selectedType
                                        ? selectedType.name
                                        : intl.formatMessage({id: 'badges.subscription.field_type_placeholder', defaultMessage: 'Выберите тип достижений'})
                                    }
                                </span>
                                <span className='type-select__arrow'>{'▾'}</span>
                            </button>
                            {typeDropdownOpen && (
                                <div className='type-select__dropdown'>
                                    {types.length === 0 && (
                                        <div className='type-select__option'>
                                            <FormattedMessage
                                                id='badges.subscription.no_types'
                                                defaultMessage='Нет доступных типов'
                                            />
                                        </div>
                                    )}
                                    {types.map((t) => (
                                        <div
                                            key={t.id}
                                            className={'type-select__option' + (String(t.id) === selectedTypeId ? ' type-select__option--selected' : '')}
                                            onClick={() => {
                                                setSelectedTypeId(String(t.id));
                                                setTypeDropdownOpen(false);
                                            }}
                                        >
                                            <span className='type-select__option-name'>{t.name}</span>
                                        </div>
                                    ))}
                                </div>
                            )}
                        </div>
                    </div>
                    {error && <div className='error-message'>{error}</div>}
                </div>
                <div className='BadgeModal__footer'>
                    <button
                        className='btn btn--cancel'
                        onClick={handleClose}
                    >
                        <FormattedMessage
                            id='badges.modal.btn_cancel'
                            defaultMessage='Отмена'
                        />
                    </button>
                    <button
                        className={isDeleteMode ? 'btn btn--danger' : 'btn btn--primary'}
                        onClick={handleSubmit}
                        disabled={loading || !selectedTypeId}
                    >
                        {loading
                            ? intl.formatMessage({id: 'badges.modal.btn_creating', defaultMessage: 'Сохранение...'})
                            : submitLabel
                        }
                    </button>
                </div>
            </div>
        </div>
    );
};

export default SubscriptionModal;
