import type { Route } from './+types/index'

import Fuse from 'fuse.js'
import {
  AwardIcon,
  BanIcon,
  FileBadgeIcon,
  HatGlassesIcon,
  LaptopIcon
} from 'lucide-react'
import { Suspense, useMemo } from 'react'
import { Await, NavLink, useSearchParams } from 'react-router'

import { createSearch } from '@repo/util/meili'
import { SearchForm } from '@repo/ui/components/search-form'
import { Skeleton } from '@repo/ui/components/skeleton'
import {
  Card,
  CardFooter,
  CardHeader,
  CardTitle
} from '@repo/ui/components/ui/card'
import {
  Empty,
  EmptyDescription,
  EmptyHeader,
  EmptyMedia,
  EmptyTitle
} from '@repo/ui/components/ui/empty'
import { Kbd } from '@repo/ui/components/ui/kbd'
import { Spinner } from '@repo/ui/components/ui/spinner'
import {
  Tooltip,
  TooltipContent,
  TooltipTrigger
} from '@repo/ui/components/ui/tooltip'

import type { Course } from './edit'
import placeholder from '@/assets/placeholder.webp'
import { cn } from '@repo/ui/lib/utils'

export function meta({}: Route.MetaArgs) {
  return [{ title: 'Gerenciar seus cursos' }]
}

export const loader = async ({ context }: Route.ActionArgs) => {
  const courses = createSearch({
    index: 'saladeaula_courses',
    sort: ['created_at:desc'],
    hitsPerPage: 100,
    env: context.cloudflare.env
  })

  return {
    data: courses
  }
}

export default function Component({ loaderData: { data } }) {
  const [searchParams, setSearchParams] = useSearchParams()
  const term = searchParams.get('term') as string

  return (
    <Suspense fallback={<Skeleton />}>
      <div className="space-y-4">
        <div className="space-y-0.5 mb-8">
          <h1 className="text-2xl font-bold tracking-tight">Cursos</h1>
          <p className="text-muted-foreground">
            Gerencie seus cursos com facilidade e organize seu conteúdo.
          </p>
        </div>

        <div className="w-full xl:w-1/3">
          <SearchForm
            placeholder={
              <>
                Digite <Kbd>/</Kbd> para pesquisar
              </>
            }
            defaultValue={term}
            onChange={(term) => {
              setSearchParams({ term })
            }}
          />
        </div>

        <Await resolve={data}>
          {({ hits = [] }) => <List term={term} hits={hits} />}
        </Await>
      </div>
    </Suspense>
  )
}

function List({ term, hits = [] }: { term: string; hits: Course[] }) {
  const fuse = useMemo(() => {
    return new Fuse(hits, {
      keys: ['name'],
      threshold: 0.3,
      includeMatches: true
    })
  }, [hits])

  const hits_ = useMemo(() => {
    if (!term) {
      return hits
    }

    return fuse.search(term).map(({ item }) => item)
  }, [term, fuse, hits])

  if (hits_.length === 0) {
    return (
      <Empty className="border border-dashed">
        <EmptyHeader>
          <EmptyMedia variant="icon">
            <BanIcon />
          </EmptyMedia>
          <EmptyTitle>Nada encontrado</EmptyTitle>
          <EmptyDescription>
            Nenhum resultado para <mark>{term}</mark>.
          </EmptyDescription>
        </EmptyHeader>
      </Empty>
    )
  }

  return (
    <div className="grid lg:grid-cols-4 gap-5">
      {hits_.map((props: Course, idx) => {
        return <Course key={idx} {...props} />
      })}
    </div>
  )
}

function Course({ id, name, access_period, cert, unlisted }: Course) {
  return (
    <NavLink to={`/edit/${id}`} className="hover:scale-105 transition">
      {({ isPending }) => (
        <Card
          className={cn(
            'overflow-hidden relative h-96',
            unlisted && 'border-dashed'
          )}
        >
          {isPending && (
            <div className="absolute bottom-0 right-0 p-6 z-1">
              <Spinner className="size-6" />
            </div>
          )}

          <CardHeader className="z-1 relative">
            <CardTitle className="text-xl/6">{name}</CardTitle>
          </CardHeader>

          <CardFooter className="text-gray-300 text-sm absolute z-1 bottom-6 w-full flex gap-1.5">
            <ul className="flex gap-2.5">
              <li>
                <Tooltip>
                  <TooltipTrigger className="flex gap-0.5 items-center">
                    <LaptopIcon className="size-4" />
                    <span>{access_period}d</span>
                  </TooltipTrigger>
                  <TooltipContent>
                    <p>Tempo de acesso ao curso</p>
                  </TooltipContent>
                </Tooltip>
              </li>

              {cert?.exp_interval && (
                <li>
                  <Tooltip>
                    <TooltipTrigger className="flex gap-0.5 items-center">
                      <AwardIcon className="size-4" />
                      <span>{cert.exp_interval}d</span>
                    </TooltipTrigger>
                    <TooltipContent>
                      <p>Perído de validade do certificado</p>
                    </TooltipContent>
                  </Tooltip>
                </li>
              )}

              {cert?.s3_uri && (
                <li className="flex items-center">
                  <FileBadgeIcon className="size-4" />
                </li>
              )}

              {unlisted && (
                <li className="flex items-center">
                  <HatGlassesIcon className="size-4" />
                </li>
              )}
            </ul>
          </CardFooter>

          <img
            src={placeholder}
            alt={name}
            className="absolute bottom-0 opacity-75"
          />
        </Card>
      )}
    </NavLink>
  )
}
