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

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

import {TypeFormData} from 'types/badges';
import {isCreateTypeModalVisible, getEditTypeModalData} from 'selectors';
import {closeCreateTypeModal, closeEditTypeModal} from 'actions/actions';
import Client from 'client/api';
import {getServerErrorId} from 'utils/helpers';
import CloseIcon from 'components/icons/close_icon';
import UserMultiSelect from 'components/user_multi_select';
import ConfirmDialog from 'components/confirm_dialog/confirm_dialog';

const emptyTypeForm: TypeFormData = {
    name: '',
    everyoneCanCreate: false,
    everyoneCanGrant: false,
    allowlistCanCreate: '',
    allowlistCanGrant: '',
};

const TypeModal: React.FC = () => {
    const dispatch = useDispatch();
    const intl = useIntl();
    const createVisible = useSelector(isCreateTypeModalVisible);
    const editData = useSelector(getEditTypeModalData);
    const isOpen = createVisible || editData !== null;
    const isEditMode = editData !== null;

    const [form, setForm] = useState<TypeFormData>(emptyTypeForm);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const [confirmDelete, setConfirmDelete] = useState(false);
    const [closing, setClosing] = useState(false);

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

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

        if (isEditMode && editData) {
            setForm({
                name: editData.name,
                everyoneCanCreate: editData.can_create?.everyone || false,
                everyoneCanGrant: editData.can_grant?.everyone || false,
                allowlistCanCreate: editData.allowlist_can_create || '',
                allowlistCanGrant: editData.allowlist_can_grant || '',
            });
        } else {
            setForm(emptyTypeForm);
        }
        setError(null);
        setConfirmDelete(false);
        setLoading(false);
    }, [isOpen, isEditMode]); // eslint-disable-line react-hooks/exhaustive-deps

    const doClose = useCallback(() => {
        if (createVisible) {
            dispatch(closeCreateTypeModal());
        }
        if (editData) {
            dispatch(closeEditTypeModal());
        }
        setClosing(false);
    }, [dispatch, createVisible, editData]);

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

    const handleSubmit = useCallback(async () => {
        setLoading(true);
        setError(null);
        try {
            const client = new Client();
            const payload = {
                name: form.name.trim(),
                everyone_can_create: form.everyoneCanCreate,
                everyone_can_grant: form.everyoneCanGrant,
                allowlist_can_create: form.allowlistCanCreate.trim(),
                allowlist_can_grant: form.allowlistCanGrant.trim(),
            };
            if (isEditMode && editData) {
                await client.updateType({id: String(editData.id), ...payload});
            } else {
                await client.createType(payload);
            }
            handleClose();
        } catch (err) {
            setError(intl.formatMessage({id: 'badges.error.' + (getServerErrorId(err) || 'unknown'), defaultMessage: 'Произошла ошибка'}));
        } finally {
            setLoading(false);
        }
    }, [isEditMode, editData, form, handleClose, intl]);

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

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

    const title = isEditMode
        ? intl.formatMessage({id: 'badges.modal.edit_type_title', defaultMessage: 'Редактировать тип'})
        : intl.formatMessage({id: 'badges.modal.create_type_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' + (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.modal.field_name'
                                defaultMessage='Название'
                            />
                            <span className='required'>{'*'}</span>
                        </label>
                        <input
                            type='text'
                            value={form.name}
                            onChange={(e) => updateForm({name: 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='typeEveryoneCanCreate'
                            checked={form.everyoneCanCreate}
                            onChange={(e) => updateForm({everyoneCanCreate: e.target.checked})}
                        />
                        <label htmlFor='typeEveryoneCanCreate'>
                            <FormattedMessage
                                id='badges.modal.new_type_everyone_create'
                                defaultMessage='Все могут создавать достижения'
                            />
                        </label>
                    </div>
                    {!form.everyoneCanCreate && (
                        <div className='form-group'>
                            <label>
                                <FormattedMessage
                                    id='badges.modal.allowlist_create'
                                    defaultMessage='Список допущенных к созданию'
                                />
                            </label>
                            <UserMultiSelect
                                value={form.allowlistCanCreate}
                                onChange={(v) => updateForm({allowlistCanCreate: v})}
                            />
                            <span className='form-group__help'>
                                <FormattedMessage
                                    id='badges.modal.allowlist_create_help'
                                    defaultMessage='Пользователи, которые могут создавать достижения этого типа.'
                                />
                            </span>
                        </div>
                    )}
                    <div className='checkbox-group'>
                        <input
                            type='checkbox'
                            id='typeEveryoneCanGrant'
                            checked={form.everyoneCanGrant}
                            onChange={(e) => updateForm({everyoneCanGrant: e.target.checked})}
                        />
                        <label htmlFor='typeEveryoneCanGrant'>
                            <FormattedMessage
                                id='badges.modal.new_type_everyone_grant'
                                defaultMessage='Все могут выдавать достижения'
                            />
                        </label>
                    </div>
                    {!form.everyoneCanGrant && (
                        <div className='form-group'>
                            <label>
                                <FormattedMessage
                                    id='badges.modal.allowlist_grant'
                                    defaultMessage='Список допущенных к выдаче'
                                />
                            </label>
                            <UserMultiSelect
                                value={form.allowlistCanGrant}
                                onChange={(v) => updateForm({allowlistCanGrant: v})}
                            />
                            <span className='form-group__help'>
                                <FormattedMessage
                                    id='badges.modal.allowlist_grant_help'
                                    defaultMessage='Пользователи, которые могут выдавать достижения этого типа.'
                                />
                            </span>
                        </div>
                    )}
                    {error && <div className='error-message'>{error}</div>}
                    {isEditMode && !editData?.is_default && (
                        <div className='delete-section'>
                            <button
                                className='btn btn--danger'
                                onClick={handleDelete}
                                disabled={loading}
                            >
                                <FormattedMessage
                                    id='badges.modal.btn_delete_type'
                                    defaultMessage='Удалить тип'
                                />
                            </button>
                            {confirmDelete && (
                                <ConfirmDialog
                                    onConfirm={handleDelete}
                                    onCancel={() => setConfirmDelete(false)}
                                >
                                    <FormattedMessage
                                        id='badges.types.confirm_delete'
                                        defaultMessage='Удалить тип «{name}» и все его достижения?'
                                        values={{name: editData?.name}}
                                    />
                                </ConfirmDialog>
                            )}
                        </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.name.trim()}
                    >
                        {loading ? intl.formatMessage({id: 'badges.modal.btn_creating', defaultMessage: 'Сохранение...'}) : submitLabel}
                    </button>
                </div>
            </div>
        </div>
    );
};

export default TypeModal;
