import {ALBUM_MODEL, PartialAlbum} from '@app/web-player/albums/album';
import {ARTIST_MODEL, PartialArtist} from '@app/web-player/artists/artist';
import {Genre, GENRE_MODEL} from '@app/web-player/genres/genre';
import {
  PartialPlaylist,
  PLAYLIST_MODEL,
} from '@app/web-player/playlists/playlist';
import {Track, TRACK_MODEL} from '@app/web-player/tracks/track';
import {PartialUserProfile} from '@app/web-player/users/user-profile';
import {ChannelContentConfig} from '@common/admin/channels/channel-editor/channel-content-config';
import {Channel, CHANNEL_MODEL} from '@common/channels/channel';
import {message} from '@ui/i18n/message';
import {GridViewIcon} from '@ui/icons/material/GridView';
import {ViewHeadlineIcon} from '@ui/icons/material/ViewHeadline';
import {ViewListIcon} from '@ui/icons/material/ViewList';
import {ViewWeekIcon} from '@ui/icons/material/ViewWeek';
import {USER_MODEL} from '@ui/types/user';

export enum Sort {
  popular = 'popularity:desc',
  recent = 'created_at:desc',
  oldest = 'id:asc',
  releaseDate = 'release_date:desc',
  curated = 'channelables.order:asc',
  attachDate = 'channelables.created_at:desc',
}
export enum Layout {
  grid = 'grid',
  table = 'trackTable',
  list = 'list',
  carousel = 'carousel',
  compactGrid = 'compactGrid',
}

enum Auto {
  topTracks = 'topTracks',
  newAlbums = 'newAlbums',
  topAlbums = 'topAlbums',
  topArtists = 'topArtists',
  playlistTracks = 'playlistTracks',
  topGenres = 'topGenres',
  nonEmptyGenres = 'nonEmptyGenres',
}

enum Restrictions {
  genre = 'genre',
}

const contentModels: ChannelContentConfig['models'] = {
  [ARTIST_MODEL]: {
    label: message('Artists'),
    sortMethods: [Sort.popular, Sort.recent, Sort.oldest],
    layoutMethods: [Layout.grid, Layout.compactGrid, Layout.carousel],
    autoUpdateMethods: [Auto.topArtists],
    restrictions: [Restrictions.genre],
  },
  [ALBUM_MODEL]: {
    label: message('Albums'),
    sortMethods: [Sort.popular, Sort.recent, Sort.releaseDate, Sort.oldest],
    layoutMethods: [
      Layout.grid,
      Layout.compactGrid,
      Layout.list,
      Layout.carousel,
    ],
    autoUpdateMethods: [Auto.newAlbums, Auto.topAlbums],
    restrictions: [Restrictions.genre],
  },
  [TRACK_MODEL]: {
    label: message('Tracks'),
    sortMethods: [Sort.popular, Sort.recent, Sort.oldest],
    layoutMethods: [
      Layout.grid,
      Layout.compactGrid,
      Layout.table,
      Layout.list,
      Layout.carousel,
    ],
    autoUpdateMethods: [Auto.topTracks, Auto.playlistTracks],
    restrictions: [Restrictions.genre],
  },
  [PLAYLIST_MODEL]: {
    label: message('Playlists'),
    sortMethods: [Sort.popular, Sort.recent, Sort.oldest],
    layoutMethods: [Layout.grid, Layout.compactGrid, Layout.carousel],
  },
  [USER_MODEL]: {
    label: message('Users'),
    sortMethods: [Sort.recent, Sort.oldest],
    layoutMethods: [Layout.grid, Layout.carousel],
    autoUpdateMethods: [],
  },
  [GENRE_MODEL]: {
    label: message('Genres'),
    sortMethods: [Sort.popular, Sort.recent, Sort.oldest],
    layoutMethods: [Layout.grid, Layout.carousel, Layout.compactGrid],
    autoUpdateMethods: [Auto.topGenres, Auto.nonEmptyGenres],
  },
  [CHANNEL_MODEL]: {
    label: message('Channels'),
    sortMethods: [],
    layoutMethods: [Layout.list],
  },
};

const contentSortingMethods: Record<
  Sort,
  ChannelContentConfig['sortingMethods']['any']
> = {
  [Sort.popular]: {
    label: message('Most popular first'),
  },
  [Sort.recent]: {
    label: message('Recently added first'),
  },
  [Sort.oldest]: {
    label: message('Oldest first'),
  },
  [Sort.curated]: {
    label: message('Curated (reorder below)'),
    contentTypes: ['manual'],
  },
  [Sort.attachDate]: {
    label: message('Recently attached first'),
  },
  [Sort.releaseDate]: {
    label: message('Most recent first (by release date)'),
  },
};

const contentLayoutMethods: Record<
  Layout,
  ChannelContentConfig['layoutMethods']['any']
> = {
  [Layout.grid]: {
    label: message('Grid'),
    icon: <GridViewIcon />,
  },
  [Layout.table]: {
    label: message('Table'),
    icon: <ViewWeekIcon />,
  },
  [Layout.list]: {
    label: message('List'),
    icon: <ViewListIcon />,
  },
  [Layout.carousel]: {
    label: message('Carousel'),
  },
  [Layout.compactGrid]: {
    label: message('Compact grid'),
    icon: <ViewHeadlineIcon />,
  },
};

const contentAutoUpdateMethods: Record<
  Auto,
  ChannelContentConfig['autoUpdateMethods']['any']
> = {
  [Auto.topTracks]: {
    label: message('Top tracks'),
    providers: ['spotify', 'deezer', 'local'],
  },
  [Auto.newAlbums]: {
    label: message('New releases'),
    providers: ['spotify', 'deezer', 'local'],
  },
  [Auto.topAlbums]: {
    label: message('Popular albums'),
    providers: ['spotify', 'deezer', 'local'],
  },
  [Auto.topArtists]: {
    label: message('Popular artists'),
    providers: ['spotify', 'deezer', 'local'],
  },
  [Auto.playlistTracks]: {
    label: message('Playlist tracks'),
    providers: ['spotify', 'deezer', 'local'],
    value: {
      label: message('Playlist ID'),
      inputType: 'text',
    },
  },
  [Auto.topGenres]: {
    label: message('Popular genres'),
    providers: ['lastfm', 'local'],
  },
  [Auto.nonEmptyGenres]: {
    label: message('Genres that have content'),
    providers: ['local'],
  },
};

const contentRestrictions: Record<
  Restrictions,
  ChannelContentConfig['restrictions']['any']
> = {
  [Restrictions.genre]: {
    label: message('Genre'),
    value: Restrictions.genre,
  },
};

export const channelContentConfig: ChannelContentConfig = {
  models: contentModels,
  sortingMethods: contentSortingMethods,
  layoutMethods: contentLayoutMethods,
  autoUpdateMethods: contentAutoUpdateMethods,
  userSelectableLayouts: [Layout.grid, Layout.table, Layout.list],
  restrictions: contentRestrictions,
};

export type ChannelContentModel =
  | PartialArtist
  | PartialAlbum
  | Track
  | PartialPlaylist
  | PartialUserProfile
  | Genre
  | Channel;
