import React, { Dispatch, SetStateAction, useEffect, useState } from 'react'

import { MultistageModalForm } from 'components/MultistageForm'
import { SmartLinkSearch } from './SmartLinkSearch/SmartLinkSearch'
import { SmartLinkSelection } from './SmartLinkSelection/SmartLinkSelection'
import { SmartLinkCustomization } from './SmartLinkCustomization/SmartLinkCustomization'

import { MusicItem } from 'models/talent/talent-profile-module.model'

import { noop } from 'utils/noop'
import { DspLink, DspResource, DspResourceType } from 'types/dsp'
import { MusicReleaseType } from '@komi-app/shared-types'

export enum SmartLinkResourceType {
  TRACK = 'track',
  ALBUM = 'album',
  //supporting legacy types
  SHOW = 'show',
  USER = 'user',
  PLAYLIST = 'playlist',
  ARTIST = 'artist',
  EPISODE = 'episode'
}

export interface SmartLinkSearchResult {
  artistNames: string[]
  externalIds: Record<string, string>
  resourceIds: Record<string, string>
  imageUrl: string
  length?: number
  name: string
  releaseYear?: number
  type?: DspResourceType
}

interface SmartLinkFormPayload {
  artists: []
  imageUrl: string
  links: DspLink[]
  name: string
  searchResult?: SmartLinkSearchResult
  selectedResource?: DspResource
  type: DspResourceType
  urlSlug: string
}

interface SmartLinkArtwork {
  height: number
  url: string
  width: number
}

interface SmartLinkArtist {
  name: string
}

interface SmartLinkMetadata {
  albumName: string
  artists: SmartLinkArtist[]
  type?: DspResourceType
  length?: number
  name: string
  previewUrl?: string
  externalUrls: Record<string, string>
  externalIds: Record<string, string>
  releaseYear?: number
  resourceIds: Record<string, string>
  images: SmartLinkArtwork[]
}

interface SmartLinkData {
  links: DspLink[]
  metadata: SmartLinkMetadata
  order?: number
  type: MusicReleaseType.NORMAL
  urlSlug: string
}

interface SmartLinkModalProps {
  isEdit: boolean
  music?: MusicItem
  onFinish?: (data: any) => void
  onCancel: () => void
}

export const SmartLinkModal: React.FC<SmartLinkModalProps> = ({
  isEdit,
  music,
  onFinish = noop,
  onCancel
}) => {
  const [setStage, setStageSetter] =
    useState<Dispatch<SetStateAction<number>>>(noop)
  const [isCustomLink, setIsCustomLink] = useState(false)

  const initialValues = React.useMemo(() => {
    if (!isEdit || !music) {
      return
    }

    const { metadata } = music
    const {
      albumName,
      artists,
      externalIds,
      images,
      length,
      name,
      releaseYear,
      resourceIds,
      type
    } = metadata as SmartLinkMetadata
    const [firstImage] = images

    const imageUrl = firstImage.url
    let artistNames = ['']

    //legacy smart link support, check for old types and conform them to existing flow
    switch (type) {
      case 'show' || 'episode':
        artistNames = [metadata.publisher]
        break

      case 'playlist':
        artistNames = [metadata.owner.display_name]
        break

      case 'user' || 'artist':
        break

      default:
        artistNames = artists.map(artist => artist.name)
        break
    }

    const searchResult: SmartLinkSearchResult = {
      artistNames,
      externalIds,
      imageUrl,
      length,
      name,
      releaseYear,
      type,
      resourceIds
    }

    const selectedResource: DspResource = {
      name,
      albumName,
      type: type || DspResourceType.TRACK,
      upc: externalIds?.upc,
      isrc: externalIds?.isrc
    }

    return {
      ...music,
      searchResult,
      selectedResource
    }
  }, [])

  useEffect(() => {
    if (isEdit && setStage) {
      setStage(2)
    }
  }, [setStage])

  const handleFinish = (values: SmartLinkFormPayload) => {
    const firstLinkWithPreview = values.links.find(link => link.previewUrl)
    const firstPreviewUrl = firstLinkWithPreview?.previewUrl

    const { artists, name, searchResult, selectedResource } = values

    const resolvedSelectedResource =
      selectedResource || ({} as Partial<DspResource>)
    const { albumName = '', isrc = '', upc = '' } = resolvedSelectedResource

    const resolvedSearchResult =
      searchResult || ({} as Partial<SmartLinkSearchResult>)
    const { length, releaseYear, resourceIds = {}, type } = resolvedSearchResult

    const metadata: SmartLinkMetadata = {
      albumName,
      artists,
      externalIds: { isrc, upc },
      externalUrls: {}, // TODO: does `komi-client` need this information? If so, add
      images: [
        {
          // TODO: Get this information from the form.
          // For now use the standard Spotify image size
          height: 640,
          url: values.imageUrl,
          width: 640
        }
      ],
      length,
      name,
      previewUrl: firstPreviewUrl,
      releaseYear,
      resourceIds,
      type
    }

    const smartLinkData: SmartLinkData = {
      links: values.links,
      order: music?.order,
      metadata,
      type: MusicReleaseType.NORMAL,
      urlSlug: values.urlSlug
    }

    onFinish(smartLinkData)
    onCancel()
  }

  return (
    <MultistageModalForm
      initialValues={initialValues}
      title="Setup Smart Link"
      onCancel={onCancel}
      onFinish={handleFinish}
      setStageSetter={setStageSetter}
    >
      <SmartLinkSearch setStage={setStage} setIsCustomLink={setIsCustomLink} />
      <SmartLinkSelection isCustomLink={isCustomLink} />
      <SmartLinkCustomization />
    </MultistageModalForm>
  )
}
