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 {Genre} from "../../../../api/models/Types.tsx";
import { CreateGenre, DeleteGenre, EditGenre, GetGenreList } from "../../../../api/GenreApi.tsx";
import {useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { ProgressSpinner } from 'primereact/progressspinner';

export const GenreList = () => {
    const genreQueryKey = 'genrees';
    const queryClient = useQueryClient();
    const { data: genres, isLoading, isError } = useQuery({queryKey: [ genreQueryKey ], queryFn: GetGenreList });

    const [filter, setFilter] = useState('');
    const [selectedGenre, setSelectedGenre] = useState<Genre | null>(null);
    const [newGenre, setNewGenre] = useState('');
    const [isCreateDialogVisible, setIsCreateDialogVisible] = useState(false);
    const [isEditDialogVisible, setIsEditDialogVisible] = useState(false);
    const [isDeleteDialogVisible, setIsDeleteDialogVisible] = useState(false);
    const [editingGenreOriginalName, setEditingGenreOriginalName] = useState<string | null>(null);
    const [errorMessage, setErrorMessage] = useState<string | null>(null);

    const addGenreMutation = useMutation({
        mutationFn: (name: string) =>
            CreateGenre(name),
        onSuccess: () => {
            queryClient.invalidateQueries({ queryKey: [ genreQueryKey ] });
            setNewGenre('');
            setIsCreateDialogVisible(false);
            setErrorMessage(null);
        },
        onError: (error) => {
            setErrorMessage(error?.toString() ?? 'Ошибка при добавлении языка');
        },
    });

    const editGenreMutation = useMutation({
        mutationFn: ({ id, name }: Genre) =>
            EditGenre(id, name),
        onSuccess: () => {
            queryClient.invalidateQueries({ queryKey: [ genreQueryKey ] });
            setSelectedGenre(null);
            setIsEditDialogVisible(false);
            setEditingGenreOriginalName(null);
        },
    });

    const deleteGenreMutation = useMutation({
        mutationFn: (id: string) => DeleteGenre(id),
        onSuccess: () => {
            queryClient.invalidateQueries({ queryKey: [ genreQueryKey ] });
            setSelectedGenre(null);
            setIsDeleteDialogVisible(false);
        },
    });

    // Добавление жанра
    const handleAddGenre = async () => {
        addGenreMutation.mutate(newGenre);
    };

    // Редактирование жанра
    const handleEditGenre = async () => {
        if (selectedGenre) {
            editGenreMutation.mutate(selectedGenre);
        }
    };

    // Удаление жанра
    const handleDeleteGenre = async () => {
        if (selectedGenre) {
            deleteGenreMutation.mutate(selectedGenre.id);
        }
    };

    // Фильтр жанров
    const filteredGenres = (genres || []).filter((genre) =>
        genre.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={filteredGenres}
                        scrollable
                        size="small"
                        style={{height:"300px"}}
                        scrollHeight="300px"
                        stripedRows
                    >
                        <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={() => {
                                            setSelectedGenre(rowData);
                                            setEditingGenreOriginalName(rowData.name);
                                            setIsEditDialogVisible(true);
                                        }}
                                        size="small"
                                    />
                                    <Button
                                        icon="pi pi-trash"
                                        severity="danger"
                                        outlined
                                        onClick={() => {
                                            setSelectedGenre(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 mt-5'>
                    <FloatLabel>
                        <InputText
                            id='new-genre'
                            value={newGenre}
                            onChange={(e) => setNewGenre(e.target.value)}
                            placeholder='Название жанра'
                            className='w-full p-inputtext-sm'
                        />
                        <label htmlFor="new-genre">Название</label>
                    </FloatLabel>
                </div>
                {errorMessage && <Message severity='error' text={errorMessage} className='mb-3' />}
                <Button
                    label='Сохранить'
                    icon='pi pi-save'
                    className='w-full'
                    disabled={newGenre.trim() === ''}
                    size='small'
                    onClick={handleAddGenre}
                />
            </Dialog>

            {/* Диалог редактирования жанра */}
            {selectedGenre && (
                <Dialog
                    header="Редактирование жанра"
                    headerClassName='p-3 pb-1'
                    contentClassName='p-3 pt-0'
                    visible={isEditDialogVisible}
                    onHide={() => {
                        if (editingGenreOriginalName != null && editingGenreOriginalName.length > 0) {
                            setSelectedGenre({
                                ...selectedGenre,
                                name: editingGenreOriginalName,
                            });
                            setEditingGenreOriginalName(null);
                        }
                        
                        setIsEditDialogVisible(false);
                    }}
                >
                    <div className='field'>
                        <p><strong>{editingGenreOriginalName}</strong></p>
                    </div>
                    <div className="field mt-5">
                        <FloatLabel>
                            <InputText
                                id="edit-genre"
                                value={selectedGenre.name}
                                onChange={(e) =>
                                    setSelectedGenre({
                                        ...selectedGenre,
                                        name: e.target.value,
                                    })
                                }
                                placeholder="Новое название"
                                className='w-full p-inputtext-sm'
                            />
                            <label htmlFor="edit-genre">Новое название</label>
                        </FloatLabel>
                    </div>
                    <Button
                        label="Сохранить"
                        icon="pi pi-save"
                        className="w-full"
                        disabled={!selectedGenre.name.trim()}
                        onClick={handleEditGenre}
                        size='small'
                    />
                </Dialog>
            )}

            {/* Диалог удаления жанра */}
            {selectedGenre && (
                <Dialog
                    header='Удаление жанра'
                    headerClassName='p-3 pb-1'
                    contentClassName='p-3 pt-0'
                    visible={isDeleteDialogVisible}
                    onHide={() => {
                        setIsDeleteDialogVisible(false);
                    }}
                >
                    <p>Удалить язык: <strong>{selectedGenre.name}</strong>?</p>

                    <Button
                        label='Удалить'
                        icon='pi pi-trash'
                        iconPos='right'
                        className='w-full'
                        severity='danger'
                        onClick={handleDeleteGenre}
                    />
                </Dialog>
            )}
        </div>
    );
};

export default GenreList;