import { useEffect, useState } from 'react'
import { useRouter } from 'next/router'
import { AnimatePresence, m } from 'framer-motion'
import cx from 'classnames'

import { getFirstTerm } from '@/lib/utilities'
import { CASE_STUDIES_PER_PAGE, PROJECTS_PER_PAGE } from '@/lib/constants'
import { OrbProvider, useOrb } from '@/lib/OrbContext'

import Container from '@/components/shared/Container'
import { CustomSelectFilter } from '@/components/shared/Filter'
import Icon from '@/components/shared/Icon'
import Hero from '@/components/sections/Hero'
import ListingCard from '@/components/blocks/ListingCard'

type Item = {
  slug: string
  title: string
  featuredImage?: any
  caseStudyProjectContent: {
    heroSection: {
      customerName: string
    }
  }
  terms: {
    edges: {
      node: {
        name: string
        slug: string
        taxonomyName: string
      }
    }[]
  }
}
type Props = {
  postType: 'case_study' | 'project'
  featuredItem?: any
  items: Item[]
  filters?: {
    key: string
    label: string
    options: {
      label: string
      value: string
    }[]
  }[]
}

export default function Listing({ postType, featuredItem, items, filters }: Props) {
  const router = useRouter()
  const ITEMS_PER_PAGE = postType === 'case_study' ? CASE_STUDIES_PER_PAGE : PROJECTS_PER_PAGE
  const [itemsToShow, setItemsToShow] = useState(ITEMS_PER_PAGE)
  const { Orb, orbPointerEvents } = useOrb()
  const [filteredItems, setFilteredItems] = useState<Item[]>([])
  const [currentFilters, setCurrentFilters] = useState<Record<string, string>>({})
  const currentItems = filteredItems.slice(0, itemsToShow)

  const label = (() => {
    switch (postType) {
      case 'case_study':
        return 'Case Studies'
      case 'project':
        return 'Projects'
    }
  })()

  useEffect(() => {
    setCurrentFilters(router.query as Record<string, string>)
  }, [router.query])

  useEffect(() => {
    const newItems = items
      .filter(item => {
        return currentFilters?.product_type
          ? item.terms.edges.some(
              ({ node: { taxonomyName, slug } }) =>
                taxonomyName === 'product_type' && slug === currentFilters.product_type
            )
          : true
      })
      .filter(item => {
        return currentFilters?.product_industry
          ? item.terms.edges.some(
              ({ node: { taxonomyName, slug } }) =>
                taxonomyName === 'product_industry' && slug === currentFilters.product_industry
            )
          : true
      })

    setFilteredItems(newItems)
    setItemsToShow(ITEMS_PER_PAGE)
    orbPointerEvents.onPointerOut?.()
  }, [ITEMS_PER_PAGE, currentFilters, items])

  return (
    <>
      <Hero variant={postType} featuredItem={featuredItem} />

      <div className="bg-white">
        <Container className="py-12 md:py-24">
          {/* Filters */}
          {filters && (
            <div className="flex flex-wrap flex-col sm:flex-row gap-x-12 gap-y-6 pb-8">
              {filters.map(filter => (
                <CustomSelectFilter
                  key={filter.key}
                  label={filter.label}
                  options={filter.options}
                  selectedOption={currentFilters?.[filter.key]}
                  onChange={newFilter => {
                    setCurrentFilters(prev => ({ ...prev, [filter.key]: newFilter }))
                  }}
                />
              ))}
              {Object.keys(currentFilters).length > 0 && (
                <div className="w-full md:w-auto md:ml-auto">
                  <button onClick={() => setCurrentFilters({})} className="flex items-center gap-2 text-h9 uppercase">
                    Clear filters <Icon name="x" className="w-3 pb-px" />
                  </button>
                </div>
              )}
            </div>
          )}

          {/* Card grid */}
          {currentItems.length > 0 ? (
            <OrbProvider>
              <div
                className={cx(
                  'grid grid-cols-1 sm:grid-cols-2 gap-16 sm:gap-x-12 sm:gap-y-24',
                  postType === 'project' && 'md:grid-cols-3'
                )}
              >
                <AnimatePresence>
                  {currentItems.map(({ slug, featuredImage, caseStudyProjectContent, terms }: any) => (
                    <m.div
                      key={slug}
                      initial={{ opacity: 0 }}
                      animate={{ opacity: 1 }}
                      exit={{ opacity: 0 }}
                      className="flex"
                    >
                      <ListingCard
                        postType={postType}
                        href={`${postType === 'case_study' ? 'case-study' : 'project'}/${slug}`}
                        image={featuredImage?.node}
                        title={caseStudyProjectContent.heroSection.customerName}
                        term={getFirstTerm(terms)?.name}
                      />
                    </m.div>
                  ))}
                </AnimatePresence>
              </div>

              <Orb />
            </OrbProvider>
          ) : (
            // No results
            <p className="text-body-lg">No {label.toLowerCase()} match those filters</p>
          )}

          {/* Load more button */}
          {itemsToShow < filteredItems.length && (
            <div className="pt-24 text-center">
              <button
                className="text-body-lg font-semibold"
                onClick={() => setItemsToShow(prev => prev + ITEMS_PER_PAGE)}
              >
                Load More
              </button>
            </div>
          )}
        </Container>
      </div>
    </>
  )
}
