import { useSuspenseQuery } from '@tanstack/react-query';
import { Fragment } from 'react';
import { useTranslation } from 'react-i18next';
import { generatePath, Link, useParams } from 'react-router';

import styles from './dummy-album-detail-route.module.css';

import { api } from '/@/renderer/api';
import { queryKeys } from '/@/renderer/api/query-keys';
import { useItemImageUrl } from '/@/renderer/components/item-image/item-image';
import { usePlayer } from '/@/renderer/features/player/context/player-context';
import { AnimatedPage } from '/@/renderer/features/shared/components/animated-page';
import { LibraryContainer } from '/@/renderer/features/shared/components/library-container';
import { LibraryHeader } from '/@/renderer/features/shared/components/library-header';
import { PageErrorBoundary } from '/@/renderer/features/shared/components/page-error-boundary';
import { DefaultPlayButton } from '/@/renderer/features/shared/components/play-button';
import { useCreateFavorite } from '/@/renderer/features/shared/mutations/create-favorite-mutation';
import { useDeleteFavorite } from '/@/renderer/features/shared/mutations/delete-favorite-mutation';
import { useFastAverageColor } from '/@/renderer/hooks';
import { queryClient } from '/@/renderer/lib/react-query';
import { AppRoute } from '/@/renderer/router/routes';
import { useCurrentServer, useShowFavorites } from '/@/renderer/store';
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
import { formatDurationString } from '/@/renderer/utils';
import { replaceURLWithHTMLLinks } from '/@/renderer/utils/linkify';
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
import { Button } from '/@/shared/components/button/button';
import { Center } from '/@/shared/components/center/center';
import { Group } from '/@/shared/components/group/group';
import { Icon } from '/@/shared/components/icon/icon';
import { Spoiler } from '/@/shared/components/spoiler/spoiler';
import { Stack } from '/@/shared/components/stack/stack';
import { Text } from '/@/shared/components/text/text';
import { LibraryItem, SongDetailResponse } from '/@/shared/types/domain-types';

const DummyAlbumDetailRoute = () => {
    const { t } = useTranslation();

    const { albumId } = useParams() as { albumId: string };
    const server = useCurrentServer();
    const showFavorites = useShowFavorites();
    const queryKey = queryKeys.songs.detail(server?.id || '', albumId);
    const detailQuery = useSuspenseQuery({
        queryFn: ({ signal }) => {
            return api.controller.getSongDetail({
                apiClientProps: { serverId: server?.id || '', signal },
                query: { id: albumId },
            });
        },
        queryKey,
    });

    const { background, colorId } = useFastAverageColor({
        id: albumId,
        src: detailQuery.data?.imageUrl,
        srcLoaded: Boolean(detailQuery.data?.imageUrl),
    });
    const { addToQueueByFetch } = usePlayer();
    const playButtonBehavior = usePlayButtonBehavior();

    const createFavoriteMutation = useCreateFavorite({});
    const deleteFavoriteMutation = useDeleteFavorite({});

    const handleFavorite = async () => {
        if (!detailQuery?.data) return;

        const wasFavorite = detailQuery.data.userFavorite;

        try {
            if (wasFavorite) {
                await deleteFavoriteMutation.mutateAsync({
                    apiClientProps: { serverId: detailQuery.data._serverId },
                    query: {
                        id: [detailQuery.data.id],
                        type: LibraryItem.SONG,
                    },
                });
            } else {
                await createFavoriteMutation.mutateAsync({
                    apiClientProps: { serverId: detailQuery.data._serverId },
                    query: {
                        id: [detailQuery.data.id],
                        type: LibraryItem.SONG,
                    },
                });
            }

            queryClient.setQueryData<SongDetailResponse>(queryKey, {
                ...detailQuery.data,
                userFavorite: !wasFavorite,
            });
        } catch (error) {
            console.error(error);
        }
    };

    const showGenres = detailQuery?.data?.genres ? detailQuery?.data?.genres.length !== 0 : false;
    const comment = detailQuery?.data?.comment;

    const handlePlay = () => {
        if (!server?.id) return;
        addToQueueByFetch(server.id, [albumId], LibraryItem.SONG, playButtonBehavior);
    };

    const metadataItems = [
        {
            id: 'releaseYear',
            secondary: false,
            value: detailQuery?.data?.releaseYear,
        },
        {
            id: 'duration',
            secondary: false,
            value: detailQuery?.data?.duration && formatDurationString(detailQuery.data.duration),
        },
    ];

    const imageUrl = useItemImageUrl({
        id: detailQuery?.data?.imageId || undefined,
        itemType: LibraryItem.ALBUM,
        type: 'header',
    });

    return (
        <AnimatedPage key={`dummy-album-detail-${albumId}`}>
            <LibraryContainer>
                <Stack>
                    <LibraryHeader
                        imageUrl={imageUrl}
                        item={{
                            explicitStatus: detailQuery?.data?.explicitStatus ?? null,
                            imageId: detailQuery?.data?.imageId,
                            imageUrl: detailQuery?.data?.imageUrl,
                            route: AppRoute.LIBRARY_SONGS,
                            type: LibraryItem.SONG,
                        }}
                        loading={!background || colorId !== albumId}
                        title={detailQuery?.data?.name || ''}
                    >
                        <Stack gap="sm">
                            <Group gap="sm">
                                {metadataItems.map((item, index) => (
                                    <Fragment key={`item-${item.id}-${index}`}>
                                        {index > 0 && <Text isNoSelect>•</Text>}
                                        <Text isMuted={item.secondary}>{item.value}</Text>
                                    </Fragment>
                                ))}
                            </Group>
                            <Group
                                gap="md"
                                mah="4rem"
                                style={{
                                    overflow: 'hidden',
                                    WebkitBoxOrient: 'vertical',
                                    WebkitLineClamp: 2,
                                }}
                            >
                                {detailQuery?.data?.albumArtists.map((artist) => (
                                    <Text
                                        component={Link}
                                        fw={600}
                                        isLink
                                        key={`artist-${artist.id}`}
                                        size="md"
                                        to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, {
                                            albumArtistId: artist.id,
                                        })}
                                        variant="subtle"
                                    >
                                        {artist.name}
                                    </Text>
                                ))}
                            </Group>
                        </Stack>
                    </LibraryHeader>
                </Stack>
                <div className={styles.detailContainer}>
                    <section>
                        <Group gap="sm" justify="space-between">
                            <Group>
                                <DefaultPlayButton onClick={() => handlePlay()} />
                                {showFavorites && (
                                    <ActionIcon
                                        icon="favorite"
                                        iconProps={{
                                            fill: detailQuery?.data?.userFavorite
                                                ? 'primary'
                                                : undefined,
                                        }}
                                        loading={
                                            createFavoriteMutation.isPending ||
                                            deleteFavoriteMutation.isPending
                                        }
                                        onClick={handleFavorite}
                                        variant="subtle"
                                    />
                                )}
                                <ActionIcon
                                    icon="ellipsisHorizontal"
                                    onClick={() => {
                                        if (!detailQuery?.data) return;
                                    }}
                                    variant="subtle"
                                />
                            </Group>
                        </Group>
                    </section>
                    {showGenres && (
                        <section>
                            <Group gap="sm">
                                {detailQuery?.data?.genres?.map((genre) => (
                                    <Button
                                        component={Link}
                                        key={`genre-${genre.id}`}
                                        radius={0}
                                        size="compact-md"
                                        to={generatePath(AppRoute.LIBRARY_GENRES_DETAIL, {
                                            genreId: genre.id,
                                        })}
                                        variant="outline"
                                    >
                                        {genre.name}
                                    </Button>
                                ))}
                            </Group>
                        </section>
                    )}
                    {comment && (
                        <section>
                            <Spoiler maxHeight={75}>
                                <Text pb="md">{replaceURLWithHTMLLinks(comment)}</Text>
                            </Spoiler>
                        </section>
                    )}
                    <section>
                        <Center>
                            <Group mr={5}>
                                <Icon fill="error" icon="error" size={30} />
                            </Group>
                            <h2>{t('error.badAlbum')}</h2>
                        </Center>
                    </section>
                </div>
            </LibraryContainer>
        </AnimatedPage>
    );
};

const DummyAlbumDetailRouteWithBoundary = () => {
    return (
        <PageErrorBoundary>
            <DummyAlbumDetailRoute />
        </PageErrorBoundary>
    );
};

export default DummyAlbumDetailRouteWithBoundary;
