import {
  ActionIcon,
  Button,
  Card,
  Center,
  Container,
  Group,
  Loader,
  SimpleGrid,
  Stack,
  Table,
  Text,
} from "@mantine/core";
import { useQuery } from "@tanstack/react-query";
import { ArrowLeft, Download } from "lucide-react";
import { useState } from "react";
import { useNavigate, useParams } from "react-router-dom";

import {
  InvoiceStatusBadge,
  formatDate,
  formatMoney,
  humanize,
} from "@/components/customers";
import { PageContainer, PageHeader } from "@/components/page";
import { api } from "@/services/api";
import { invoicesService } from "@/services/invoices.service";

function openPdfBlob(blob: Blob, filename: string) {
  const url = URL.createObjectURL(blob);
  const opened = window.open(url, "_blank");
  if (!opened) {
    const a = document.createElement("a");
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    a.remove();
  }
  setTimeout(() => URL.revokeObjectURL(url), 60_000);
}

function InfoField({ label, value }: { label: string; value?: string | null }) {
  return (
    <Stack gap={2}>
      <Text
        size="xs"
        fw={600}
        c="edr-muted"
        tt="uppercase"
        style={{ letterSpacing: "0.04em" }}
      >
        {label}
      </Text>
      <Text size="sm" c="edr-text">
        {value && value.trim() ? value : "—"}
      </Text>
    </Stack>
  );
}

export default function InvoiceDetailPage() {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const [downloading, setDownloading] = useState(false);

  const { data: invoice, isLoading } = useQuery(
    api.invoices.getById.queryOptions({
      input: { id: id ?? "" },
      enabled: Boolean(id),
    }),
  );

  const downloadDocument = async () => {
    if (!id) return;
    setDownloading(true);
    try {
      const { data } = await invoicesService.downloadDocument(id);
      openPdfBlob(data, `${invoice?.invoiceNumber ?? "invoice"}.pdf`);
    } finally {
      setDownloading(false);
    }
  };

  if (isLoading) {
    return (
      <Center mih="60vh">
        <Loader />
      </Center>
    );
  }

  if (!invoice) {
    return (
      <Container size="sm" py="xl">
        <Stack align="center" gap="md">
          <Text fw={700}>Invoice not found</Text>
          <Button
            variant="default"
            leftSection={<ArrowLeft size={16} />}
            onClick={() => navigate("/dashboard/invoices")}
          >
            Back to invoices
          </Button>
        </Stack>
      </Container>
    );
  }

  return (
    <PageContainer>
      <PageHeader
        breadcrumbs={[
          { label: "Invoices", href: "/dashboard/invoices" },
          { label: invoice.invoiceNumber },
        ]}
        backTo="/dashboard/invoices"
        title={invoice.invoiceNumber}
        subtitle={`${humanize(invoice.source)} · ${invoice.sourceId}`}
        meta={<InvoiceStatusBadge status={invoice.status} />}
        action={
          <ActionIcon
            variant="default"
            size="lg"
            radius="md"
            aria-label="Download invoice"
            loading={downloading}
            onClick={() => void downloadDocument()}
          >
            <Download size={16} />
          </ActionIcon>
        }
      />

      <Stack gap="lg">
        <Card>
          <Stack gap="lg">
            <Text fw={600} c="edr-text">
              Summary
            </Text>
            <SimpleGrid cols={{ base: 1, sm: 2, lg: 4 }} spacing="lg">
              <InfoField label="Billed to" value={invoice.company?.name} />
              <InfoField
                label="Profile"
                value={invoice.companyProfile?.reference}
              />
              <InfoField label="Type" value={humanize(invoice.type)} />
              <InfoField label="Currency" value={invoice.currency} />
              <InfoField label="Issued" value={formatDate(invoice.issuedAt)} />
              <InfoField label="Due" value={formatDate(invoice.dueAt)} />
              <InfoField
                label="Total"
                value={formatMoney(invoice.totalAmount, invoice.currency)}
              />
              <InfoField
                label="Balance"
                value={formatMoney(invoice.balanceAmount, invoice.currency)}
              />
            </SimpleGrid>
          </Stack>
        </Card>

        <Card>
          <Stack gap="md">
            <Text fw={600} c="edr-text">
              Line items
            </Text>
            <Table striped withRowBorders={false} verticalSpacing="xs">
              <Table.Thead>
                <Table.Tr>
                  <Table.Th>Description</Table.Th>
                  <Table.Th>Charge type</Table.Th>
                  <Table.Th ta="right">Quantity</Table.Th>
                  <Table.Th ta="right">Unit rate</Table.Th>
                  <Table.Th ta="right">Amount</Table.Th>
                </Table.Tr>
              </Table.Thead>
              <Table.Tbody>
                {(invoice.lines ?? []).map((line) => (
                  <Table.Tr key={line.id}>
                    <Table.Td>{line.description ?? line.chargeType}</Table.Td>
                    <Table.Td>
                      <Text size="sm" c="dimmed">
                        {humanize(line.chargeType)}
                      </Text>
                    </Table.Td>
                    <Table.Td ta="right">{line.quantity}</Table.Td>
                    <Table.Td ta="right">
                      {formatMoney(line.unitRate, line.currency)}
                    </Table.Td>
                    <Table.Td ta="right">
                      {formatMoney(line.amount, line.currency)}
                    </Table.Td>
                  </Table.Tr>
                ))}
                {(invoice.lines ?? []).length === 0 && (
                  <Table.Tr>
                    <Table.Td colSpan={5}>
                      <Text size="sm" c="dimmed" ta="center" py="md">
                        No line items.
                      </Text>
                    </Table.Td>
                  </Table.Tr>
                )}
              </Table.Tbody>
            </Table>

            <Group
              justify="flex-end"
              gap="xl"
              pt="sm"
              style={{
                borderTop: "1px solid var(--mantine-color-edr-border-0)",
              }}
            >
              <Stack gap={2} align="flex-end">
                <Text size="xs" c="edr-muted">
                  Subtotal
                </Text>
                <Text size="sm">
                  {formatMoney(invoice.subtotalAmount, invoice.currency)}
                </Text>
              </Stack>
              <Stack gap={2} align="flex-end">
                <Text size="xs" c="edr-muted">
                  Tax
                </Text>
                <Text size="sm">
                  {formatMoney(invoice.taxAmount, invoice.currency)}
                </Text>
              </Stack>
              <Stack gap={2} align="flex-end">
                <Text size="xs" c="edr-muted">
                  Paid
                </Text>
                <Text size="sm">
                  {formatMoney(invoice.paidAmount, invoice.currency)}
                </Text>
              </Stack>
              <Stack gap={2} align="flex-end">
                <Text size="xs" fw={700}>
                  Total
                </Text>
                <Text size="sm" fw={700}>
                  {formatMoney(invoice.totalAmount, invoice.currency)}
                </Text>
              </Stack>
            </Group>
          </Stack>
        </Card>
      </Stack>
    </PageContainer>
  );
}
