import { Filter, kinds, nip19 } from 'nostr-tools'
import { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { A11y, Navigation, Pagination, Autoplay } from 'swiper/modules'
import { Swiper, SwiperSlide } from 'swiper/react'
import { BlogCard } from '../components/BlogCard'
import { GameCard } from '../components/GameCard'
import { ModCard } from '../components/ModCard'
import { LANDING_PAGE_DATA } from '../constants'
import { RelayController } from '../controllers'
import { useDidMount } from '../hooks'
import { appRoutes, getModPageRoute } from '../routes'
import { ModDetails } from '../types'
import {
  extractModData,
  fetchMods,
  handleModImageError,
  log,
  LogType
} from '../utils'

import '../styles/cardLists.css'
import '../styles/SimpleSlider.css'
import '../styles/styles.css'

// Import Swiper styles
import 'swiper/css'
import 'swiper/css/navigation'
import 'swiper/css/pagination'

export const HomePage = () => {
  const navigate = useNavigate()
  return (
    <div className='InnerBodyMain'>
      <div className='SliderWrapper'>
        <div className='ContainerMain'>
          <div className='IBMSecMain'>
            <div className='simple-slider IBMSMSlider'>
              <Swiper
                className='swiper-container IBMSMSliderContainer'
                wrapperClass='swiper-wrapper IBMSMSliderContainerWrapper'
                modules={[Navigation, Pagination, A11y, Autoplay]}
                pagination={{ clickable: true, dynamicBullets: true }}
                slidesPerView={1}
                autoplay={{ delay: 5000 }}
                speed={1000}
                navigation
                loop
              >
                {LANDING_PAGE_DATA.featuredSlider.map((naddr) => (
                  <SwiperSlide className='swiper-slide IBMSMSliderContainerWrapperSlider'>
                    <SlideContent naddr={naddr} />
                  </SwiperSlide>
                ))}
              </Swiper>
            </div>
          </div>
        </div>
      </div>
      <div className='ContainerMain'>
        <div className='IBMSecMainGroup IBMSecMainGroupAlt'>
          <div className='IBMSecMain IBMSMListWrapper'>
            <div className='IBMSMTitleMain'>
              <h2 className='IBMSMTitleMainHeading'>Cool Games</h2>
            </div>
            <div className='IBMSMList IBMSMListFeaturedAlt'>
              {LANDING_PAGE_DATA.featuredGames.map((game) => (
                <GameCard title={game.title} imageUrl={game.imageUrl} />
              ))}
            </div>
            <div className='IBMSMAction'>
              <a
                className='btn btnMain IBMSMActionBtn'
                role='button'
                onClick={() => navigate(appRoutes.games)}
              >
                View All
              </a>
            </div>
          </div>
          <div className='IBMSecMain IBMSMListWrapper'>
            <div className='IBMSMTitleMain'>
              <h2 className='IBMSMTitleMainHeading'>Awesome Mods</h2>
            </div>
            <div className='IBMSMList IBMSMListAlt'>
              {LANDING_PAGE_DATA.awesomeMods.map((naddr) => (
                <DisplayMod key={naddr} naddr={naddr} />
              ))}
            </div>
            <div className='IBMSMAction'>
              <a
                className='btn btnMain IBMSMActionBtn'
                role='button'
                onClick={() => navigate(appRoutes.mods)}
              >
                View All
              </a>
            </div>
          </div>
          <DisplayLatestMods />
          <div className='IBMSecMain IBMSMListWrapper'>
            <div className='IBMSMTitleMain'>
              <h2 className='IBMSMTitleMainHeading'>Blog Posts (WIP)</h2>
            </div>
            <div className='IBMSMList'>
              <BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
              <BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
              <BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
              <BlogCard backgroundLink='/assets/img/DEGMods%20Placeholder%20Img.png' />
            </div>

            <div className='IBMSMAction'>
              <a
                className='btn btnMain IBMSMActionBtn'
                role='button'
                href='blog.html'
              >
                View All
              </a>
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}

type SlideContentProps = {
  naddr: string
}

const SlideContent = ({ naddr }: SlideContentProps) => {
  const navigate = useNavigate()
  const [mod, setMod] = useState<ModDetails>()

  useDidMount(() => {
    const decoded = nip19.decode<'naddr'>(naddr as `naddr1${string}`)
    const { identifier, kind, pubkey, relays = [] } = decoded.data

    const filter: Filter = {
      '#a': [identifier],
      authors: [pubkey],
      kinds: [kind]
    }

    RelayController.getInstance()
      .fetchEvent(filter, relays)
      .then((event) => {
        if (event) {
          const extracted = extractModData(event)
          setMod(extracted)
        }
      })
      .catch((err) => {
        log(
          true,
          LogType.Error,
          'An error occurred in fetching mod details from relays',
          err
        )
      })
  })

  if (!mod) return <Spinner />

  return (
    <>
      <div className='IBMSMSCWSPicWrapper'>
        <img
          src={mod.featuredImageUrl}
          onError={handleModImageError}
          className='IBMSMSCWSPic'
        />
      </div>
      <div className='IBMSMSCWSInfo'>
        <h3 className='IBMSMSCWSInfoHeading'>{mod.title}</h3>
        <p className='IBMSMSCWSInfoText'>
          {mod.summary}
          <br />
        </p>
        <div className='IBMSMSliderContainerWrapperSliderAction'>
          <a
            className='btn btnMain IBMSMSliderContainerWrapperSliderActionbtn'
            role='button'
            onClick={() => navigate(getModPageRoute(naddr))}
          >
            Check it out
          </a>
        </div>
      </div>
    </>
  )
}

type DisplayModProps = {
  naddr: string
}

const DisplayMod = ({ naddr }: DisplayModProps) => {
  const navigate = useNavigate()
  const [mod, setMod] = useState<ModDetails>()

  useDidMount(() => {
    const decoded = nip19.decode<'naddr'>(naddr as `naddr1${string}`)
    const { identifier, kind, pubkey, relays = [] } = decoded.data

    const filter: Filter = {
      '#a': [identifier],
      authors: [pubkey],
      kinds: [kind]
    }

    RelayController.getInstance()
      .fetchEvent(filter, relays)
      .then((event) => {
        if (event) {
          const extracted = extractModData(event)
          setMod(extracted)
        }
      })
      .catch((err) => {
        log(
          true,
          LogType.Error,
          'An error occurred in fetching mod details from relays',
          err
        )
      })
  })

  if (!mod) return <Spinner />

  const route = getModPageRoute(naddr)

  return (
    <ModCard
      title={mod.title}
      summary={mod.summary}
      imageUrl={mod.featuredImageUrl}
      link={`#${route}`}
      handleClick={() => navigate(route)}
    />
  )
}

const DisplayLatestMods = () => {
  const navigate = useNavigate()
  const [isFetchingLatestMods, setIsFetchingLatestMods] = useState(true)
  const [latestMods, setLatestMods] = useState<ModDetails[]>([])

  useDidMount(() => {
    fetchMods({ source: window.location.host, limit: 4 })
      .then((res) => {
        res.sort((a, b) => b.published_at - a.published_at)
        setLatestMods(res)
      })
      .finally(() => {
        setIsFetchingLatestMods(false)
      })
  })

  return (
    <div className='IBMSecMain IBMSMListWrapper'>
      <div className='IBMSMTitleMain'>
        <h2 className='IBMSMTitleMainHeading'>Latest Mods</h2>
      </div>
      <div className='IBMSMList'>
        {isFetchingLatestMods ? (
          <Spinner />
        ) : (
          latestMods.map((mod) => {
            const route = getModPageRoute(
              nip19.naddrEncode({
                identifier: mod.aTag,
                pubkey: mod.author,
                kind: kinds.ClassifiedListing
              })
            )

            return (
              <ModCard
                key={mod.id}
                title={mod.title}
                summary={mod.summary}
                imageUrl={mod.featuredImageUrl}
                link={`#${route}`}
                handleClick={() => navigate(route)}
              />
            )
          })
        )}
      </div>

      <div className='IBMSMAction'>
        <a
          className='btn btnMain IBMSMActionBtn'
          role='button'
          onClick={() => navigate(appRoutes.mods)}
        >
          View All
        </a>
      </div>
    </div>
  )
}

const Spinner = () => {
  return (
    <div className='spinner'>
      <div className='spinnerCircle'></div>
    </div>
  )
}
