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

import { DateTime } from 'luxon'
import { Suspense } from 'react'
import { ClockIcon } from 'lucide-react'

import { request as req } from '@repo/util/request'
import { Skeleton } from '@repo/ui/components/skeleton'
import { Await } from 'react-router'
import { billingPeriod, formatDate } from './util'
import { Card, CardContent } from '@repo/ui/components/ui/card'
import {
  Table,
  TableBody,
  TableCell,
  TableFooter,
  TableHead,
  TableHeader,
  TableRow
} from '@repo/ui/components/ui/table'
import { Abbr } from '@repo/ui/components/abbr'
import { Button } from '@repo/ui/components/ui/button'

import { RangePeriod } from './range-period'
import { statuses } from './data'
import { cn } from '@repo/ui/lib/utils'

export function meta({}) {
  return [{ title: 'Resumo de cobranças' }]
}

export async function loader({ context, request, params }: Route.LoaderArgs) {
  const { searchParams } = new URL(request.url)
  const subscription = await req({
    url: `/orgs/${params.orgid}/subscription`,
    context,
    request
  }).then((r) => r.json())

  const [startDate, endDate] = billingPeriod(
    subscription?.billing_day || 1,
    new Date()
  )
  const start = searchParams.get('start') || formatDate(startDate)
  const end = searchParams.get('end') || formatDate(endDate)

  const billing = req({
    url: `/orgs/${params.orgid}/billing?start_date=${start}&end_date=${end}`,
    context,
    request
  }).then((r) => r.json())

  return {
    subscription,
    billing,
    startDate: DateTime.fromISO(start).toJSDate(),
    endDate: DateTime.fromISO(end).toJSDate()
  }
}

export default function Route({
  loaderData: { subscription, billing, startDate, endDate }
}: Route.ComponentProps) {
  return (
    <>
      <Suspense fallback={<Skeleton />}>
        <div className="space-y-0.5 mb-8">
          <h1 className="text-2xl font-bold tracking-tight">
            Resumo de cobranças
          </h1>
          <p className="text-muted-foreground">
            Acompanhe as cobranças em tempo real e garanta mais eficiência no
            controle financeiro.
          </p>
        </div>

        <Await resolve={billing}>
          {({ items = [], ...billing }) => {
            const {
              icon: Icon,
              label: status,
              color
            } = statuses?.[billing?.status || 'CLOSED']
            return (
              <Card>
                <CardContent className="space-y-2.5">
                  <div className="flex max-lg:flex-col gap-2.5">
                    <Button
                      className={cn('pointer-events-none', color)}
                      variant="outline"
                      asChild
                    >
                      <span>
                        <Icon className="size-3.5" /> {status}
                      </span>
                    </Button>

                    <RangePeriod
                      startDate={startDate}
                      endDate={endDate}
                      billingDay={subscription.billing_day || 1}
                    />
                  </div>

                  <Table className="table-auto w-full">
                    <TableHeader>
                      <TableRow className="hover:bg-transparent">
                        <TableHead>Colaborador</TableHead>
                        <TableHead>Curso</TableHead>
                        <TableHead>Matriculado por</TableHead>
                        <TableHead>Matriculado em</TableHead>
                        <TableHead>Valor unit.</TableHead>
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {items
                        ?.filter((item) => 'course' in item)
                        ?.map(
                          (
                            {
                              user,
                              course,
                              author: created_by,
                              unit_price,
                              enrolled_at
                            },
                            index
                          ) => (
                            <TableRow key={index}>
                              <TableCell>
                                <Abbr>{user.name}</Abbr>
                              </TableCell>
                              <TableCell>
                                <Abbr>{course.name}</Abbr>
                              </TableCell>
                              <TableCell>
                                <Abbr>
                                  {created_by ? created_by.name : 'N/A'}
                                </Abbr>
                              </TableCell>
                              <TableCell>
                                {datetime.format(new Date(enrolled_at))}
                              </TableCell>
                              <TableCell>
                                {currency.format(unit_price)}
                              </TableCell>
                            </TableRow>
                          )
                        )}

                      {items.length === 0 && (
                        <TableRow className="hover:bg-transparent">
                          <TableCell colSpan={5} className="h-24 text-center">
                            Nenhum resultado.
                          </TableCell>
                        </TableRow>
                      )}
                    </TableBody>
                    <TableFooter>
                      <TableRow className="hover:bg-transparent">
                        <TableCell colSpan={4} className="text-right">
                          Total
                        </TableCell>
                        <TableCell>
                          {currency.format(
                            items
                              ?.filter((item) => 'course' in item)
                              ?.reduce(
                                (acc, { unit_price }) => acc + unit_price,
                                0
                              )
                          )}
                        </TableCell>
                      </TableRow>
                    </TableFooter>
                  </Table>
                </CardContent>
              </Card>
            )
          }}
        </Await>
      </Suspense>
    </>
  )
}
const currency = new Intl.NumberFormat('pt-BR', {
  style: 'currency',
  currency: 'BRL'
})

const datetime = new Intl.DateTimeFormat('pt-BR', {
  day: '2-digit',
  month: '2-digit',
  year: 'numeric',
  hour: '2-digit',
  minute: '2-digit'
})
