import {appQueries} from '@app/app-queries';
import {SmallArtistImage} from '@app/web-player/artists/artist-image/small-artist-image';
import {GenreImage} from '@app/web-player/genres/genre-image';
import {BulletSeparatedItems} from '@app/web-player/layout/bullet-separated-items';
import {
  actionButtonClassName,
  MediaPageHeaderLayout,
} from '@app/web-player/layout/media-page-header-layout';
import {PlayerPageSuspense} from '@app/web-player/layout/player-page-suspsense';
import {PlaybackToggleButton} from '@app/web-player/playable-item/playback-toggle-button';
import {queueGroupId} from '@app/web-player/queue-group-id';
import {RadioSeed} from '@app/web-player/radio/radio-recommendations-response';
import {TrackImage} from '@app/web-player/tracks/track-image/track-image';
import {TrackTable} from '@app/web-player/tracks/track-table/track-table';
import {AdHost} from '@common/admin/ads/ad-host';
import {PageMetaTags} from '@common/http/page-meta-tags';
import {useRequiredParams} from '@common/ui/navigation/use-required-params';
import {NotFoundPage} from '@common/ui/not-found-page/not-found-page';
import {useSortableTableData} from '@common/ui/tables/use-sortable-table-data';
import {useSuspenseQuery} from '@tanstack/react-query';
import {FormattedDuration} from '@ui/i18n/formatted-duration';
import {Trans} from '@ui/i18n/trans';
import {MusicNoteIcon} from '@ui/icons/material/MusicNote';
import {IllustratedMessage} from '@ui/images/illustrated-message';
import {ReactNode, useMemo} from 'react';

const validSeeds = ['artist', 'track', 'genre'];

export function Component() {
  const {seedType} = useRequiredParams(['seedType']);

  if (!validSeeds.includes(seedType)) {
    return <NotFoundPage />;
  }

  return (
    <PlayerPageSuspense>
      <RadioPage />
    </PlayerPageSuspense>
  );
}

function RadioPage() {
  const {seedId, seedType} = useRequiredParams(['seedId', 'seedType']);
  const query = useSuspenseQuery(
    appQueries.radio.recommendations(seedType, seedId),
  );
  const {data, onSortChange, sortDescriptor} = useSortableTableData(
    query.data.recommendations,
  );

  const totalDuration = useMemo(() => {
    return data.reduce((total, track) => {
      return total + (track.duration || 0);
    }, 0);
  }, [data]);

  const seed = query.data.seed;
  const queueId = queueGroupId(seed, 'radio');

  if (!data.length) {
    return <NoResultsMessage seedType={seedType} />;
  }

  return (
    <div>
      <PageMetaTags query={query} />
      <AdHost slot="general_top" className="mb-44" />
      <MediaPageHeaderLayout
        image={<Image seed={seed} />}
        title={
          <Trans
            message=":name radio"
            values={{
              name:
                'display_name' in seed && seed.display_name
                  ? seed.display_name
                  : seed.name,
            }}
          />
        }
        subtitle={
          <BulletSeparatedItems className="justify-center text-sm text-muted md:justify-start">
            <RadioType seed={seed} />
            <Trans
              message="[one 1 song|other :count songs]"
              values={{count: data.length}}
            />
            <FormattedDuration ms={totalDuration} verbose />
          </BulletSeparatedItems>
        }
        actionsBar={
          <div className="text-center md:text-start">
            <PlaybackToggleButton
              tracks={data}
              disabled={!data.length}
              buttonType="text"
              queueId={queueId}
              className={actionButtonClassName({isFirst: true})}
            />
          </div>
        }
      />
      <TrackTable
        className="mt-34"
        tracks={data}
        queueGroupId={queueId}
        onSortChange={onSortChange}
        sortDescriptor={sortDescriptor}
      />
      <AdHost slot="general_bottom" className="mt-44" />
    </div>
  );
}

interface SeedImageProps {
  seed: RadioSeed;
}
function Image({seed}: SeedImageProps) {
  switch (seed.model_type) {
    case 'artist':
      return (
        <SmallArtistImage
          artist={seed}
          size="w-240 h-240"
          wrapperClassName="mx-auto"
          className="rounded"
        />
      );
    case 'genre':
      return (
        <GenreImage
          genre={seed}
          size="w-240 h-240"
          className="mx-auto rounded"
        />
      );
    default:
      return (
        <TrackImage
          track={seed}
          size="w-240 h-240"
          className="mx-auto rounded"
        />
      );
  }
}

function RadioType({seed}: SeedImageProps) {
  switch (seed.model_type) {
    case 'artist':
      return <Trans message="Artist radio" />;
    case 'genre':
      return <Trans message="Genre radio" />;
    default:
      return <Trans message="Track radio" />;
  }
}

type NoResultsMessageProps = {
  seedType: string;
};
function NoResultsMessage({seedType}: NoResultsMessageProps) {
  let description: ReactNode = null;
  if (seedType === 'artist') {
    description = <Trans message="Try a different artist" />;
  } else if (seedType === 'genre') {
    description = <Trans message="Try a different genre" />;
  } else {
    description = <Trans message="Try a different track" />;
  }

  return (
    <IllustratedMessage
      image={<MusicNoteIcon size="xl" />}
      imageHeight="h-auto"
      title={<Trans message="No song recommendations found" />}
      description={description}
    />
  );
}
