import {useEffect, useState } from "react";
import { Button } from "primereact/button";
import {
    EpisodeShort,
    CreateNameModel,
    EditNameModel,
    DeleteNameModel,
    CreateDescriptionModel,
    EditDescriptionModel,
    DeleteDescriptionModel,
    CreateMediaInfoModel,
    DeleteMediaInfoModel,
    CreateGenreProportionModel,
    EditGenreProportionModel,
    DeleteGenreProportionModel,
    EditDateModel,
    EditDirectorModel,
    AnimeEpisodeCreateModel,
    AnimeEpisodeType,
    EditStudioModel,
    EditCountryModel,
    MediaInfoType,
    NameItem, NameType,
    // EditStudioModel, EditCountryModel
} from "../../../../api/models/Types.tsx";
import { libraryClient } from "../../../../api/axios.tsx";
import useUser from "../../../../api/hooks/useUser.tsx";
import {QueryClient, useQuery, useQueryClient } from "@tanstack/react-query";
import {
    currentUser as currentUserQueryKey,
    languages as languageQueryKey,
    genres as genresQueryKey
} from "../../../../common/QueryKeys.tsx";
import { useParams } from "react-router-dom";
import AnimeLibraryBreadcrumbsComponent, { ItemAction } from "../../../../components/AnimeLibraryBreadcrumbsComponent.tsx";
import {GetLanguageList} from "../../../../api/LanguageApi.tsx";

import {GetGenreList} from "../../../../api/GenreApi.tsx";
import EpisodeEditShortComponent from "../Episode/EpisodeEditShortComponent.tsx";
import { Dialog } from "primereact/dialog";
import {
    ClearAnimeSeasonPreview,
    CreateAnimeSeasonDescription,
    CreateAnimeSeasonGenre,
    CreateAnimeSeasonName,
    DeleteAnimeSeasonDescription,
    DeleteAnimeSeasonGenre,
    DeleteAnimeSeasonName,
    EditAnimeSeasonDescription,
    EditAnimeSeasonGenre,
    EditAnimeSeasonName,
    GetAnimeSeasonDetail,
    SetAnimeSeasonAnnouncementDate,
    SetAnimeSeasonCountry,
    SetAnimeSeasonDirector,
    SetAnimeSeasonExpectedReleaseDate,
    SetAnimeSeasonPreview,
    SetAnimeSeasonReleaseDate,
    SetAnimeSeasonStudio
} from "../../../../api/AnimeSeasonApi.tsx";
import AnimeItemContentListComponent from "../../../../components/library/AnimeItemContentListComponent.tsx";
import CreateEpisodeComponentShort, {
    AddAnimeEpisodeModel
} from "../../../../components/admin/library/animeItems/CreateEpisodeComponentShort.tsx";
import {AddEpisode} from "../../../../api/AnimeSeasonApi.tsx";
import EditPreviewImageComponent from "../../../../components/library/EditPreviewImageComponent.tsx";
import {getDate} from "../../../../common/Helper.tsx";
import NamesEditComponent from "../../../../components/library/NamesEditComponent.tsx";
import DescriptionsEditComponent from "../../../../components/library/DescriptionsEditComponent.tsx";
import GenresEditComponent from "../../../../components/library/GenresEditComponent.tsx";
import { Card } from "primereact/card";
import DateEditComponent from "../../../../components/admin/library/animeItems/DateEditComponent.tsx";
import { Divider } from "primereact/divider";
import TextEditComponent from "../../../../components/admin/library/animeItems/TextEditComponent.tsx";

const queryKey = 'anime_season';
export default function EpisodeEdit() {
    const client = libraryClient;
    //useAxiosWithAuth(libraryClient);
    const { getUser } = useUser();
    const queryClient = useQueryClient();
    const { data: user } = useQuery({queryKey: [currentUserQueryKey], queryFn: () => getUser(),
        refetchInterval: 30000}, queryClient);

    const { data: languages } = useQuery({queryKey: [languageQueryKey], queryFn: () => GetLanguageList(),
        refetchInterval: 30000}, queryClient);
    const { data: genres } = useQuery({queryKey: [genresQueryKey], queryFn: () => GetGenreList(),
        refetchInterval: 30000}, queryClient);

    const { titleId, id } = useParams();
    
    const { data: animeSeason, isLoading, error } = useQuery({queryKey: [queryKey],
        queryFn: () => GetAnimeSeasonDetail(titleId ?? '', id ?? '', client)}, queryClient);

    const [ isAddEpisodeDialogVisible, setIsAddEpisodeDialogVisible ] = useState<boolean>(false);
    const [dialogEpisodeValue, setDialogEpisodeValue] = useState<AddAnimeEpisodeModel>({
        episodeType: AnimeEpisodeType.Regular,
        releaseDate: null,
        durationTicks: null
    });


    const [ waitingForAction, setWaitingForAction ] = useState<boolean>(false);

    const [ dateDialogOpen, setDateDialogOpen ] = useState<string | null>(null);
    const [ dialogDate, setDialogDate ] = useState<Date | null>(null);

    const [ textDialogOpen, setTextDialogOpen ] = useState<string | null>(null);
    const [ dialogText, setDialogText ] = useState<string | null>(null);

    // const [ isRateEditing, setIsRateEditing ] = useState<bool>(false);
    const [ titleName, setTitleName ] = useState<NameItem | null>(null);
    const [ originalName, setOriginalName ] = useState<NameItem | null>(null);
    

    const [isDialogValueValid, setIsDialogValueValid] = useState<boolean>(false);
    const [isSaving, setIsSaving] = useState<boolean>(false);
    const [savingError, setSavingError] = useState<string | null>(null);

    useEffect(() => {
        if (animeSeason == null) {
            setTitleName(null);
            setOriginalName(null);
        }
        else {
            setTitleName(animeSeason.titleNames.find(q => q.type === NameType.Original) ?? null);
            setOriginalName(animeSeason.commonProperties.names.find(q => q.type === NameType.Original) ?? null);
        }
    }, [animeSeason, user]); //user
    
    if (animeSeason == null){
        return (<>НЕТУТИ НИЧАГО</>);
    }
    
    if (isLoading){
        return (
            <>Загрузка...</>
        );
    }

    return (
        <div className='grid pt-3'>
            <div className='col-12'>
                <AnimeLibraryBreadcrumbsComponent action={ItemAction.update}
                                                  title={{ id: animeSeason.titleId, name: titleName?.value ?? '' }}
                                                  season={{ id: animeSeason.id, name: `Сезон ${animeSeason.number}${originalName?.value != null && originalName.value.length > 0 ? `. ${originalName?.value}` : ''}` }} />
            </div>
            <div className='col'>

                <Card
                    // header={}
                    pt={{
                        // header: () => ({
                        //     className: 'p-2 border-bottom-1 border-200'
                        // }),
                        body: () => ({
                            className: 'p-2 pt-3'
                        }),
                        content: () => ({
                            className: 'grid p-0'
                        })
                    }}
                >
                    <>
                        <div className="col-12 sm:col-6 lg:col-2">
                            {/*{animeSeason.commonProperties.preview?.url && (*/}
                            {/*    <img src={animeSeason.commonProperties.preview.url} className="w-full border-round"*/}
                            {/*         alt={(originalName ? `[${originalName.value}] ` : '') +  'preview'} />*/}
                            {/*)}*/}

                            <EditPreviewImageComponent
                                mediaInfo={animeSeason?.commonProperties.preview}
                                dataLoadingError={null}
                                // inputTypeFilter={InputType.Url}
                                editMediaInfo={(mediaInfo, newUrl, newFile) =>
                                    SetAnimeSeasonPreview({
                                        animeTitleId: animeSeason.titleId,
                                        animeSeasonId: animeSeason.id,
                                        animeEpisodeId: null,
                                        newType: mediaInfo?.type ?? MediaInfoType.Image,
                                        newUrl: newUrl,
                                        newFile: newFile,
                                    } as CreateMediaInfoModel)
                                }
                                deleteMediaInfo={(mediaInfo) =>
                                    ClearAnimeSeasonPreview({
                                        animeTitleId: animeSeason.titleId,
                                        animeSeasonId: animeSeason.id,
                                        animeEpisodeId: null,
                                        objectId: mediaInfo.objectId,
                                    } as DeleteMediaInfoModel)}
                                forceRefresh={() => invalidateItem(queryClient)}
                            />

                            <Card className='mt-4 mb-2 shadow-none'
                                  pt={{
                                      body: () => ({
                                          className: 'p-0'
                                      }),
                                      content: () => ({
                                          className: 'py-0 flex flex-column gap-3'
                                      })
                                  }}
                            >
                                {DateEditComponent('Анонс', 'дату анонса', getDate(animeSeason.commonProperties.announcementDate),
                                    dateDialogOpen === 'announcementDate', (show) => {
                                        setDialogDate(show ? getDate(animeSeason.commonProperties.announcementDate) : null);
                                        setDateDialogOpen(show ? 'announcementDate' : null);
                                    },
                                    dialogDate, (date) => setDialogDate(date),
                                    waitingForAction,
                                    () => {
                                        setWaitingForAction(true);
                                        SetAnimeSeasonAnnouncementDate({
                                            animeTitleId: animeSeason.titleId,
                                            animeSeasonId: animeSeason.id,
                                            animeEpisodeId: null,
                                            value: dialogDate
                                        } as EditDateModel)
                                            .then(() => {
                                                setDateDialogOpen(null);
                                                invalidateItem(queryClient);
                                            })
                                            .finally(() => setWaitingForAction(false));
                                    }
                                )}

                                {DateEditComponent('Ожидаемая дата выхода', 'ожидаемую дату выхода', getDate(animeSeason.commonProperties.expectedReleaseDate),
                                    dateDialogOpen === 'expectedReleaseDate', (show) => {
                                        setDialogDate(show ? getDate(animeSeason.commonProperties.expectedReleaseDate) : null);
                                        setDateDialogOpen(show ? 'expectedReleaseDate' : null);
                                    },
                                    dialogDate, (date) => setDialogDate(date),
                                    waitingForAction,
                                    () => {
                                        if (animeSeason == null) {
                                            return;
                                        }
                                        setWaitingForAction(true);
                                        SetAnimeSeasonExpectedReleaseDate({
                                            animeTitleId: animeSeason.titleId,
                                            animeSeasonId: animeSeason.id,
                                            animeEpisodeId: null,
                                            value: dialogDate
                                        } as EditDateModel)
                                            .then(() => {
                                                setDateDialogOpen(null);
                                                invalidateItem(queryClient);
                                            })
                                            .finally(() => setWaitingForAction(false));
                                    }
                                )}

                                {DateEditComponent('Дата выхода', 'дату выхода', getDate(animeSeason.commonProperties.releaseDate),
                                    dateDialogOpen === 'releaseDate', (show) => {
                                        setDialogDate(show ? getDate(animeSeason.commonProperties.releaseDate) : null);
                                        setDateDialogOpen(show ? 'releaseDate' : null);
                                    },
                                    dialogDate, (date) => setDialogDate(date),
                                    waitingForAction,
                                    () => {
                                        if (animeSeason == null) {
                                            return;
                                        }
                                        setWaitingForAction(true);
                                        SetAnimeSeasonReleaseDate({
                                            animeTitleId: animeSeason.titleId,
                                            animeSeasonId: animeSeason.id,
                                            animeEpisodeId: null,
                                            value: dialogDate
                                        } as EditDateModel)
                                            .then(() => {
                                                setDateDialogOpen(null);
                                                invalidateItem(queryClient);
                                            })
                                            .finally(() => setWaitingForAction(false));
                                    }
                                )}

                                <Divider type="solid" className="my-0" />

                                {TextEditComponent('Режиссёр', 'режиссёра', animeSeason.director,
                                    textDialogOpen === 'director', (show) => {
                                        setDialogText(show ? animeSeason.director : null);
                                        setTextDialogOpen(show ? 'director' : null);
                                    },
                                    dialogText, (text) => setDialogText(text),
                                    waitingForAction,
                                    () => {
                                        if (animeSeason == null) {
                                            return;
                                        }
                                        setWaitingForAction(true);
                                        SetAnimeSeasonDirector({
                                            animeTitleId: animeSeason.titleId,
                                            animeSeasonId: animeSeason.id,
                                            animeEpisodeId: null,
                                            value: dialogText
                                        } as EditDirectorModel)
                                            .then(() => {
                                                setTextDialogOpen(null);
                                                invalidateItem(queryClient);
                                            })
                                            .finally(() => setWaitingForAction(false));
                                    }
                                )}

                                {TextEditComponent('Студия', 'студию', animeSeason.studio,
                                    textDialogOpen === 'studio', (show) => {
                                        setDialogText(show ? animeSeason.studio : null);
                                        setTextDialogOpen(show ? 'studio' : null);
                                    },
                                    dialogText, (text) => setDialogText(text),
                                    waitingForAction,
                                    () => {
                                        if (animeSeason == null) {
                                            return;
                                        }
                                        setWaitingForAction(true);
                                        SetAnimeSeasonStudio({
                                            animeTitleId: animeSeason.titleId,
                                            animeSeasonId: animeSeason.id,
                                            animeEpisodeId: null,
                                            value: dialogText
                                        } as EditStudioModel)
                                            .then(() => {
                                                setTextDialogOpen(null);
                                                invalidateItem(queryClient);
                                            })
                                            .finally(() => setWaitingForAction(false));
                                    }
                                )}

                                {TextEditComponent('Страна', 'страну', animeSeason.country,
                                    textDialogOpen === 'country', (show) => {
                                        setDialogText(show ? animeSeason.country : null);
                                        setTextDialogOpen(show ? 'country' : null);
                                    },
                                    dialogText, (text) => setDialogText(text),
                                    waitingForAction,
                                    () => {
                                        if (animeSeason == null) {
                                            return;
                                        }
                                        setWaitingForAction(true);
                                        SetAnimeSeasonCountry({
                                            animeTitleId: animeSeason.titleId,
                                            animeSeasonId: animeSeason.id,
                                            animeEpisodeId: null,
                                            value: dialogText
                                        } as EditCountryModel)
                                            .then(() => {
                                                setTextDialogOpen(null);
                                                invalidateItem(queryClient);
                                            })
                                            .finally(() => setWaitingForAction(false));
                                    }
                                )}
                            </Card>
                        </div>
                        <div className="col-12 sm:col-6 lg:col-10 flex flex-column gap-2">

                            <NamesEditComponent languages={languages ?? []} names={animeSeason.commonProperties.names}
                                onAdd={(name) => new Promise ((resolve, reject) => {
                                    CreateAnimeSeasonName({
                                        animeTitleId: animeSeason.titleId,
                                        animeSeasonId: animeSeason.id,
                                        animeEpisodeId: null,
                                        languageId:name.language.id,
                                        value: name.value,
                                        type: name.type
                                    } as CreateNameModel)
                                        .then((response) => {
                                            invalidateItem(queryClient);
                                            resolve(response);
                                        })
                                        .catch(e => reject(e));
                                })}
                                onEdit={(name, newValue, newLanguage) => new Promise ((resolve, reject) => {
                                    EditAnimeSeasonName({
                                        animeTitleId: animeSeason.titleId,
                                        animeSeasonId: animeSeason.id,
                                        animeEpisodeId: null,

                                        languageId: name.language.id,
                                        value: name.value,
                                        type: name.type,

                                        newLanguageId: newLanguage?.id,
                                        newValue: newValue,
                                    } as EditNameModel)
                                        .then((response) => {
                                            invalidateItem(queryClient);
                                            resolve(response);
                                        })
                                        .catch(e => reject(e));
                                })}
                                onDelete={(name) => new Promise ((resolve, reject) => {
                                    DeleteAnimeSeasonName({
                                        animeTitleId: animeSeason.titleId,
                                        animeSeasonId: animeSeason.id,
                                        animeEpisodeId: null,

                                        languageId: name.language.id,
                                        value: name.value,
                                        type: name.type,
                                    } as DeleteNameModel)
                                        .then((response) => {
                                            invalidateItem(queryClient);
                                            resolve(response);
                                        })
                                        .catch(e => reject(e));
                                })}
                            />

                            <DescriptionsEditComponent languages={languages ?? []} descriptions={animeSeason.commonProperties.descriptions}
                               onAdd={(description) => new Promise ((resolve, reject) => {
                                   CreateAnimeSeasonDescription({
                                       animeTitleId: animeSeason.titleId,
                                       animeSeasonId: animeSeason.id,
                                       animeEpisodeId: null,
                                       languageId:description.language.id,
                                       value: description.value,
                                       isOriginal: description.isOriginal
                                   } as CreateDescriptionModel)
                                       .then((response) => {
                                           invalidateItem(queryClient);
                                           resolve(response);
                                       })
                                       .catch(e => reject(e));
                               })}
                               onEdit={(description, newValue, newLanguage) => new Promise ((resolve, reject) => {
                                   EditAnimeSeasonDescription({
                                       animeTitleId: animeSeason.titleId,
                                       animeSeasonId: animeSeason.id,
                                       animeEpisodeId: null,

                                       languageId: description.language.id,
                                       value: description.value,
                                       isOriginal: description.isOriginal,

                                       newLanguageId: newLanguage?.id,
                                       newValue: newValue,
                                   } as EditDescriptionModel)
                                       .then((response) => {
                                           invalidateItem(queryClient);
                                           resolve(response);
                                       })
                                       .catch(e => reject(e));
                               })}
                               onDelete={(description) => new Promise ((resolve, reject) => {
                                   DeleteAnimeSeasonDescription({
                                       animeTitleId: animeSeason.titleId,
                                       animeSeasonId: animeSeason.id,
                                       animeEpisodeId: null,

                                       languageId: description.language.id,
                                       value: description.value,
                                       isOriginal: description.isOriginal,
                                   } as DeleteDescriptionModel)
                                       .then((response) => {
                                           invalidateItem(queryClient);
                                           resolve(response);
                                       })
                                       .catch(e => reject(e));
                               })}
                            />


                            <div className='d-flex '>
                                <GenresEditComponent genres={genres ?? []} genreProportions={animeSeason.commonProperties.genres}
                                     onAdd={(genreProportionItem) => new Promise ((resolve, reject) => {
                                         CreateAnimeSeasonGenre({
                                             animeTitleId: animeSeason.titleId,
                                             animeSeasonId: animeSeason.id,
                                             animeEpisodeId: null,
                                             genreId:genreProportionItem.genre.id,
                                             proportion: genreProportionItem.proportion,
                                         } as CreateGenreProportionModel)
                                             .then((response) => {
                                                 invalidateItem(queryClient);
                                                 resolve(response);
                                             })
                                             .catch(e => reject(e));
                                     })}
                                     onEdit={(genreProportionItem, proportionPercentage) => new Promise ((resolve, reject) => {
                                         EditAnimeSeasonGenre({
                                             animeTitleId: animeSeason.titleId,
                                             animeSeasonId: animeSeason.id,
                                             animeEpisodeId: null,
                                             genreId:genreProportionItem.genre.id,
                                             proportion: proportionPercentage
                                         } as EditGenreProportionModel)
                                             .then((response) => {
                                                 invalidateItem(queryClient);
                                                 resolve(response);
                                             })
                                             .catch(e => reject(e));
                                     })}
                                     onDelete={(genreProportionItem) => new Promise ((resolve, reject) => {
                                         DeleteAnimeSeasonGenre({
                                             animeTitleId: animeSeason.titleId,
                                             animeSeasonId: animeSeason.id,
                                             animeEpisodeId: null,
                                             genreId:genreProportionItem.genre.id,
                                             // proportion: genreProportionItem.proportion,
                                         } as DeleteGenreProportionModel)
                                             .then((response) => {
                                                 invalidateItem(queryClient);
                                                 resolve(response);
                                             })
                                             .catch(e => reject(e));
                                     })}
                                />
                            </div>
                        </div>

                        <div className="col-12">
                            <AnimeItemContentListComponent<EpisodeShort>
                                items={animeSeason.episodes}
                                headerTitle='Список эпизодов'
                                onOpenCreateModal={() => setIsAddEpisodeDialogVisible(true)}
                                createPageLinks={[
                                    { label: 'Эпизод', url: `/admin/library/anime/${animeSeason.titleId}/season/${animeSeason.id}/episode` }
                                ]}
                                renderItem={(episode) => (
                                    <EpisodeEditShortComponent
                                        key={episode.id}
                                        titleId={animeSeason.titleId}
                                        seasonId={animeSeason.id}
                                        episodeId={episode.id}
                                        episodeNumber={episode.number ?? 0}
                                        episodeVariant={episode.variant}
                                        previewImage={episode.preview?.url ?? ''}
                                        names={episode.names}
                                        primaryLanguageId={user?.languageId}
                                        announcementDate={episode.announcementDate ?? null}
                                        expectedReleaseDate={episode.expectedReleaseDate ?? null}
                                        releaseDate={episode.releaseDate ?? null}
                                        isCompleted={episode.completed}
                                        duration={episode.durationTicks ?? 0}
                                        userRating={episode.rating}
                                        myRating={episode.myRating}
                                    />
                                )}
                            />
                        </div>

                        <Dialog header='Добавить содержимое'
                                headerClassName='p-3 pt-2 pb-1'
                                contentClassName='p-3 pt-0'
                                style={{ width: '50vw' }}
                                visible={isAddEpisodeDialogVisible} onHide={() => setIsAddEpisodeDialogVisible(false)}>
                            <div className='flex flex-column gap-3 mt-3'>
                                <CreateEpisodeComponentShort value={dialogEpisodeValue}
                                                             onChange={(model, isValid) => {
                                                                 setDialogEpisodeValue(model);
                                                                 setIsDialogValueValid(isValid);
                                                             }} />
                            </div>
                            <Button label='Добавить эпизод' className='w-full mt-4' loading={isSaving}
                                    disabled={!isDialogValueValid}
                                    onClick={() => {
                                        setIsSaving(true);
                                        AddEpisode({
                                            animeTitleId: animeSeason.titleId,
                                            animeSeasonId: animeSeason.id,
                                            type: dialogEpisodeValue.episodeType,
                                            releaseDate: dialogEpisodeValue.releaseDate,
                                            durationTicks: dialogEpisodeValue.durationTicks,
                                        } as AnimeEpisodeCreateModel)
                                            .then(() => {
                                                setSavingError(null);
                                                setIsAddEpisodeDialogVisible(false);
                                                invalidateItem(queryClient);
                                                setDialogEpisodeValue({
                                                    episodeType: AnimeEpisodeType.Regular,
                                                    releaseDate: null,
                                                    durationTicks: null
                                                } as AddAnimeEpisodeModel);
                                            })
                                            .catch((err: Error | null | undefined) => setSavingError(err?.message ?? null))
                                            .finally(() => setIsSaving(false));
                                    }
                                    } />
                        </Dialog>

                    </>
                </Card>
            </div>
        </div>
    );
};

function invalidateItem(queryClient: QueryClient) { queryClient.invalidateQueries({ queryKey: [queryKey] }); }