import React, {ChangeEvent, useState } from 'react';
import { TabView, TabPanel } from 'primereact/tabview';
import { Button } from 'primereact/button';
import { Dialog } from 'primereact/dialog';
import { InputText } from 'primereact/inputtext';
import { Dropdown } from 'primereact/dropdown';
import { Language, NameItem, NameType } from '../../api/models/Types.tsx';
import { Divider } from 'primereact/divider';

interface INamesEditComponentProps {
    names: NameItem[];
    languages: Language[];
    onAdd: (name: NameItem) => Promise<string | undefined>;
    onEdit: (name: NameItem, newValue: string | null, newLanguage: Language | null) => Promise<string | undefined>;
    onDelete: (name: NameItem) => Promise<string | undefined>;
}

const NamesEditComponent: React.FC<INamesEditComponentProps> = ({ names, languages, onAdd, onEdit, onDelete }) => {
    const [dialogItem, setDialogItem] = useState<NameItem | null>(null);
    const [nameLanguageIdValue, setNameLanguageIdValue] = useState<[languageId: string | null, name: string | null]>();
    const [addDialogVisible, setAddDialogVisible] = useState(false);
    const [editDialogVisible, setEditDialogVisible] = useState(false);
    const [deleteDialogVisible, setDeleteDialogVisible] = useState(false);
    const [waitingForAction, setWaitingForAction] = useState(false);

    const showAddNameDialog = (nameType: NameType) => {
        setDialogItem({ value: '', type: nameType, language: languages[0] } as NameItem);
        setAddDialogVisible(true);
    }

    const selectLanguage = (id?: string | null) => {
        setNameLanguageIdValue(
            [
                (id == nameLanguageIdValue?.[0] ? null : id) ?? null,
                nameLanguageIdValue?.[1] ?? null,
            ]
        );
    };

    const onNameChange = (event : ChangeEvent<HTMLInputElement>) => {
        setNameLanguageIdValue(
            [
                nameLanguageIdValue?.[0] ?? null,
                event.target.value ?? null,
            ]
        );
    }
    
    return (
        <>
            <TabView className='border-2 border-200 border-round' panelContainerClassName='p-2'>
                <TabPanel header='Оригинальное название'>
                    {!names.some(n => n.type === NameType.Original) && (
                        <Button
                            icon='pi pi-plus'
                            label='Создать оригинальное название'
                            onClick={() => showAddNameDialog(NameType.Original)}
                        />
                    )}
                    {names.filter(n => n.type === NameType.Original).map(name =>
                        showNameItem(name,
                            () => { setDialogItem(name); setNameLanguageIdValue( [ name.language.id, name.value ] ); setEditDialogVisible(true); },
                            () => { setDialogItem(name); setDeleteDialogVisible(true); })
                    )}
                </TabPanel>

                {[
                    { type: NameType.OriginalInAnotherLanguage, header: 'Оригинальные названия на других языках' },
                    { type: NameType.Translation, header: 'Переведённые названия' },
                    { type: NameType.Abbreviation, header: 'Аббривеатуры' }
                ].map(({ type, header }) => (
                    <TabPanel key={type} header={header}>
                        <div className='flex flex-row justify-content-end'>
                            <Button
                                icon='pi pi-plus'
                                // label={`Добавить ${header.toLowerCase()}`}
                                label={`Добавить ${ type === NameType.Abbreviation ? 'аббривеатуру' : 'название'}`}
                                size='small'
                                onClick={() => showAddNameDialog(type)}
                            />
                        </div>

                        {names.some(n => n.type === type) &&
                            <Divider className='my-2' />
                        }
                        
                        {names.filter(n => n.type === type).map(name =>
                            showNameItem(name,
                                () => { setDialogItem(name); setNameLanguageIdValue( [ name.language.id, name.value ] ); setEditDialogVisible(true); },
                                () => { setDialogItem(name); setDeleteDialogVisible(true); })
                        )}
                    </TabPanel>
                ))}
            </TabView>

            <Dialog header='Добавить название'
                    headerClassName='p-3 pb-1'
                    contentClassName='p-3 pt-0'
                    visible={addDialogVisible} onHide={() => setAddDialogVisible(false)}>
                <div className='p-fluid'>
                    <label htmlFor='name'>Название</label>
                    <InputText id='name' className='mb-2' value={dialogItem?.value || ''} autoComplete='off'
                               onChange={(e) => setDialogItem({ ...dialogItem!, value: e.target.value })} />

                    <label htmlFor='language'>Язык</label>
                    <Dropdown id='language' value={dialogItem?.language} options={languages} optionLabel='name'
                              onChange={(e) => setDialogItem({ ...dialogItem!, language: e.value })} />
                </div>

                <Button label='Сохранить' className='w-full mt-4' loading={waitingForAction} onClick={() => {
                    setWaitingForAction(true);
                    if (dialogItem) {
                        onAdd(dialogItem)
                            .then(() => {
                                setAddDialogVisible(false);
                            })
                            .finally(() => setWaitingForAction(false));
                    }
                }} />
            </Dialog>
            
            <Dialog header='Редактировать название'
                    headerClassName='p-3 pb-1'
                    contentClassName='p-3 pt-0'
                    visible={editDialogVisible} onHide={() => setEditDialogVisible(false)}>
                <div className='p-fluid'>
                    <label htmlFor='name'>Название</label>
                    <InputText id='name' className='mb-2' value={nameLanguageIdValue?.[1] || ''} autoComplete='off' onChange={onNameChange} />

                    <label htmlFor='language'>Язык</label>
                    <Dropdown id='language' value={dialogItem?.language} options={languages} optionLabel='name'
                              onChange={(e) => selectLanguage(e.target.value)} />
                </div>

                <Button label='Сохранить' className='w-full mt-4' loading={waitingForAction} onClick={() => {
                    setWaitingForAction(true);
                    if (dialogItem) {
                        onEdit(dialogItem, nameLanguageIdValue![1], languages?.find(q => q.id == nameLanguageIdValue![0]) ?? null)
                            .then(() => {
                                setEditDialogVisible(false);
                            })
                            .finally(() => setWaitingForAction(false));
                    }
                }} />
            </Dialog>

            {/* Диалог для удаления */}
            <Dialog header='Подтверждение удаления'
                    headerClassName='p-3 pb-1'
                    contentClassName='p-3 pt-0'
                    visible={deleteDialogVisible} onHide={() => setDeleteDialogVisible(false)}>
                <p>Вы уверены, что хотите удалить '{dialogItem?.value}'?</p>
                <Button label='Удалить' severity='danger' className='w-full mt-1' loading={waitingForAction} onClick={() => {
                    setWaitingForAction(true);
                    if (dialogItem) {
                        onDelete(dialogItem)
                            .then(() => {
                                setDeleteDialogVisible(false);
                            })
                            .finally(() => setWaitingForAction(false));
                    }
                }} />
            </Dialog>
        </>
    );
};

function showNameItem(name: NameItem, onBtnEditClicked: () => void, onBtnDeleteClicked: () => void) {
    return (
        <div key={name.value} className='flex flex-row justify-content-between align-items-center 
        border-2 border-200 border-dotted border-round pl-2'>
            <div>
                <span className='select-all'>{name.value}</span> [<span className='select-all'>{name.language.codeIso3}</span>]
            </div>
            <div className='flex gap-2'>
                <Button icon='pi pi-pencil' size='small' severity='secondary' onClick={() => onBtnEditClicked()} />
                <Button icon='pi pi-trash' size='small' severity='danger' onClick={() => onBtnDeleteClicked()} />
            </div>
        </div>
    );
}

export default NamesEditComponent;