'use client'

import React, { useState, useEffect, useMemo } from 'react'
import { ProjectCard } from '@/components/ProjectCard'
import projectsData from '../../../public/projects.json'
import { projectsSchema, Project, Tag } from '@/typings/project'
import { useInView } from 'react-intersection-observer'

const Page = () => {
  const parsedProjects = projectsSchema.safeParse(projectsData)

  if (!parsedProjects.success) {
    console.error('Invalid project data', parsedProjects.error)
    return <div>Error loading projects</div>
  }

  const projects: Project[] = parsedProjects.data

  const [currentPage, setCurrentPage] = useState(1)
  const [itemsPerPage] = useState<number>(12)
  const [filterTag, setFilterTag] = useState<Tag | null>(null)
  const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('asc')

  const { ref, inView } = useInView({
    threshold: 1.0,
  })

  const handleFilterChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
    setFilterTag(
      event.target.value === 'All' ? null : (event.target.value as Tag)
    )
    setCurrentPage(1)
  }

  const handleSortChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
    setSortOrder(event.target.value as 'asc' | 'desc')
    setCurrentPage(1)
  }

  const filteredAndSortedProjects = useMemo(() => {
    let updatedProjects = filterTag
      ? projects.filter(project => project.tags.includes(filterTag))
      : projects

    updatedProjects = [...updatedProjects].sort((a, b) => {
      if (sortOrder === 'asc') {
        return a.name.localeCompare(b.name)
      } else {
        return b.name.localeCompare(a.name)
      }
    })

    return updatedProjects
  }, [projects, filterTag, sortOrder])

  const visibleProjects = useMemo(() => {
    return filteredAndSortedProjects.slice(0, currentPage * itemsPerPage)
  }, [filteredAndSortedProjects, currentPage, itemsPerPage])

  useEffect(() => {
    if (
      inView &&
      currentPage * itemsPerPage < filteredAndSortedProjects.length
    ) {
      setCurrentPage(prevPage => prevPage + 1)
    }
  }, [inView, currentPage, itemsPerPage, filteredAndSortedProjects.length])

  return (
    <div>
      <div className="mb-4 flex gap-4">
        <select
          onChange={handleFilterChange}
          className="rounded border border-gray-300 bg-white p-2 text-gray-900 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100"
        >
          <option value="All">All Tags</option>
          {Array.from(new Set(projects.flatMap(project => project.tags))).map(
            tag => (
              <option key={tag} value={tag}>
                {tag}
              </option>
            )
          )}
        </select>
        <select
          onChange={handleSortChange}
          className="rounded border border-gray-300 bg-white p-2 text-gray-900 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100"
        >
          <option value="asc">Sort by Name (A-Z)</option>
          <option value="desc">Sort by Name (Z-A)</option>
        </select>
      </div>
      <div className="m-8 flex flex-wrap justify-center gap-6">
        {visibleProjects.map((project, index) => (
          <ProjectCard project={project} key={index} />
        ))}
      </div>
      <div ref={ref}></div>
    </div>
  )
}

export default Page
