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

import { BookCopyIcon, PlusCircleIcon, PlusIcon } from 'lucide-react'
import { DateTime } from 'luxon'
import { MeiliSearchFilterBuilder } from 'meilisearch-helper'
import { Suspense, useState } from 'react'
import { Await, Link, useSearchParams } from 'react-router'

import { CustomizeColumns, DataTable } from '@/components/data-table'
import { FacetedFilter } from '@/components/faceted-filter'
import { RangeCalendarFilter } from '@/components/range-calendar-filter'
import { SearchForm } from '@/components/search-form'
import { Skeleton } from '@/components/skeleton'
import { Button } from '@/components/ui/button'
import { Kbd } from '@/components/ui/kbd'
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectTrigger,
  SelectValue
} from '@/components/ui/select'
import { createSearch } from '@/lib/meili'
import { columns, statuses, type Enrollment } from './columns'

export function meta({}: Route.MetaArgs) {
  return [{ title: 'Matrículas' }]
}

const dtOptions = {
  zone: 'America/Sao_Paulo'
}

export async function loader({ params, context, request }: Route.LoaderArgs) {
  const { searchParams } = new URL(request.url)
  const { orgid } = params
  const query = searchParams.get('q') || ''
  const field = searchParams.get('field') || ''
  const from = searchParams.get('from') || ''
  const to = searchParams.get('to') || ''
  const status = searchParams.getAll('status') || []
  const page = Number(searchParams.get('p')) + 1
  const hitsPerPage = Number(searchParams.get('perPage')) || 25

  let builder = new MeiliSearchFilterBuilder().where('org_id', '=', orgid)

  if (status.length) {
    builder = builder.where('status', 'in', status)
  }

  if (field && from && to) {
    builder = builder.where(field, 'between', [from, to])
  }

  return {
    data: createSearch({
      index: 'betaeducacao-prod-enrollments',
      sort: ['created_at:desc'],
      filter: builder.build(),
      query,
      page,
      hitsPerPage,
      env: context.cloudflare.env
    })
  }
}

const formatted = new Intl.DateTimeFormat('en-CA', {
  year: 'numeric',
  month: '2-digit',
  day: '2-digit'
})

export default function Route({ loaderData: { data } }) {
  const [searchParams, setSearchParams] = useSearchParams()
  const [from, to] = [searchParams.get('from'), searchParams.get('to')]
  const [rangeField, setRangeField] = useState<string>(
    searchParams.get('field') || 'created_at'
  )

  return (
    <Suspense fallback={<Skeleton />}>
      <div className="space-y-0.5 mb-8">
        <h1 className="text-2xl font-bold tracking-tight">
          Gerenciar matrículas
        </h1>
        <p className="text-muted-foreground">
          Matricule colaboradores de forma rápida e acompanhe seu progresso.
        </p>
      </div>

      <Await resolve={data}>
        {({ hits, page, hitsPerPage, totalHits }) => {
          return (
            <DataTable
              columns={columns}
              data={hits as Enrollment[]}
              pageIndex={page - 1}
              pageSize={hitsPerPage}
              rowCount={totalHits}
              hiddenColumn={[
                'completed_at',
                'started_at',
                'failed_at',
                'canceled_at'
              ]}
            >
              <div className="flex flex-col 2xl:flex-row gap-2.5 mb-2.5">
                <div className="w-full 2xl:w-1/3">
                  <SearchForm
                    defaultValue={searchParams.get('q') || ''}
                    placeholder={
                      <>
                        Pressione <Kbd className="border font-mono">/</Kbd> para
                        pesquisar...
                      </>
                    }
                    onChange={(value) =>
                      setSearchParams((searchParams) => {
                        searchParams.set('q', String(value))
                        searchParams.delete('p')
                        return searchParams
                      })
                    }
                  />
                </div>

                <div className="flex gap-2.5 max-lg:flex-col w-full">
                  <div className="flex gap-2.5 max-lg:flex-col">
                    <FacetedFilter
                      icon={BookCopyIcon}
                      className="lg:flex-1"
                      value={searchParams.getAll('courses')}
                      onChange={(courses) => {
                        setSearchParams((searchParams) => {
                          searchParams.delete('courses')
                          searchParams.delete('p')

                          if (statuses.length) {
                            courses.forEach((s) =>
                              searchParams.has('courses', s)
                                ? null
                                : searchParams.append('courses', s)
                            )
                          }

                          return searchParams
                        })
                      }}
                      title="Cursos"
                      options={Object.entries(statuses).map(([key, value]) => ({
                        value: key,
                        ...value
                      }))}
                    />

                    <FacetedFilter
                      icon={PlusCircleIcon}
                      className="lg:flex-1"
                      value={searchParams.getAll('status')}
                      onChange={(statuses) => {
                        setSearchParams((searchParams) => {
                          searchParams.delete('status')
                          searchParams.delete('p')

                          if (statuses.length) {
                            statuses.forEach((s) =>
                              searchParams.has('status', s)
                                ? null
                                : searchParams.append('status', s)
                            )
                          }

                          return searchParams
                        })
                      }}
                      title="Status"
                      options={Object.entries(statuses).map(([key, value]) => ({
                        value: key,
                        ...value
                      }))}
                    />

                    <RangeCalendarFilter
                      className="lg:flex-1"
                      value={
                        from && to
                          ? {
                              from: DateTime.fromISO(from, dtOptions),
                              to: DateTime.fromISO(to, dtOptions)
                            }
                          : undefined
                      }
                      onChange={(dateRange) => {
                        setSearchParams((searchParams) => {
                          if (dateRange) {
                            searchParams.set('field', rangeField)
                            searchParams.set(
                              'from',
                              formatted.format(dateRange.from)
                            )
                            searchParams.set(
                              'to',
                              formatted.format(dateRange.to)
                            )
                          } else {
                            searchParams.delete('from')
                            searchParams.delete('to')
                            searchParams.delete('field')
                          }

                          return searchParams
                        })
                      }}
                    >
                      <div className="p-2.5">
                        <Select
                          defaultValue={rangeField}
                          onValueChange={(field) => {
                            setRangeField(field)
                            setSearchParams((searchParams) => {
                              if (searchParams.has('from')) {
                                searchParams.set('field', field)
                              }

                              return searchParams
                            })
                          }}
                        >
                          <SelectTrigger className="w-full">
                            <SelectValue />
                          </SelectTrigger>
                          <SelectContent>
                            <SelectGroup>
                              <SelectItem value="created_at">
                                Matriculado em
                              </SelectItem>
                              <SelectItem value="started_at">
                                Iniciado em
                              </SelectItem>
                              <SelectItem value="completed_at">
                                Aprovado em
                              </SelectItem>
                              <SelectItem value="failed_at">
                                Reprovado em
                              </SelectItem>
                              <SelectItem value="canceled_at">
                                Cancelado em
                              </SelectItem>
                            </SelectGroup>
                          </SelectContent>
                        </Select>
                      </div>
                    </RangeCalendarFilter>
                  </div>

                  <div className="lg:ml-auto flex gap-2.5">
                    <CustomizeColumns className="flex-1" />

                    <Button className="flex-1" asChild>
                      <Link to="add">
                        <PlusIcon /> Adicionar
                      </Link>
                    </Button>
                  </div>
                </div>
              </div>
            </DataTable>
          )
        }}
      </Await>
    </Suspense>
  )
}
