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

import { ErrorMessage } from '@hookform/error-message'
import { zodResolver } from '@hookform/resolvers/zod'
import {
  CircleQuestionMarkIcon,
  CopyIcon,
  PlusIcon,
  Trash2Icon
} from 'lucide-react'
import { Fragment } from 'react'
import { Controller, useFieldArray, useForm } from 'react-hook-form'
import { Link } from 'react-router'

import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator
} from '@repo/ui/components/ui/breadcrumb'
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle
} from '@repo/ui/components/ui/card'
import {
  HoverCard,
  HoverCardContent,
  HoverCardTrigger
} from '@repo/ui/components/ui/hover-card'
import { Kbd } from '@repo/ui/components/ui/kbd'
import { request as req } from '@repo/util/request'

import { Button } from '@repo/ui/components/ui/button'
import { useParams } from 'react-router'
import { CoursePicker } from '../_.$orgid.enrollments.add/course-picker'
import {
  formSchema,
  MAX_ITEMS,
  type User
} from '../_.$orgid.enrollments.add/data'
import {
  Cell,
  DuplicateRowMultipleTimes,
  emptyRow
} from '../_.$orgid.enrollments.add/route'
import { ScheduledForInput } from '../_.$orgid.enrollments.add/scheduled-for'
import { UserPicker } from '../_.$orgid.enrollments.add/user-picker'

export function meta({}: Route.MetaArgs) {
  return [{ title: 'Adicionar matrícula' }]
}

export async function loader({ request, params, context }: Route.LoaderArgs) {
  const seats = await req({
    url: `/orgs/${params.orgid}/seats`,
    request,
    context
  })
    .then((r) => r.json() as any)
    .then(({ items }) => items)

  const courses = new Promise((resolve, reject) => {
    resolve({
      hits: seats.map(({ course }) => ({ metadata__unit_price: 1, ...course }))
    })
  })
  return { seats, courses }
}

export default function Route({
  loaderData: { courses }
}: Route.ComponentProps) {
  const { orgid } = useParams()
  const form = useForm({
    resolver: zodResolver(formSchema),
    defaultValues: { enrollments: [emptyRow] }
  })
  const { formState, control, handleSubmit, getValues, setValue } = form
  const { fields, insert, remove, append } = useFieldArray({
    control,
    name: 'enrollments'
  })

  const onSearch = async (search: string) => {
    const params = new URLSearchParams({ q: search })
    const r = await fetch(`/${orgid}/users.json?${params.toString()}`)
    const { hits } = (await r.json()) as { hits: User[] }
    return hits
  }

  const duplicateRow = (index: number, times: number = 1) => {
    if (fields.length + times > MAX_ITEMS) {
      return null
    }

    const { user, ...rest } = getValues(`enrollments.${index}`)
    Array.from({ length: times }, (_, i) => {
      // @ts-ignore
      insert(index + 1 + i, rest)
    })
  }

  return (
    <div className="space-y-2.5">
      <Breadcrumb>
        <BreadcrumbList>
          <BreadcrumbItem>
            <BreadcrumbLink asChild>
              <Link to="../enrollments">Matrículas</Link>
            </BreadcrumbLink>
          </BreadcrumbItem>
          <BreadcrumbSeparator />
          <BreadcrumbItem>
            <BreadcrumbPage>Adicionar matrículas</BreadcrumbPage>
          </BreadcrumbItem>
        </BreadcrumbList>
      </Breadcrumb>

      <Card className="lg:max-w-4xl mx-auto">
        <CardHeader>
          <CardTitle className="text-2xl">Adicionar matrículas</CardTitle>
          <CardDescription>
            Siga os passos abaixo para adicionar colaboradores às matrículas
            abertas.
          </CardDescription>
        </CardHeader>

        <CardContent className="space-y-4">
          <div className="grid lg:grid-cols-[repeat(3,1fr)_auto] w-full gap-3">
            {/* Header */}
            <>
              <Cell>Colaborador</Cell>
              <Cell>Curso</Cell>
              <Cell className="flex items-center gap-1.5">
                Matricular em
                <HoverCard openDelay={0}>
                  <HoverCardTrigger asChild>
                    <button type="button">
                      <CircleQuestionMarkIcon className="size-4 text-muted-foreground" />
                    </button>
                  </HoverCardTrigger>
                  <HoverCardContent
                    align="end"
                    className="text-sm space-y-1.5 lg:w-76"
                  >
                    <p>
                      Escolha a data em que o colaborador será matriculado no
                      curso.
                    </p>

                    <p>
                      Você poderá acompanhar as matrículas em{' '}
                      <Kbd>Agendamentos</Kbd>
                    </p>
                  </HoverCardContent>
                </HoverCard>
              </Cell>
              <Cell>{/**/}</Cell>
            </>

            {/* Rows */}
            <>
              {fields.map((field, index) => (
                <Fragment key={field.id}>
                  {/* Separator only for mobile */}
                  {index >= 1 && <div className="h-2.5 lg:hidden"></div>}

                  <Controller
                    control={control}
                    name={`enrollments.${index}.user`}
                    render={({
                      field: { name, value, onChange },
                      fieldState
                    }) => (
                      <div className="grid gap-1">
                        <UserPicker
                          value={value}
                          onChange={onChange}
                          onSearch={onSearch}
                          fieldState={fieldState}
                        />

                        <ErrorMessage
                          errors={formState.errors}
                          name={name}
                          render={({ message }) => (
                            <p className="text-destructive text-sm">
                              {message}
                            </p>
                          )}
                        />
                      </div>
                    )}
                  />

                  <Controller
                    control={control}
                    name={`enrollments.${index}.course`}
                    render={({
                      field: { name, value, onChange },
                      fieldState
                    }) => (
                      <div className="grid gap-1">
                        <CoursePicker
                          value={value}
                          onChange={onChange}
                          options={courses}
                          error={fieldState.error}
                          readOnly
                        />
                        <ErrorMessage
                          errors={formState.errors}
                          name={name}
                          render={({ message }) => (
                            <p className="text-destructive text-sm">
                              {message}
                            </p>
                          )}
                        />
                      </div>
                    )}
                  />

                  <Controller
                    control={control}
                    name={`enrollments.${index}.scheduled_for`}
                    render={({ field: { value, onChange } }) => (
                      <ScheduledForInput value={value} onChange={onChange} />
                    )}
                  />

                  {/* Action */}
                  <div className="flex gap-1.5">
                    <Button
                      type="button"
                      tabIndex={-1}
                      variant="outline"
                      className="cursor-pointer"
                      onClick={() => duplicateRow(index)}
                      title="Duplicar linha"
                    >
                      <CopyIcon />
                    </Button>

                    <DuplicateRowMultipleTimes
                      index={index}
                      duplicateRow={duplicateRow}
                    />

                    <Button
                      tabIndex={-1}
                      variant="destructive"
                      className="cursor-pointer"
                      disabled={fields.length == 1}
                      onClick={() => remove(index)}
                    >
                      <Trash2Icon />
                    </Button>
                  </div>
                </Fragment>
              ))}
            </>
          </div>

          <div className="max-lg:mt-2.5">
            <Button
              type="button"
              // @ts-ignore
              onClick={() => append(emptyRow)}
              className="cursor-pointer"
              disabled={fields.length == MAX_ITEMS}
              variant="outline"
              size="sm"
            >
              <PlusIcon /> Adicionar
            </Button>
          </div>
        </CardContent>
      </Card>
    </div>
  )
}
