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 {isCreateBadgeModalVisible, getEditBadgeModalData} from 'selectors';
import {closeCreateBadgeModal, closeEditBadgeModal} from 'actions/actions';
import {BadgeTypeDefinition} from 'types/badges';
import Client from 'client/api';
import {getServerErrorId} from 'utils/helpers';
import CloseIcon from 'components/icons/close_icon';
import EmojiIcon from 'components/icons/emoji_icon';
import RenderEmoji from 'components/utils/emoji';

import EmojiPickerOverlay from './emoji_picker';
import TypeSelect from './type_select';

import './badge_modal.scss';

const NEW_TYPE_VALUE = '__new__';

const BadgeModal: React.FC = () => {
    const dispatch = useDispatch();
    const intl = useIntl();
    const createVisible = useSelector(isCreateBadgeModalVisible);
    const editData = useSelector(getEditBadgeModalData);
    const channelId = useSelector((state: GlobalState) => getCurrentChannelId(state));
    const isOpen = createVisible || editData !== null;
    const isEditMode = editData !== null;
    const [name, setName] = useState('');
    const [description, setDescription] = useState('');
    const [image, setImage] = useState('');
    const [badgeType, setBadgeType] = useState('');
    const [multiple, setMultiple] = useState(false);
    const [types, setTypes] = useState<BadgeTypeDefinition[]>([]);
    const [showCreateType, setShowCreateType] = useState(false);
    const [newTypeName, setNewTypeName] = useState('');
    const [newTypeEveryoneCanCreate, setNewTypeEveryoneCanCreate] = useState(false);
    const [newTypeEveryoneCanGrant, setNewTypeEveryoneCanGrant] = useState(false);
    const [canCreateType, setCanCreateType] = useState(false);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const [confirmDelete, setConfirmDelete] = useState(false);
    const [confirmDeleteTypeId, setConfirmDeleteTypeId] = useState<string | null>(null);
    const [typeDropdownOpen, setTypeDropdownOpen] = useState(false);
    const [showEmojiPicker, setShowEmojiPicker] = useState(false);
    const dialogRef = useRef<HTMLDivElement>(null);

    const emojiData = (window as any)?.useGetEmojiSelectorData?.();
    const {
        emojiButtonRef,
        calculateRightOffSet,
    } = emojiData || {};

    useEffect(() => {
        if (!isOpen) {
            return;
        }
        const fetchTypes = async () => {
            const client = new Client();
            const resp = await client.getTypes();
            setTypes(resp.types);
            setCanCreateType(resp.can_create_type);
            if (!isEditMode && resp.types.length > 0) {
                const defaultType = resp.types.find((t) => t.is_default);
                setBadgeType(String(defaultType ? defaultType.id : resp.types[0].id));
            }
        };
        fetchTypes();

        if (isEditMode && editData) {
            setName(editData.name);
            setDescription(editData.description);
            setImage(editData.image);
            setBadgeType(String(editData.type));
            setMultiple(editData.multiple);
        } else {
            setName('');
            setDescription('');
            setImage('');
            setBadgeType('');
            setMultiple(false);
        }
        setShowCreateType(false);
        setNewTypeName('');
        setNewTypeEveryoneCanCreate(false);
        setNewTypeEveryoneCanGrant(false);
        setError(null);
        setConfirmDelete(false);
        setConfirmDeleteTypeId(null);
        setTypeDropdownOpen(false);
        setShowEmojiPicker(false);
        setLoading(false);
    }, [isOpen, isEditMode]); // eslint-disable-line react-hooks/exhaustive-deps

    const handleClose = useCallback(() => {
        if (createVisible) {
            dispatch(closeCreateBadgeModal());
        }
        if (editData) {
            dispatch(closeEditBadgeModal());
        }
    }, [dispatch, createVisible, editData]);

    const handleTypeSelect = useCallback((val: string) => {
        if (val === NEW_TYPE_VALUE) {
            setShowCreateType(true);
            setBadgeType('');
        } else {
            setShowCreateType(false);
            setBadgeType(val);
        }
        setTypeDropdownOpen(false);
        setConfirmDeleteTypeId(null);
    }, []);

    const handleEmojiSelect = (emoji: any) => {
        if (emoji.short_name) {
            setImage(emoji.short_name);
        } else if (emoji.name) {
            setImage(emoji.name);
        }
        setShowEmojiPicker(false);
    };

    const handleDeleteType = useCallback(async (typeId: string) => {
        if (confirmDeleteTypeId !== typeId) {
            setConfirmDeleteTypeId(typeId);
            return;
        }
        try {
            const client = new Client();
            await client.deleteType(typeId);
            const removeById = (t: BadgeTypeDefinition) => String(t.id) !== typeId;
            setTypes((prev) => prev.filter(removeById));
            if (badgeType === typeId) {
                setBadgeType('');
            }
        } catch (err) {
            setError(intl.formatMessage({id: 'badges.error.' + (getServerErrorId(err) || 'unknown'), defaultMessage: 'Произошла ошибка'}));
        }
        setConfirmDeleteTypeId(null);
    }, [confirmDeleteTypeId, badgeType, intl]);

    const handleSubmit = useCallback(async () => {
        setLoading(true);
        setError(null);
        try {
            const client = new Client();
            let typeID = badgeType;
            if (showCreateType) {
                if (!newTypeName.trim()) {
                    setError(intl.formatMessage({id: 'badges.modal.error_type_name_required', defaultMessage: 'Введите название типа'}));
                    setLoading(false);
                    return;
                }
                const createdType = await client.createType({
                    name: newTypeName.trim(),
                    everyone_can_create: newTypeEveryoneCanCreate,
                    everyone_can_grant: newTypeEveryoneCanGrant,
                    channel_id: channelId,
                });
                typeID = String(createdType.id);
            }
            if (!typeID) {
                setError(intl.formatMessage({id: 'badges.modal.error_type_required', defaultMessage: 'Выберите тип значка'}));
                setLoading(false);
                return;
            }
            if (isEditMode && editData) {
                await client.updateBadge({
                    id: String(editData.id),
                    name: name.trim(),
                    description: description.trim(),
                    image: image.trim(),
                    type: typeID,
                    multiple,
                });
            } else {
                await client.createBadge({
                    name: name.trim(),
                    description: description.trim(),
                    image: image.trim(),
                    type: typeID,
                    multiple,
                    channel_id: channelId,
                });
            }
            handleClose();
        } catch (err) {
            setError(intl.formatMessage({id: 'badges.error.' + (getServerErrorId(err) || 'unknown'), defaultMessage: 'Произошла ошибка'}));
        } finally {
            setLoading(false);
        }
    }, [badgeType, showCreateType, newTypeName, newTypeEveryoneCanCreate, newTypeEveryoneCanGrant, isEditMode, editData, name, description, image, multiple, handleClose, intl, channelId]);

    const handleDelete = useCallback(async () => {
        if (!editData) {
            return;
        }
        if (!confirmDelete) {
            setConfirmDelete(true);
            return;
        }
        setLoading(true);
        setError(null);
        try {
            const client = new Client();
            await client.deleteBadge(editData.id);
            handleClose();
        } catch (err) {
            setError(intl.formatMessage({id: 'badges.error.' + (getServerErrorId(err) || 'unknown'), defaultMessage: 'Произошла ошибка'}));
        } finally {
            setLoading(false);
        }
    }, [editData, confirmDelete, handleClose, intl]);

    if (!isOpen) {
        return null;
    }

    const title = isEditMode ? intl.formatMessage({id: 'badges.modal.edit_badge_title', defaultMessage: 'Редактировать значок'}) : intl.formatMessage({id: 'badges.modal.create_badge_title', defaultMessage: 'Создать значок'});
    const submitLabel = isEditMode ? intl.formatMessage({id: 'badges.modal.btn_save', defaultMessage: 'Сохранить'}) : intl.formatMessage({id: 'badges.modal.btn_create', defaultMessage: 'Создать'});

    return (
        <div className='BadgeModal'>
            <div
                className='BadgeModal__backdrop'
                onClick={handleClose}
            />
            <div
                className='BadgeModal__dialog'
                ref={dialogRef}
            >
                <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.modal.field_name'
                                defaultMessage='Название'
                            />
                        </label>
                        <input
                            type='text'
                            value={name}
                            onChange={(e) => setName(e.target.value)}
                            maxLength={20}
                            placeholder={intl.formatMessage({id: 'badges.modal.field_name_placeholder', defaultMessage: 'Название значка (макс. 20 символов)'})}
                        />
                    </div>
                    <div className='form-group'>
                        <label>
                            <FormattedMessage
                                id='badges.modal.field_description'
                                defaultMessage='Описание'
                            />
                        </label>
                        <textarea
                            value={description}
                            onChange={(e) => setDescription(e.target.value)}
                            maxLength={120}
                            placeholder={intl.formatMessage({id: 'badges.modal.field_description_placeholder', defaultMessage: 'Описание значка (макс. 120 символов)'})}
                        />
                    </div>
                    <div className='form-group'>
                        <label>
                            <FormattedMessage
                                id='badges.modal.field_image'
                                defaultMessage='Эмодзи'
                            />
                        </label>
                        <div className='emoji-input'>
                            <button
                                type='button'
                                className='emoji-input__icon'
                                onClick={() => setShowEmojiPicker((prev) => !prev)}
                                ref={emojiButtonRef}
                            >
                                <EmojiIcon/>
                            </button>
                            {image && (
                                <RenderEmoji
                                    emojiName={image}
                                    size={20}
                                />
                            )}
                            <input
                                type='text'
                                value={image}
                                onChange={(e) => setImage(e.target.value)}
                                placeholder={intl.formatMessage({id: 'badges.modal.field_image_placeholder', defaultMessage: 'Название эмодзи (напр. star)'})}
                            />
                        </div>
                        {showEmojiPicker && (
                            <EmojiPickerOverlay
                                target={() => emojiButtonRef?.current}
                                container={() => dialogRef.current}
                                show={showEmojiPicker}
                                onHide={() => setShowEmojiPicker(false)}
                                onEmojiClick={handleEmojiSelect}
                                rightOffset={calculateRightOffSet?.(emojiButtonRef?.current)}
                                defaultHorizontalPosition='right'
                                hideCustomEmojiButton={true}
                            />
                        )}
                    </div>
                    <div className='form-group'>
                        <label>
                            <FormattedMessage
                                id='badges.modal.field_type'
                                defaultMessage='Тип'
                            />
                        </label>
                        <TypeSelect
                            types={types}
                            badgeType={badgeType}
                            showCreateType={showCreateType}
                            canCreateType={canCreateType}
                            typeDropdownOpen={typeDropdownOpen}
                            confirmDeleteTypeId={confirmDeleteTypeId}
                            onToggleDropdown={() => setTypeDropdownOpen(!typeDropdownOpen)}
                            onSelect={handleTypeSelect}
                            onDeleteType={handleDeleteType}
                            onCancelDeleteType={() => setConfirmDeleteTypeId(null)}
                        />
                        {showCreateType && (
                            <div className='inline-type-section'>
                                <div className='form-group'>
                                    <label>
                                        <FormattedMessage
                                            id='badges.modal.new_type_name'
                                            defaultMessage='Название типа'
                                        />
                                    </label>
                                    <input
                                        type='text'
                                        value={newTypeName}
                                        onChange={(e) => setNewTypeName(e.target.value)}
                                        maxLength={20}
                                        placeholder={intl.formatMessage({id: 'badges.modal.new_type_name_placeholder', defaultMessage: 'Название типа (макс. 20 символов)'})}
                                    />
                                </div>
                                <div className='checkbox-group'>
                                    <input
                                        type='checkbox'
                                        id='newTypeEveryoneCanCreate'
                                        checked={newTypeEveryoneCanCreate}
                                        onChange={(e) => setNewTypeEveryoneCanCreate(e.target.checked)}
                                    />
                                    <label htmlFor='newTypeEveryoneCanCreate'>
                                        <FormattedMessage
                                            id='badges.modal.new_type_everyone_create'
                                            defaultMessage='Все могут создавать значки'
                                        />
                                    </label>
                                </div>
                                <div className='checkbox-group'>
                                    <input
                                        type='checkbox'
                                        id='newTypeEveryoneCanGrant'
                                        checked={newTypeEveryoneCanGrant}
                                        onChange={(e) => setNewTypeEveryoneCanGrant(e.target.checked)}
                                    />
                                    <label htmlFor='newTypeEveryoneCanGrant'>
                                        <FormattedMessage
                                            id='badges.modal.new_type_everyone_grant'
                                            defaultMessage='Все могут выдавать значки'
                                        />
                                    </label>
                                </div>
                            </div>
                        )}
                    </div>
                    <div className='checkbox-group'>
                        <input
                            type='checkbox'
                            id='badgeMultiple'
                            checked={multiple}
                            onChange={(e) => setMultiple(e.target.checked)}
                        />
                        <label htmlFor='badgeMultiple'>
                            <FormattedMessage
                                id='badges.modal.field_multiple'
                                defaultMessage='Можно выдавать несколько раз'
                            />
                        </label>
                    </div>
                    {error && <div className='error-message'>{error}</div>}
                    {isEditMode && (
                        <div className='delete-section'>
                            {confirmDelete ? (
                                <div className='confirm-delete'>
                                    <span>
                                        <FormattedMessage
                                            id='badges.modal.confirm_delete'
                                            defaultMessage='Вы уверены?'
                                        />
                                    </span>
                                    <button
                                        className='btn btn--danger'
                                        onClick={handleDelete}
                                        disabled={loading}
                                    >
                                        <FormattedMessage
                                            id='badges.modal.btn_confirm_delete'
                                            defaultMessage='Да, удалить'
                                        />
                                    </button>
                                    <button
                                        className='btn btn--cancel'
                                        onClick={() => setConfirmDelete(false)}
                                    >
                                        <FormattedMessage
                                            id='badges.modal.btn_cancel'
                                            defaultMessage='Отмена'
                                        />
                                    </button>
                                </div>
                            ) : (
                                <button
                                    className='btn btn--danger'
                                    onClick={handleDelete}
                                    disabled={loading}
                                >
                                    <FormattedMessage
                                        id='badges.modal.btn_delete'
                                        defaultMessage='Удалить значок'
                                    />
                                </button>
                            )}
                        </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 || !name.trim() || !image.trim()}
                    >
                        {loading ? intl.formatMessage({id: 'badges.modal.btn_creating', defaultMessage: 'Сохранение...'}) : submitLabel}
                    </button>
                </div>
            </div>
        </div>
    );
};

export default BadgeModal;
