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

import { formatCEP } from '@brazilian-utils/brazilian-utils'
import {
  AlertCircleIcon,
  ArrowLeftRightIcon,
  HelpCircleIcon
} from 'lucide-react'
import { useEffect } from 'react'
import { Link } from 'react-router'

import { Currency } from '@repo/ui/components/currency'
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator
} from '@repo/ui/components/ui/breadcrumb'
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle
} from '@repo/ui/components/ui/card'
import {
  Item,
  ItemContent,
  ItemGroup,
  ItemTitle
} from '@repo/ui/components/ui/item'
import {
  Table,
  TableBody,
  TableCell,
  TableFooter,
  TableHead,
  TableHeader,
  TableRow
} from '@repo/ui/components/ui/table'
import { request as req } from '@repo/util/request'

import { Abbr } from '@repo/ui/components/abbr'
import { Badge } from '@repo/ui/components/ui/badge'
import { Button } from '@repo/ui/components/ui/button'
import { Kbd } from '@repo/ui/components/ui/kbd'
import { cn } from '@repo/ui/lib/utils'
import {
  labels,
  statuses,
  type Order as Order_
} from '@repo/ui/routes/orders/data'

import type { CreditCard as CreditCard_ } from '../_.$orgid.enrollments.buy/payment'
import type { Address } from '../_.$orgid.enrollments.buy/review'
import { useWizardStore } from '../_.$orgid.enrollments.buy/store'

export function meta() {
  return [
    {
      title: 'Detalhes do pagamento'
    }
  ]
}

const PaymentMethodComponent = {
  PIX: Pix,
  BANK_SLIP: BankSlip,
  CREDIT_CARD: CreditCard
}

type Item_ = {
  id: string
  name: string
  unit_price: number
  quantity: number
}

type User = {
  id: string
  name: string
}

type Order = Order_ & {
  items: Item_[]
  interest_amount: number
  due_date: string
  created_at: string
  subtotal: number
  discount: number
  address: Address
  credit_card?: CreditCard_
  coupon?: string
  installments?: number
  created_by?: User
}

export async function loader({ context, request, params }: Route.LoaderArgs) {
  const order = (await req({
    url: `/orders/${params.id}`,
    context,
    request
  }).then((r) => r.json())) as Order

  return { order }
}

export default function Route({ loaderData: { order } }: Route.ComponentProps) {
  const { reset } = useWizardStore()
  const {
    coupon,
    address,
    total,
    payment_method,
    interest_amount,
    discount,
    subtotal,
    items = []
  } = order

  const Component = PaymentMethodComponent[payment_method]

  useEffect(() => {
    reset()
  }, [])

  return (
    <div className="space-y-2.5">
      <Breadcrumb>
        <BreadcrumbList>
          <BreadcrumbItem>
            <BreadcrumbLink asChild>
              <Link to="../payments">Pagamentos</Link>
            </BreadcrumbLink>
          </BreadcrumbItem>
          <BreadcrumbSeparator />
          <BreadcrumbItem>
            <BreadcrumbPage>Detalhes do pagamento</BreadcrumbPage>
          </BreadcrumbItem>
        </BreadcrumbList>
      </Breadcrumb>

      <Card className="lg:max-w-4xl mx-auto">
        <CardHeader className="gap-0">
          <CardTitle className="text-2xl">Detalhes do pagamento</CardTitle>
        </CardHeader>

        <CardContent className="space-y-4">
          <ItemGroup className="grid lg:grid-cols-2 gap-4">
            <Item variant="outline">
              <ItemContent>
                <ItemTitle>Endereço de cobrança</ItemTitle>
                <ul className="text-muted-foreground text-sm leading-normal font-normal text-balance">
                  {address?.address1}
                  {address?.address2 ? <>, {address?.address2}</> : null}
                  <br />
                  {address?.neighborhood}
                  <br />
                  {address?.city}, {address?.state}
                  <br />
                  {formatCEP(address?.postcode)}
                </ul>
              </ItemContent>
            </Item>

            <Item variant="outline" className="items-start">
              <ItemContent>
                <ItemTitle>Forma de pagamento</ItemTitle>
                <div className="text-muted-foreground text-sm leading-normal font-normal text-balance">
                  {Component && <Component {...order} />}
                </div>
              </ItemContent>
            </Item>
          </ItemGroup>

          <Table className="pointer-events-none">
            <TableHeader>
              <TableRow>
                <TableHead>Curso</TableHead>
                <TableHead>Quantidade</TableHead>
                <TableHead>Valor unit.</TableHead>
                <TableHead>Total</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {items?.map(({ name, unit_price, quantity }, index) => {
                return (
                  <TableRow key={index}>
                    <TableCell>{name}</TableCell>
                    <TableCell>{quantity}</TableCell>
                    <TableCell>
                      <Currency>{unit_price}</Currency>
                    </TableCell>
                    <TableCell>
                      <Currency>{unit_price * quantity}</Currency>
                    </TableCell>
                  </TableRow>
                )
              })}
            </TableBody>

            {/* Summary */}
            <TableFooter>
              <TableRow>
                <TableCell className="text-right" colSpan={3}>
                  Subtotal
                </TableCell>
                <TableCell>
                  <Currency>{subtotal}</Currency>
                </TableCell>
              </TableRow>
              {/* Discount */}
              <TableRow>
                <TableCell colSpan={3}>
                  <span className="flex gap-1 justify-end">
                    Descontos
                    {coupon && (
                      <Kbd>
                        <Abbr maxLen={8}>{coupon}</Abbr>
                      </Kbd>
                    )}
                  </span>
                </TableCell>
                <TableCell>
                  <Currency>{discount}</Currency>
                </TableCell>
              </TableRow>
              {/* Interest */}
              {interest_amount ? (
                <TableRow>
                  <TableCell className="text-right" colSpan={3}>
                    Juros
                  </TableCell>
                  <TableCell>
                    <Currency>{interest_amount}</Currency>
                  </TableCell>
                </TableRow>
              ) : (
                <></>
              )}
              {/* Total */}
              <TableRow>
                <TableCell className="text-right" colSpan={3}>
                  Total
                </TableCell>
                <TableCell>
                  <Currency>{total}</Currency>
                </TableCell>
              </TableRow>
            </TableFooter>
          </Table>
        </CardContent>
      </Card>

      {/*<pre>{JSON.stringify(order, null, 2)}</pre>*/}
    </div>
  )
}

function Status({ status: s }: { status: string }) {
  const status = labels[s] ?? s
  const { icon: Icon, color } = statuses?.[s] ?? { icon: HelpCircleIcon }

  return (
    <Badge variant="outline" className={cn(color, ' px-1.5')}>
      <Icon className={cn('stroke-2', color)} />
      {status}
    </Badge>
  )
}

type PaymentMethodProps = {
  status: string
  total: number
  installments: number
}

type CreditCardProps = PaymentMethodProps & {
  stats: { last_attempt_succeeded: boolean }
  credit_card: { last4: string; brand: string }
}

function CreditCard({
  status,
  total,
  credit_card,
  installments,
  stats
}: CreditCardProps) {
  return (
    <>
      <ul className="flex max-lg:flex-col gap-x-1.5">
        <li>
          {credit_card.brand} (Crédito) **** {credit_card.last4}
        </li>
        <li>
          {!stats.last_attempt_succeeded ? (
            <Badge
              variant="outline"
              className="text-red-400 border-red-400 px-1.5"
            >
              <AlertCircleIcon /> Transação negada
            </Badge>
          ) : (
            <Status status={status} />
          )}
        </li>
      </ul>

      <p>
        {installments}x <Currency>{total / Number(installments)}</Currency>
      </p>

      {!stats.last_attempt_succeeded ? (
        <div className="flex justify-center mt-2">
          <Button size="sm" variant="secondary" className="cursor-pointer">
            <ArrowLeftRightIcon /> Tentar com outro cartão
          </Button>
        </div>
      ) : null}
    </>
  )
}

type BankSlipProps = PaymentMethodProps & {}

function BankSlip({ status }: BankSlipProps) {
  return (
    <ul className="flex max-lg:flex-col gap-x-1.5">
      <li>Boleto bancário</li>
      <li>
        <Status status={status} />
      </li>
    </ul>
  )
}

type PixProps = PaymentMethodProps & {}

function Pix({}: PixProps) {
  return <>Pix</>
}
