import { useState } from 'react';
import { DataTable } from 'primereact/datatable';
import { Column } from 'primereact/column';
import { InputText } from 'primereact/inputtext';
import { Button } from 'primereact/button';
import { Dialog } from 'primereact/dialog';
import { Card } from 'primereact/card';
import { FloatLabel } from 'primereact/floatlabel';
import { Message } from 'primereact/message';

import { IconField } from 'primereact/iconfield';
import { InputIcon } from 'primereact/inputicon';

import { Language } from '../../../../api/models/Types.tsx';
import { CreateLanguage, DeleteLanguage, EditLanguage, GetLanguageList } from '../../../../api/LanguageApi.tsx';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { ProgressSpinner } from 'primereact/progressspinner';

export const LanguageList = () => {
    const languageQueryKey = 'languages';
    const queryClient = useQueryClient();
    const { data: languages, isLoading, isError } = useQuery({queryKey: [ languageQueryKey ], queryFn: GetLanguageList });
    const [filter, setFilter] = useState('');
    const [selectedLanguage, setSelectedLanguage] = useState<Language | null>(null);
    const [newLanguage, setNewLanguage] = useState({ codeIso3: '', name: '' });
    const [isCreateDialogVisible, setIsCreateDialogVisible] = useState(false);
    const [isEditDialogVisible, setIsEditDialogVisible] = useState(false);
    const [isDeleteDialogVisible, setIsDeleteDialogVisible] = useState(false);
    const [editingLanguageOriginalName, setEditingLanguageOriginalName] = useState<string | null>(null);
    const [errorMessage, setErrorMessage] = useState<string | null>(null);
    
    const addLanguageMutation = useMutation({
        mutationFn: ({ codeIso3, name }: { codeIso3: string; name: string }) =>
            CreateLanguage(codeIso3, name),
        onSuccess: () => {
            queryClient.invalidateQueries({ queryKey: [ languageQueryKey ] });
            setNewLanguage({ codeIso3: '', name: '' });
            setIsCreateDialogVisible(false);
            setErrorMessage(null);
        },
        onError: (error) => {
            setErrorMessage(error?.toString() ?? 'Ошибка при добавлении языка');
        },
    });
    
    const editLanguageMutation = useMutation({
        mutationFn: ({ id, codeIso3, name }: Language) =>
            EditLanguage(id, codeIso3, name),
        onSuccess: () => {
            queryClient.invalidateQueries({ queryKey: [ languageQueryKey ] });
            setSelectedLanguage(null);
            setIsEditDialogVisible(false);
            setEditingLanguageOriginalName(null);
        },
    });
    
    const deleteLanguageMutation = useMutation({
        mutationFn: (id: string) => DeleteLanguage(id),
        onSuccess: () => {
            // Удаление из кэша после успешного удаления
            // queryClient.setQueryData(['languages'], (old: Language[] | undefined) =>
            //     old ? old.filter((lang) => lang.id !== selectedLanguage?.id) : []
            // );
            queryClient.invalidateQueries({ queryKey: [ languageQueryKey ] });
            setSelectedLanguage(null);
            setIsDeleteDialogVisible(false);
        },
    });

    // Добавление языка
    const handleAddLanguage = async () => {
        addLanguageMutation.mutate(newLanguage);
    };

    // Редактирование языка
    const handleEditLanguage = async () => {
        if (selectedLanguage) {
            editLanguageMutation.mutate(selectedLanguage);
        }
    };

    // Удаление языка
    const handleDeleteLanguage = async () => {
        if (selectedLanguage) {
            deleteLanguageMutation.mutate(selectedLanguage.id);
        }
    };

    // Фильтр языков
    // const filteredLanguages = languages.filter(
    const filteredLanguages = (languages || []).filter(
        (lang) =>
            lang.codeIso3.toLowerCase().includes(filter.toLowerCase()) ||
            lang.name.toLowerCase().includes(filter.toLowerCase())
    );

    return (
        <div className='grid justify-center align-center'>
            <Card
                className='shadow-2 w-full mx-2'
                header={() => (
                    <div className='grid align-center justify-content-between m-0 surface-100 px-2'
                         style={{borderRadius: '6px 6px 0 0' }}>
                        <div className='col-12 md:col-5 align-content-center'>
                            <h3 className='my-0'>Языки</h3>
                        </div>
                        <div className='col-12 md:col-7 xl:col-5 md:max-w-max align-content-center'>
                            <Button
                                label='Добавить язык'
                                icon='pi pi-plus'
                                className="p-button-success w-full"
                                size='small'
                                onClick={() => setIsCreateDialogVisible(true)}
                            />
                        </div>
                        <div className='col-12 px-2 align-content-center pt-0'>
                            <IconField iconPosition='left'>
                                <InputIcon className='pi pi-search'> </InputIcon>
                                <InputText
                                    value={filter}
                                    onChange={(e) => setFilter(e.target.value)}
                                    placeholder='Поиск по коду или названию'
                                    className="w-full p-inputtext-sm"
                                />
                            </IconField>
                        </div>
                    </div>
                )}
            >
                {isLoading && (
                    <div className="flex justify-content-center align-items-center" style={{ height: '300px' }}>
                        <ProgressSpinner />
                    </div>
                )}

                {isError && (
                    <div className="p-0">
                        <Message severity="error" text="Ошибка при загрузке данных. Пожалуйста, попробуйте позже." />
                    </div>
                )}

                {(!isLoading && !isError) &&
                    <DataTable
                        value={filteredLanguages}
                        scrollable
                        style={{height:"300px"}}
                        scrollHeight="300px"
                        size="small"
                        stripedRows
                    >
                        <Column field='codeIso3' header='Код ISO 639.2' headerClassName="surface-100" />
                        <Column field='name' header='Название' headerClassName='surface-100' />
                        <Column
                            header=''
                            headerClassName='surface-100'
                            body={(rowData) => (
                                <div className='flex justify-content-end gap-3'>
                                    <Button
                                        icon='pi pi-pencil'
                                        outlined
                                        onClick={() => {
                                            setEditingLanguageOriginalName(rowData.name);
                                            setSelectedLanguage(rowData);
                                            setIsEditDialogVisible(true);
                                        }}
                                        size='small'
                                    />
                                    <Button
                                        icon='pi pi-trash'
                                        severity='danger'
                                        outlined
                                        onClick={() => {
                                            setSelectedLanguage(rowData);
                                            setIsDeleteDialogVisible(true);
                                        }}
                                        size='small'
                                    />
                                </div>
                            )}
                        />
                    </DataTable>
                }
            </Card>

            {/* Диалог добавления языка */}
            <Dialog
                header='Добавление языка'
                headerClassName='p-3 pb-1'
                contentClassName='p-3 pt-0'
                visible={isCreateDialogVisible}
                onHide={() => {
                    setIsCreateDialogVisible(false);
                    setErrorMessage(null); // Убираем сообщение об ошибке при закрытии
                }}
            >
                <div className='field my-5'>
                    <FloatLabel>
                        <InputText
                            id='codeIso3'
                            value={newLanguage.codeIso3}
                            maxLength={3}
                            onChange={(e) =>
                                setNewLanguage({ ...newLanguage, codeIso3: e.target.value.toUpperCase() })
                            }
                            placeholder='Код ISO 639.2 Alpha-3'
                            className='w-full p-inputtext-sm'
                        />
                        <label htmlFor='codeIso3'>Код (3 символа)</label>
                    </FloatLabel>
                </div>
                <div className='field mt-5'>
                    <FloatLabel>
                        <InputText
                            id='name'
                            value={newLanguage.name}
                            onChange={(e) =>
                                setNewLanguage({ ...newLanguage, name: e.target.value })
                            }
                            placeholder='Название'
                            className='w-full p-inputtext-sm'
                        />
                        <label htmlFor='name'>Название</label>
                    </FloatLabel>
                </div>
                {errorMessage && <Message severity='error' text={errorMessage} className='mb-3' />}
                <Button
                    label='Сохранить'
                    icon='pi pi-save'
                    className='w-full'
                    disabled={newLanguage.codeIso3.length !== 3 || newLanguage.name === ''}
                    size='small'
                    onClick={handleAddLanguage}
                />
            </Dialog>

            {/* Диалог редактирования языка */}
            {selectedLanguage && (
                <Dialog
                    header='Редактирование языка'
                    headerClassName='p-3 pb-1'
                    contentClassName='p-3 pt-0'
                    visible={isEditDialogVisible}
                    onHide={() => {
                        if (editingLanguageOriginalName != null && editingLanguageOriginalName.length > 0) {
                            setSelectedLanguage({
                                ...selectedLanguage,
                                name: editingLanguageOriginalName,
                            });
                            setEditingLanguageOriginalName(null);
                        }

                        setIsEditDialogVisible(false);
                    }}
                >
                    <div className='field'>
                        <p>[<strong>{selectedLanguage.codeIso3}</strong>] <strong>{editingLanguageOriginalName}</strong></p>
                    </div>
                    <div className='field mt-5'>
                        <FloatLabel>
                            <InputText
                                id='edit-name'
                                value={selectedLanguage.name}
                                onChange={(e) =>
                                    setSelectedLanguage({
                                        ...selectedLanguage,
                                        name: e.target.value,
                                    })
                                }
                                placeholder='Новое название'
                                className='w-full p-inputtext-sm'
                            />
                            <label htmlFor='edit-name'>Новое название</label>
                        </FloatLabel>
                    </div>
                    <Button
                        label='Сохранить'
                        icon='pi pi-save'
                        className='w-full'
                        disabled={!selectedLanguage.name.trim()}
                        onClick={handleEditLanguage}
                        size='small'
                    />
                </Dialog>
            )}

            {/* Диалог удаления языка */}
            {selectedLanguage && (
                <Dialog
                    header='Удаление языка'
                    headerClassName='p-3 pb-1'
                    contentClassName='p-3 pt-0'
                    visible={isDeleteDialogVisible}
                    onHide={() => {
                        setIsDeleteDialogVisible(false);
                    }}
                >
                    <p>Удалить язык: [<strong>{selectedLanguage.codeIso3}</strong>] <strong>{editingLanguageOriginalName}</strong>?</p>
                    
                    <Button
                        label='Удалить'
                        icon='pi pi-trash'
                        iconPos='right'
                        className='w-full'
                        severity='danger'
                        onClick={handleDeleteLanguage}
                    />
                </Dialog>
            )}
        </div>
    );
};

export default LanguageList;