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 {Client4} from 'mattermost-redux/client';

import {closeGrantModal} from 'actions/actions';
import {getGrantModalData} from 'selectors';
import {AllBadgesBadge} from 'types/badges';
import Client from 'client/api';
import {getServerErrorId, getUserDisplayName} from 'utils/helpers';
import CloseIcon from 'components/icons/close_icon';
import RenderEmoji from 'components/emoji/emoji';

type GrantFormData = {
    badgeId: string;
    userId: string;
    userDisplayName: string;
    reason: string;
    notifyHere: boolean;
}

const emptyForm: GrantFormData = {
    badgeId: '',
    userId: '',
    userDisplayName: '',
    reason: '',
    notifyHere: false,
};

const GrantModal: React.FC = () => {
    const dispatch = useDispatch();
    const intl = useIntl();
    const modalData = useSelector(getGrantModalData);
    const channelId = useSelector((state: GlobalState) => getCurrentChannelId(state));
    const isOpen = modalData !== null;
    const hasFixedUser = Boolean(modalData?.prefillUser);

    const [form, setForm] = useState<GrantFormData>(emptyForm);
    const [badges, setBadges] = useState<AllBadgesBadge[]>([]);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const [closing, setClosing] = useState(false);

    // Выбор достижения
    const [badgeDropdownOpen, setBadgeDropdownOpen] = useState(false);
    const badgeDropdownRef = useRef<HTMLDivElement>(null);

    const updateForm = useCallback((updates: Partial<GrantFormData>) => {
        setForm((prev) => ({...prev, ...updates}));
    }, []);

    useEffect(() => {
        if (!isOpen) {
            return;
        }

        // Всегда очищаем форму при открытии
        setForm(emptyForm);
        setError(null);
        setLoading(false);
        setBadgeDropdownOpen(false);

        const fetchBadges = async () => {
            const client = new Client();
            const allBadges = await client.getAllBadges();
            setBadges(allBadges);
        };
        fetchBadges();

        // Prefill достижения, если передан
        if (modalData?.prefillBadgeId) {
            setForm((prev) => ({...prev, badgeId: modalData.prefillBadgeId || ''}));
        }

        // Prefill пользователя, если передан
        if (modalData?.prefillUser) {
            Client4.getUserByUsername(modalData.prefillUser).then((user) => {
                setForm((prev) => ({
                    ...prev,
                    userId: user.id,
                    userDisplayName: getUserDisplayName(user) || user.username,
                }));
            }).catch(() => {
                // Если пользователь не найден — игнорируем
            });
        }
    }, [isOpen]); // eslint-disable-line react-hooks/exhaustive-deps

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

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

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

    const handleBadgeSelect = (badgeId: string) => {
        updateForm({badgeId});
        setBadgeDropdownOpen(false);
    };

    const handleSubmit = useCallback(async () => {
        setLoading(true);
        setError(null);
        try {
            const client = new Client();
            await client.grantBadge({
                badge_id: form.badgeId,
                user_id: form.userId,
                reason: form.reason.trim(),
                notify_here: form.notifyHere,
                channel_id: channelId,
            });
            handleClose();
        } catch (err) {
            setError(intl.formatMessage({id: 'badges.error.' + (getServerErrorId(err) || 'unknown'), defaultMessage: 'Произошла ошибка'}));
        } finally {
            setLoading(false);
        }
    }, [form, channelId, handleClose, intl]);

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

    const selectedBadge = badges.find((b) => String(b.id) === form.badgeId);

    return (
        <div className={'BadgeModal' + (closing ? ' BadgeModal--closing' : '')}>
            <div
                className='BadgeModal__backdrop'
                onClick={handleClose}
            />
            <div className='BadgeModal__dialog'>
                <div className='BadgeModal__header'>
                    <h4>
                        <FormattedMessage
                            id='badges.grant.title'
                            defaultMessage='Выдать достижение'
                        />
                    </h4>
                    <button
                        className='close-btn'
                        onClick={handleClose}
                    >
                        <CloseIcon/>
                    </button>
                </div>
                <div className='BadgeModal__body'>
                    {hasFixedUser && form.userDisplayName && (
                        <p className='grant-intro'>
                            <FormattedMessage
                                id='badges.grant.intro'
                                defaultMessage='Выдать достижение пользователю @{username}'
                                values={{username: modalData?.prefillUser || ''}}
                            />
                        </p>
                    )}
                    <div className='form-group'>
                        <label>
                            <FormattedMessage
                                id='badges.grant.field_badge'
                                defaultMessage='Достижение'
                            />
                            <span className='required'>{'*'}</span>
                        </label>
                        <div
                            className='type-select'
                            ref={badgeDropdownRef}
                        >
                            <button
                                type='button'
                                className='type-select__trigger'
                                onClick={() => setBadgeDropdownOpen(!badgeDropdownOpen)}
                            >
                                <span className='type-select__value'>
                                    {selectedBadge ? (
                                        <>
                                            <RenderEmoji
                                                emojiName={selectedBadge.image}
                                                size={16}
                                            />
                                            {' '}{selectedBadge.name}
                                        </>
                                    ) : intl.formatMessage({id: 'badges.grant.field_badge_placeholder', defaultMessage: 'Выберите достижение'})}
                                </span>
                                <span className='type-select__arrow'>{'▾'}</span>
                            </button>
                            {badgeDropdownOpen && (
                                <div className='type-select__dropdown'>
                                    {badges.length === 0 && (
                                        <div className='type-select__option'>
                                            <FormattedMessage
                                                id='badges.grant.no_badges'
                                                defaultMessage='Нет доступных достижений'
                                            />
                                        </div>
                                    )}
                                    {badges.map((badge) => (
                                        <div
                                            key={badge.id}
                                            className={'type-select__option' + (String(badge.id) === form.badgeId ? ' type-select__option--selected' : '')}
                                            onClick={() => handleBadgeSelect(String(badge.id))}
                                        >
                                            <span className='type-select__option-name'>
                                                <RenderEmoji
                                                    emojiName={badge.image}
                                                    size={16}
                                                />
                                                {' '}{badge.name}
                                            </span>
                                            <span style={{opacity: 0.56, fontSize: '12px'}}>{badge.type_name}</span>
                                        </div>
                                    ))}
                                </div>
                            )}
                        </div>
                    </div>
                    <div className='form-group'>
                        <label>
                            <FormattedMessage
                                id='badges.grant.field_reason'
                                defaultMessage='Причина'
                            />
                        </label>
                        <textarea
                            value={form.reason}
                            onChange={(e) => updateForm({reason: e.target.value})}
                            maxLength={200}
                            placeholder={intl.formatMessage({id: 'badges.grant.field_reason_placeholder', defaultMessage: 'За что выдаётся достижение? (необязательно)'})}
                        />
                    </div>
                    <div className='checkbox-group'>
                        <input
                            type='checkbox'
                            id='grantNotifyHere'
                            checked={form.notifyHere}
                            onChange={(e) => updateForm({notifyHere: e.target.checked})}
                        />
                        <label htmlFor='grantNotifyHere'>
                            <FormattedMessage
                                id='badges.grant.notify_here'
                                defaultMessage='Уведомить в канале'
                            />
                        </label>
                    </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='btn btn--primary'
                        onClick={handleSubmit}
                        disabled={loading || !form.badgeId || !form.userId}
                    >
                        {loading
                            ? intl.formatMessage({id: 'badges.modal.btn_creating', defaultMessage: 'Сохранение...'})
                            : intl.formatMessage({id: 'badges.grant.btn_grant', defaultMessage: 'Выдать'})
                        }
                    </button>
                </div>
            </div>
        </div>
    );
};

export default GrantModal;
