import { defineComponent, ref, computed, toRefs, PropType } from 'vue'
import { useRouter } from '@/hooks/index'
import { SearchSuggest, HeaderActions, Songs } from '@/interface'
import { useHeaderModule } from '@/modules/index'
import { playMusic } from '@/shared/music-shared'
import { Jump } from '@/shared/jump-shared'
import Keyword from '@/components/keyword/keyword'
import { debounce } from 'lodash-es'
import './search.less'

const enum SearchType {
  SONGS = 'SONGS',
  ARTISTS = 'ARTISTS',
  ALBUMS = 'ALBUMS',
  PLAYLISTS = 'PLAYLISTS'
}

const Option = defineComponent({
  name: 'Option',
  props: {
    value: {
      type: [Number, String] as PropType<number | string>,
      required: true
    },
    detail: {
      type: String as PropType<string>,
      required: true
    },
    keyword: {
      type: String as PropType<string>,
      required: true
    },
    onSelect: {
      type: Function,
      required: true
    },
    className: {
      type: String as PropType<string>,
      default: ''
    }
  },
  setup(props) {
    const { value, onSelect, detail, keyword, className } = toRefs(props)
    const handleSelect = () => {
      onSelect?.value(value?.value)
    }
    return () => (
      <li class={className.value} onClick={handleSelect}>
        <Keyword keyword={keyword.value} text={detail?.value} />
      </li>
    )
  }
})

const Group = defineComponent({
  name: 'Group',
  props: {
    words: {
      type: String as PropType<string>,
      required: true
    },
    item: {
      type: Array as PropType<Required<SearchSuggest>['songs']>,
      required: true
    },
    onSelect: {
      type: Function as PropType<() => void>,
      required: true
    }
  },
  emits: ['select'],
  setup(props, { emit }) {
    const { words, item } = toRefs(props)
    const handleSelect = () => {
      emit('select')
    }
    return () => (
      <>
        <div class="search-popper-title" v-show={item.value}>
          <icon icon="facebook" color="#333" size={14}></icon>单曲
        </div>
        <ul class="search-popper-group">
          {item.value.map(song => {
            return (
              <Option
                value={song.id}
                onSelect={handleSelect}
                keyword={words.value}
                detail={`${song.name} - ${song.artists
                  .map(artist => artist.name)
                  .join(' ')}`}
              ></Option>
            )
          })}
        </ul>
      </>
    )
  }
})

export const Search = defineComponent({
  name: 'SearchInput',
  components: {
    Option,
    Group
  },
  setup() {
    const router = useRouter()
    const { useActions, useState } = useHeaderModule()

    const state = useState()
    const words = ref('')
    const loading = ref(false)
    const zh = ref(false)

    const source = computed(() => {
      return state.searchSuggest.order || []
    })

    const handleSearch = debounce(async () => {
      if (words.value && !zh.value) {
        loading.value = true
        await useActions(HeaderActions.GET_SEARCH_SUGGEST, words.value)
        loading.value = false
      }
    }, 200)

    const jump = new Jump()
    const handleSelect = async (type: SearchType, id: unknown) => {
      switch (type) {
        case SearchType.SONGS:
          playMusic((id as Songs).id)
          break
        case SearchType.PLAYLISTS:
          jump.songList(id as number)
          break
        case SearchType.ARTISTS:
          jump.artist(id as number)
          break
        case SearchType.ALBUMS:
          jump.albumList(id as number)
      }
    }

    const handleSearchMore = () => {
      router.push({
        path: '/search/song',
        query: {
          words: words.value
        }
      })
    }

    const Slot = {
      prefix: () => <icon icon="search" color="#ffffff61" size={18}></icon>,
      popper: () => (
        <div class="search-popper">
          <div class="search-popper-more" onClick={handleSearchMore}>
            搜"<strong class="keyword">{words.value}</strong>"相关的结果
          </div>
          <div class="search-popper-title" v-show={state.searchSuggest.songs}>
            <icon icon="facebook" color="#333" size={14}></icon>单曲
          </div>
          <ul class="search-popper-group">
            {state.searchSuggest.songs?.map(song => {
              return (
                <Option
                  value={song.id}
                  onSelect={() => handleSelect(SearchType.SONGS, song)}
                  keyword={words.value}
                  detail={`${song.name} - ${song.artists
                    .map(artist => artist.name)
                    .join(' ')}`}
                ></Option>
              )
            })}
          </ul>
          <div class="search-popper-title" v-show={state.searchSuggest.artists}>
            <icon icon="facebook" color="#333" size={14}></icon>歌手
          </div>
          <ul class="search-popper-group">
            {state.searchSuggest.artists?.map(artist => {
              return (
                <Option
                  value={artist.id}
                  onSelect={() => handleSelect(SearchType.ARTISTS, artist.id)}
                  keyword={words.value}
                  detail={artist.name}
                ></Option>
              )
            })}
          </ul>
          <div class="search-popper-title" v-show={state.searchSuggest.albums}>
            <icon icon="facebook" color="#333" size={14}></icon>专辑
          </div>
          <ul class="search-popper-group search-popper-last">
            {state.searchSuggest.albums?.map(album => {
              return (
                <Option
                  value={album.id}
                  onSelect={() => handleSelect(SearchType.ALBUMS, album.id)}
                  keyword={words.value}
                  detail={`${album.name} - ${album.artist.name}`}
                ></Option>
              )
            })}
          </ul>
          <div
            class="search-popper-title"
            v-show={state.searchSuggest.playlists}
          >
            <icon icon="facebook" color="#333" size={14}></icon>歌单
          </div>
          <ul class="search-popper-group search-popper-last">
            {state.searchSuggest.playlists?.map(list => {
              return (
                <Option
                  value={list.id}
                  onSelect={() => handleSelect(SearchType.PLAYLISTS, list.id)}
                  keyword={words.value}
                  detail={list.name}
                ></Option>
              )
            })}
          </ul>
        </div>
      )
    }
    return () => (
      <div class="search">
        <ve-auto-complete
          class="search-input"
          type="search"
          size="small"
          v-model={[words.value, 'value']}
          data-source={source.value}
          onSearch={handleSearch}
          onCompositionstart={() => (zh.value = true)}
          onCompositionend={() => (zh.value = false)}
          loading={loading.value}
          v-slots={Slot}
        ></ve-auto-complete>
      </div>
    )
  }
})