import { Button, Form } from 'antd'
import { useForm } from 'antd/lib/form/Form'
import Cookies from 'js-cookie'
import { PodcastItem as MusicType } from 'models/talent/talent-profile-module.model'
import * as React from 'react'
import { useCallback, useEffect, useState } from 'react'
import {
  KOMI_SPOTIFY_ACCESS_TOKEN,
  KOMI_SPOTIFY_REFRESH_TOKEN
} from 'services/SpotifyService'
import spotifyUri from 'spotify-uri'
import { defaultPodcastTags } from '../../constants/social'
import {
  SocialProfileLinkItem,
  SocialProfileLinkTypes
} from '../../redux/User/types'
import { spotifyService } from '../../services'
import notification from '../../utils/notification'
import Modal from '../Modal'
import MusicItem from '../MusicItem'
import MusicList from '../MusicList'
import { Paragraph } from '../Typography'
import './AddProfileSmartPodcast.scss'
interface AddProfileSmartPodcastProps {
  visible?: boolean
  isEdit: boolean
  music?: MusicType
  onFinish?: (data: any) => void
  onSetVisible?: (value: boolean) => void
  onConnectSpotify?: (callback: any) => Promise<void>
}

const AddProfileSmartPodcast = ({
  visible,
  onSetVisible,
  onFinish,
  onConnectSpotify,
  isEdit,
  music
}: AddProfileSmartPodcastProps) => {
  const [form] = useForm()
  const [loading, setLoading] = useState(false)
  const [spotify, setSpotify] = useState({
    edit: true,
    value: ''
  })
  const [musics] = useState(defaultPodcastTags)
  const [musicLinks, setMusicLinks] = useState<SocialProfileLinkItem[]>([])

  const handleClose = () => {
    form.resetFields()
    setSpotify({ edit: true, value: '' })
    setMusicLinks([])
    onSetVisible?.(false)
  }
  const handleClickTag = useCallback(
    (id: number) => () => {
      setMusicLinks((values: any[]) => {
        const tag = values.find(item => item.id === id)
        if (tag) {
          form.resetFields([tag.key])
          return [...values].filter(item => item.id !== id)
        }
        const link = musics.find(item => item.id === id)
        return [...values, { ...link, edit: true, value: '' }]
      })
    },
    [form]
  )
  const handleChangeField = useCallback(
    (name: string) => (text: string) => {
      form.setFieldsValue({
        [name]: text
      })
    },
    [form]
  )
  const handleChangeSpotify = useCallback((item: any) => {
    setSpotify(value => ({ ...value, ...item }))
  }, [])
  const handleFinish = useCallback(
    async (uri: any, result: any, values: any) => {
      const { response } = result
      let metadata: any = {}
      switch (uri.type) {
        case 'show':
          metadata = {
            images: response?.images,
            type: response?.type,
            name: response?.name,
            publisher: response?.publisher,
            externalUrls: response?.external_urls,
            previewUrl: response?.episodes?.items?.[0]?.audio_preview_url
          }
          break

        case 'user':
          metadata = {
            name: response?.display_name,
            externalUrls: response?.external_urls,
            images: response?.images,
            type: response?.type
          }
          break
        case 'playlist':
          const track = response?.tracks?.items?.find(
            (el: any) => !!el.track.preview_url
          )
          metadata = {
            name: response?.name,
            externalUrls: response?.external_urls,
            images: response?.images,
            type: response?.type,
            owner: response?.owner,
            previewUrl: track?.preview_url
          }
          break
        case 'artist':
          metadata = {
            name: response?.name,
            externalUrls: response?.external_urls,
            images: response?.images,
            type: response?.type
          }
          break
        case 'album':
          const albumTrack = response?.tracks?.items?.find(
            (el: any) => !!el?.preview_url
          )
          metadata = {
            name: response?.name,
            externalUrls: response?.external_urls,
            images: response?.images,
            type: response?.type,
            artists: response?.artists,
            previewUrl: albumTrack?.preview_url
          }
          break
        case 'track':
          metadata = {
            name: response?.name,
            externalUrls: response?.external_urls,
            images: response?.album?.images,
            type: response?.type,
            artists: response?.artists,
            previewUrl: response?.preview_url
          }
          break
        case 'episode':
          metadata = {
            name: response?.name,
            externalUrls: response?.external_urls,
            images: response?.images,
            type: response?.type,
            publisher: response?.show?.publisher,
            previewUrl: response?.audio_preview_url
          }
          break
        default:
          break
      }
      const links = [
        {
          type: SocialProfileLinkTypes.SPOTIFY,
          url: values[SocialProfileLinkTypes.SPOTIFY]
        },
        ...musicLinks.map(item => ({
          type: item.key,
          url: values[item.key]
        }))
      ]

      const data = {
        id: music?.id,
        order: music?.order,
        metadata,
        links
      }
      onFinish?.(data)
      handleClose()
    },
    [handleClose, onFinish, musicLinks, music]
  )
  const handleSubmit = useCallback(
    async values => {
      try {
        setLoading(true)
        const { SPOTIFY } = values
        const uri: any = spotifyUri.parse(SPOTIFY)
        const result: any = await spotifyService.getSpotifyById(
          `${uri.type}s`,
          uri.id || uri.user
        )
        if (result && 'ok' in result) {
          handleFinish(uri, result, values)
        } else {
          throw result
        }
      } catch (error: any) {
        if (error?.kind && error?.kind === 'unauthorized') {
          Cookies.remove(KOMI_SPOTIFY_ACCESS_TOKEN)
          Cookies.remove(KOMI_SPOTIFY_REFRESH_TOKEN)
          notification.error({
            message:
              'Spotify authentication is expired. We’re refreshing your authentication'
          })
          setTimeout(() => {
            onConnectSpotify?.(() => {
              notification.success({
                message: 'Spotify is authenticated. Please try again!'
              })
            })
          }, 300)
        } else {
          console.error(error)
          notification.error({
            message: 'Please enter the correct Spotify song link'
          })
        }
      } finally {
        setLoading(false)
      }
    },
    [form, handleFinish, onConnectSpotify]
  )
  useEffect(() => {
    if (isEdit && music) {
      setSpotify({
        edit: false,
        value: music.links?.[0].url || ''
      })
      const editLinks = music.links
        .filter(musicLink => musicLink.type !== SocialProfileLinkTypes.SPOTIFY)
        .map(item => {
          const link = musics.find(el => el.key === item.type)
          return { ...link, value: item.url } as SocialProfileLinkItem
        })
      setMusicLinks(editLinks)
      const initValues = music.links.reduce((values, item) => {
        return { ...values, [item.type as string]: item.url }
      }, {})
      form.setFieldsValue(initValues)
    }
  }, [isEdit, music, form])

  return (
    <Modal
      width={664}
      title={isEdit ? 'Edit a podcast smart link' : 'Add a podcast smart link'}
      className="profile-smart-podcast"
      visible={visible}
      zIndex={100}
      onCancel={handleClose}
      maskClosable={false}
    >
      <div>
        <Form
          labelCol={{
            span: 24
          }}
          wrapperCol={{
            span: 24
          }}
          form={form}
          hideRequiredMark
          onFinish={handleSubmit}
        >
          <Paragraph className="m__b--5" preset="semibold18">
            Add Spotify podcast link
          </Paragraph>
          <Paragraph className="opacity--80 m__b--16" preset="regular16">
            We use the Spotify API to enable fans to play a snippet of your
            podcast
          </Paragraph>
          <MusicItem
            onChangeText={handleChangeField('SPOTIFY')}
            name={'SPOTIFY'}
            title="Spotify"
            icon="spotify"
            value={form.getFieldValue('SPOTIFY')}
            edit={spotify.edit}
            onSetItem={handleChangeSpotify}
            defaultValue={spotify.value}
          />
          <Paragraph className="m__t--16 m__b--5" preset="semibold18">
            Add other streaming links
          </Paragraph>
          <Paragraph className="opacity--80 m__b--16" preset="regular16">
            Give fans additional ways to access your podcast
          </Paragraph>

          <MusicList
            className="module-music"
            links={musicLinks}
            onSetLinks={setMusicLinks}
            tags={musics}
            onChangeField={handleChangeField}
            onClickTag={handleClickTag}
          />
          <div className="profile-smart-podcast__actions m__t--24">
            <Button
              className="ant-btn-xl ant-btn-uppercase"
              onClick={handleClose}
            >
              Cancel
            </Button>
            <Button
              className="ant-btn-xl ant-btn-uppercase"
              htmlType="submit"
              size="large"
              type="primary"
              loading={loading}
            >
              {isEdit ? 'Save' : 'Done'}
            </Button>
          </div>
        </Form>
      </div>
    </Modal>
  )
}

export default AddProfileSmartPodcast
