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

import { Grid2X2Icon, ListIcon } from 'lucide-react'
import { Suspense, useMemo } from 'react'
import { Await, useSearchParams } from 'react-router'

import { SearchForm } from '@repo/ui/components/search-form'
import { Skeleton } from '@repo/ui/components/skeleton'
import { Kbd } from '@repo/ui/components/ui/kbd'
import { cloudflareContext } from '@repo/auth/context'
import { createSearch } from '@repo/util/meili'
import { request as req } from '@repo/util/request'
import {
  ToggleGroup,
  ToggleGroupItem
} from '@repo/ui/components/ui/toggle-group'

import type { CustomPricing, Course } from './data'
import { List } from './list'
import { Grid } from './grid'

export function meta({}: Route.MetaArgs) {
  return [{ title: 'Catálogo de cursos' }]
}

export async function loader({ context, request, params }: Route.LoaderArgs) {
  const cloudflare = context.get(cloudflareContext)
  const courses = createSearch({
    index: 'saladeaula_courses',
    sort: ['created_at:desc'],
    filter: 'unlisted NOT EXISTS',
    hitsPerPage: 100,
    env: cloudflare.env
  })

  const customPricing = req({
    url: `/orgs/${params.orgid}/custom-pricing`,
    context,
    request
  }).then((r) => r.json() as Promise<{ items: CustomPricing[] }>)

  return {
    data: Promise.all([courses, customPricing])
  }
}

export default function Route({ loaderData: { data } }: Route.ComponentProps) {
  const [searchParams, setSearchParams] = useSearchParams()
  const search = searchParams.get('s') as string
  const view = searchParams.get('view') || 'grid'

  return (
    <Suspense fallback={<Skeleton />}>
      <div className="space-y-0.5 mb-8">
        <h1 className="text-2xl font-bold tracking-tight">
          Catálogo de cursos
        </h1>
        <p className="text-muted-foreground">
          Explore o catálogo de cursos disponíveis para sua empresa.
        </p>
      </div>

      <Await resolve={data}>
        {([{ hits }, { items }]) => {
          const hits_ = hits.filter(
            ({ metadata__unit_price = 0 }) => metadata__unit_price > 0
          ) as Course[]

          return (
            <>
              <div className="flex flex-col lg:flex-row justify-between gap-2.5 mb-2.5">
                <div className="2xl:w-92">
                  <SearchForm
                    placeholder={
                      <>
                        Digite <Kbd className="border font-mono">/</Kbd> para
                        pesquisar
                      </>
                    }
                    defaultValue={search}
                    onChange={(search) => {
                      setSearchParams((searchParams) => {
                        searchParams.set('s', String(search))
                        return searchParams
                      })
                    }}
                  />
                </div>

                <ToggleGroup
                  variant="outline"
                  type="single"
                  value={view}
                  className="**:cursor-pointer"
                  onValueChange={(value) => {
                    setSearchParams((searchParams) => {
                      searchParams.set('view', value)
                      return searchParams
                    })
                  }}
                >
                  <ToggleGroupItem value="list">
                    <ListIcon />
                  </ToggleGroupItem>
                  <ToggleGroupItem value="grid">
                    <Grid2X2Icon />
                  </ToggleGroupItem>
                </ToggleGroup>
              </div>

              {view === 'list' ? (
                <List search={search} hits={hits_} customPricing={items} />
              ) : (
                <Grid search={search} hits={hits_} customPricing={items} />
              )}
            </>
          )
        }}
      </Await>
    </Suspense>
  )
}
