import { createFileRoute } from "@tanstack/react-router";
import { useEffect, useMemo, useRef, useState } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import { Loader2, Plus, Printer, Trash2, UserPlus, RefreshCw } from "lucide-react";
import { toast } from "sonner";
import { supabase } from "@/integrations/supabase/client";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
  financeAccess,
  financeOverview,
  addTransaction,
  deleteTransaction,
  createReceipt,
  addFinanceUser,
  removeFinanceUser,
  listFinanceUserEmails,
  type ReceiptRow,
  type ReceiptItem,
} from "@/lib/finance.functions";
import signature from "@/assets/administrator-signature.png.asset.json";
import gazmanLogo from "@/assets/gazman-logo.png.asset.json";

export const Route = createFileRoute("/finance")({
  head: () => ({
    meta: [
      { title: "Finance Module — Gatavase Corporation" },
      {
        name: "description",
        content:
          "Secure finance workspace for Gazman Advanced Technologies: money in, money out, balances, receipts and audit trail.",
      },
      { name: "robots", content: "noindex, nofollow" },
      { property: "og:title", content: "Finance Module — Gatavase Corporation" },
      { property: "og:description", content: "Internal finance workspace." },
      { property: "og:type", content: "website" },
      { name: "twitter:card", content: "summary" },
    ],
  }),
  component: FinancePage,
});

const COMPANY = {
  name: "Gazman Advanced Technologies Ltd",
  address: "Namasuba, Entebbe Road, P.O.BOX 203127, Kampala Uganda",
  tel: "Tel: +256762502080, +256773231138",
  email: "Email: info@gatavase.com, sales@gatavase.com",
  website: "Website: www.gatavase.com",
};

function money(amount: number, currency: string) {
  return `${currency} ${amount.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
}

function FinancePage() {
  const [sessionReady, setSessionReady] = useState(false);
  const [signedIn, setSignedIn] = useState(false);

  useEffect(() => {
    const { data: sub } = supabase.auth.onAuthStateChange((_event, session) => {
      setSignedIn(Boolean(session));
    });
    void supabase.auth.getSession().then(({ data }) => {
      setSignedIn(Boolean(data.session));
      setSessionReady(true);
    });
    return () => sub.subscription.unsubscribe();
  }, []);

  if (!sessionReady) {
    return (
      <div className="grid min-h-[60vh] place-items-center">
        <Loader2 className="size-6 animate-spin text-primary" />
      </div>
    );
  }

  return signedIn ? <FinanceWorkspace /> : <FinanceLogin />;
}

function FinanceLogin() {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [busy, setBusy] = useState(false);

  async function onSubmit(e: React.FormEvent) {
    e.preventDefault();
    setBusy(true);
    const { error } = await supabase.auth.signInWithPassword({ email, password });
    setBusy(false);
    if (error) toast.error(error.message);
  }

  return (
    <div className="mx-auto grid min-h-[70vh] max-w-md place-items-center px-5 py-16">
      <form onSubmit={onSubmit} className="panel w-full space-y-4 p-8">
        <div>
          <p className="font-mono text-xs tracking-[0.2em] text-primary uppercase">Finance</p>
          <h1 className="mt-2 text-2xl font-bold">Finance module sign in</h1>
          <p className="mt-2 text-sm text-muted-foreground">
            Restricted to Gazman Advanced Technologies finance administrators.
          </p>
        </div>
        <div className="space-y-2">
          <Label htmlFor="fin-email">Email</Label>
          <Input
            id="fin-email"
            type="email"
            autoComplete="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            required
          />
        </div>
        <div className="space-y-2">
          <Label htmlFor="fin-password">Password</Label>
          <Input
            id="fin-password"
            type="password"
            autoComplete="current-password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            required
          />
        </div>
        <Button type="submit" className="w-full" disabled={busy}>
          {busy ? <Loader2 className="size-4 animate-spin" /> : null} Sign in
        </Button>
      </form>
    </div>
  );
}

function FinanceWorkspace() {
  const qc = useQueryClient();
  const checkAccess = useServerFn(financeAccess);
  const fetchOverview = useServerFn(financeOverview);
  const fetchMembers = useServerFn(listFinanceUserEmails);
  const [receipt, setReceipt] = useState<ReceiptRow | null>(null);

  const accessQuery = useQuery({ queryKey: ["finance-access"], queryFn: () => checkAccess({}) });
  const canAccess = accessQuery.data?.canAccess === true;
  const isAdmin = accessQuery.data?.isAdmin === true;

  const overviewQuery = useQuery({
    queryKey: ["finance-overview"],
    queryFn: () => fetchOverview({}),
    enabled: canAccess,
  });
  const membersQuery = useQuery({
    queryKey: ["finance-members"],
    queryFn: () => fetchMembers({}),
    enabled: canAccess,
  });

  const refresh = () => {
    void qc.invalidateQueries({ queryKey: ["finance-overview"] });
    void qc.invalidateQueries({ queryKey: ["finance-members"] });
  };

  if (accessQuery.isLoading) {
    return (
      <div className="grid min-h-[60vh] place-items-center">
        <Loader2 className="size-6 animate-spin text-primary" />
      </div>
    );
  }

  if (!canAccess) {
    return (
      <div className="mx-auto max-w-lg px-5 py-28 text-center">
        <h1 className="text-2xl font-bold">Finance access required</h1>
        <p className="mt-3 text-muted-foreground">
          {accessQuery.data?.email ?? "This account"} is not a member of the finance team.
        </p>
        <Button
          variant="outline"
          className="mt-6"
          onClick={() => supabase.auth.signOut()}
        >
          Sign out
        </Button>
      </div>
    );
  }

  const data = overviewQuery.data;

  return (
    <div className="mx-auto max-w-6xl px-5 py-16">
      <div className="flex flex-wrap items-end justify-between gap-4">
        <div>
          <p className="font-mono text-xs tracking-[0.2em] text-primary uppercase">Finance</p>
          <h1 className="mt-2 text-3xl font-bold">Finance module</h1>
          <p className="mt-2 text-sm text-muted-foreground">
            Signed in as {accessQuery.data?.email}. Money in, money out, balance, receipts and audit.
          </p>
        </div>
        <div className="flex gap-2">
          <Button variant="outline" size="sm" onClick={refresh}>
            <RefreshCw className="size-4" /> Refresh
          </Button>
          <Button variant="outline" size="sm" onClick={() => supabase.auth.signOut()}>
            Sign out
          </Button>
        </div>
      </div>

      <div className="mt-8 grid gap-4 sm:grid-cols-3">
        <Stat label="Money in" value={money(data?.totals.moneyIn ?? 0, "UGX")} />
        <Stat label="Money out" value={money(data?.totals.moneyOut ?? 0, "UGX")} />
        <Stat label="Balance" value={money(data?.totals.balance ?? 0, "UGX")} />
      </div>

      <Tabs defaultValue="transactions" className="mt-10">
        <TabsList>
          <TabsTrigger value="transactions">Transactions</TabsTrigger>
          <TabsTrigger value="receipts">Receipts</TabsTrigger>
          <TabsTrigger value="audit">Audit</TabsTrigger>
          <TabsTrigger value="team">Team</TabsTrigger>
        </TabsList>

        <TabsContent value="transactions" className="mt-6 space-y-6">
          <TransactionForm onDone={refresh} />
          <div className="panel overflow-x-auto p-6">
            <h2 className="text-lg font-semibold">Recent transactions</h2>
            {overviewQuery.isLoading ? (
              <Loader2 className="mt-6 size-5 animate-spin text-primary" />
            ) : (
              <table className="mt-4 w-full text-left text-sm">
                <thead className="text-xs text-muted-foreground uppercase">
                  <tr>
                    <th className="py-2 pr-4">Date</th>
                    <th className="py-2 pr-4">Type</th>
                    <th className="py-2 pr-4">Description</th>
                    <th className="py-2 pr-4">Category</th>
                    <th className="py-2 pr-4 text-right">Amount</th>
                    {isAdmin ? <th className="py-2" /> : null}
                  </tr>
                </thead>
                <tbody>
                  {(data?.transactions ?? []).map((t) => (
                    <tr key={t.id} className="border-t border-border">
                      <td className="py-2 pr-4 whitespace-nowrap">{t.occurred_on}</td>
                      <td className="py-2 pr-4">
                        <span
                          className={
                            t.direction === "in" ? "text-primary" : "text-muted-foreground"
                          }
                        >
                          {t.direction === "in" ? "Money in" : "Money out"}
                        </span>
                      </td>
                      <td className="py-2 pr-4">{t.description}</td>
                      <td className="py-2 pr-4">{t.category}</td>
                      <td className="py-2 pr-4 text-right font-mono">
                        {t.direction === "out" ? "-" : "+"}
                        {money(t.amount, t.currency)}
                      </td>
                      {isAdmin ? (
                        <td className="py-2 text-right">
                          <DeleteTransactionButton id={t.id} onDone={refresh} />
                        </td>
                      ) : null}
                    </tr>
                  ))}
                  {data && data.transactions.length === 0 ? (
                    <tr>
                      <td colSpan={6} className="py-4 text-muted-foreground">
                        No transactions recorded yet.
                      </td>
                    </tr>
                  ) : null}
                </tbody>
              </table>
            )}
          </div>
        </TabsContent>

        <TabsContent value="receipts" className="mt-6 space-y-6">
          <ReceiptForm
            onCreated={(r) => {
              setReceipt(r);
              refresh();
            }}
          />
          <div className="panel overflow-x-auto p-6">
            <h2 className="text-lg font-semibold">Issued receipts</h2>
            <table className="mt-4 w-full text-left text-sm">
              <thead className="text-xs text-muted-foreground uppercase">
                <tr>
                  <th className="py-2 pr-4">Receipt</th>
                  <th className="py-2 pr-4">Issued to</th>
                  <th className="py-2 pr-4">Date</th>
                  <th className="py-2 pr-4 text-right">Amount</th>
                  <th className="py-2" />
                </tr>
              </thead>
              <tbody>
                {(data?.receipts ?? []).map((r) => (
                  <tr key={r.id} className="border-t border-border">
                    <td className="py-2 pr-4 font-mono">{r.receipt_no}</td>
                    <td className="py-2 pr-4">{r.issued_to}</td>
                    <td className="py-2 pr-4">{r.issued_on}</td>
                    <td className="py-2 pr-4 text-right font-mono">
                      {money(r.amount, r.currency)}
                    </td>
                    <td className="py-2 text-right">
                      <Button variant="outline" size="sm" onClick={() => setReceipt(r)}>
                        <Printer className="size-4" /> View
                      </Button>
                    </td>
                  </tr>
                ))}
                {data && data.receipts.length === 0 ? (
                  <tr>
                    <td colSpan={5} className="py-4 text-muted-foreground">
                      No receipts issued yet.
                    </td>
                  </tr>
                ) : null}
              </tbody>
            </table>
          </div>
        </TabsContent>

        <TabsContent value="audit" className="mt-6">
          <div className="panel overflow-x-auto p-6">
            <h2 className="text-lg font-semibold">Audit trail</h2>
            <p className="mt-1 text-sm text-muted-foreground">
              Every finance action is recorded and cannot be edited or deleted.
            </p>
            <table className="mt-4 w-full text-left text-sm">
              <thead className="text-xs text-muted-foreground uppercase">
                <tr>
                  <th className="py-2 pr-4">When</th>
                  <th className="py-2 pr-4">Who</th>
                  <th className="py-2 pr-4">Action</th>
                  <th className="py-2 pr-4">Entity</th>
                  <th className="py-2">Details</th>
                </tr>
              </thead>
              <tbody>
                {(data?.audit ?? []).map((a) => (
                  <tr key={a.id} className="border-t border-border">
                    <td className="py-2 pr-4 whitespace-nowrap">
                      {new Date(a.created_at).toLocaleString()}
                    </td>
                    <td className="py-2 pr-4 break-all">{a.actor_email ?? "—"}</td>
                    <td className="py-2 pr-4">{a.action}</td>
                    <td className="py-2 pr-4">{a.entity}</td>
                    <td className="py-2 font-mono text-xs break-all">
                      {JSON.stringify(a.details)}
                    </td>
                  </tr>
                ))}
                {data && data.audit.length === 0 ? (
                  <tr>
                    <td colSpan={5} className="py-4 text-muted-foreground">
                      No audit entries yet.
                    </td>
                  </tr>
                ) : null}
              </tbody>
            </table>
          </div>
        </TabsContent>

        <TabsContent value="team" className="mt-6 space-y-6">
          {isAdmin ? <FinanceUserForm onDone={refresh} /> : null}
          <div className="panel p-6">
            <h2 className="text-lg font-semibold">Finance team</h2>
            <ul className="mt-4 space-y-3">
              {(membersQuery.data ?? []).map((m) => (
                <li
                  key={m.userId}
                  className="flex items-center justify-between gap-4 border-t border-border pt-3 text-sm first:border-0 first:pt-0"
                >
                  <div>
                    <p className="break-all">{m.email}</p>
                    <p className="text-xs text-muted-foreground">{m.roles.join(", ")}</p>
                  </div>
                  {isAdmin ? <RemoveMemberButton userId={m.userId} onDone={refresh} /> : null}
                </li>
              ))}
              {membersQuery.data && membersQuery.data.length === 0 ? (
                <li className="text-sm text-muted-foreground">No finance users yet.</li>
              ) : null}
            </ul>
          </div>
        </TabsContent>
      </Tabs>

      {receipt ? <ReceiptView receipt={receipt} onClose={() => setReceipt(null)} /> : null}
    </div>
  );
}

function Stat({ label, value }: { label: string; value: string }) {
  return (
    <div className="panel p-5">
      <p className="text-xs tracking-wide text-muted-foreground uppercase">{label}</p>
      <p className="mt-2 text-2xl font-bold">{value}</p>
    </div>
  );
}

function DeleteTransactionButton({ id, onDone }: { id: string; onDone: () => void }) {
  const remove = useServerFn(deleteTransaction);
  const [busy, setBusy] = useState(false);
  return (
    <Button
      variant="ghost"
      size="icon-sm"
      aria-label="Delete transaction"
      disabled={busy}
      onClick={async () => {
        setBusy(true);
        try {
          await remove({ data: { id } });
          toast.success("Transaction deleted");
          onDone();
        } catch (error) {
          toast.error(error instanceof Error ? error.message : "Delete failed");
        } finally {
          setBusy(false);
        }
      }}
    >
      <Trash2 className="size-4" />
    </Button>
  );
}

function RemoveMemberButton({ userId, onDone }: { userId: string; onDone: () => void }) {
  const remove = useServerFn(removeFinanceUser);
  return (
    <Button
      variant="outline"
      size="sm"
      onClick={async () => {
        try {
          await remove({ data: { userId } });
          toast.success("Finance access removed");
          onDone();
        } catch (error) {
          toast.error(error instanceof Error ? error.message : "Could not remove access");
        }
      }}
    >
      Remove
    </Button>
  );
}

function TransactionForm({ onDone }: { onDone: () => void }) {
  const add = useServerFn(addTransaction);
  const [busy, setBusy] = useState(false);
  const [direction, setDirection] = useState<"in" | "out">("in");
  const formRef = useRef<HTMLFormElement>(null);

  async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const form = new FormData(e.currentTarget);
    setBusy(true);
    try {
      await add({
        data: {
          direction,
          amount: Number(form.get("amount")),
          currency: String(form.get("currency") || "UGX"),
          category: String(form.get("category") || "general"),
          description: String(form.get("description") || ""),
          counterparty: String(form.get("counterparty") || "") || undefined,
          method: String(form.get("method") || "cash"),
          reference: String(form.get("reference") || "") || undefined,
          occurred_on: String(form.get("occurred_on") || new Date().toISOString().slice(0, 10)),
        },
      });
      toast.success("Transaction recorded");
      formRef.current?.reset();
      onDone();
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Could not record transaction");
    } finally {
      setBusy(false);
    }
  }

  return (
    <form ref={formRef} onSubmit={onSubmit} className="panel space-y-4 p-6">
      <h2 className="text-lg font-semibold">Record money in / money out</h2>
      <div className="flex gap-2">
        <Button
          type="button"
          size="sm"
          variant={direction === "in" ? "default" : "outline"}
          onClick={() => setDirection("in")}
        >
          Money in
        </Button>
        <Button
          type="button"
          size="sm"
          variant={direction === "out" ? "default" : "outline"}
          onClick={() => setDirection("out")}
        >
          Money out
        </Button>
      </div>
      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
        <Field label="Amount" name="amount" type="number" step="0.01" min="0.01" required />
        <Field label="Currency" name="currency" defaultValue="UGX" />
        <Field
          label="Date"
          name="occurred_on"
          type="date"
          defaultValue={new Date().toISOString().slice(0, 10)}
        />
        <Field label="Category" name="category" defaultValue="general" />
        <Field label="Method" name="method" defaultValue="cash" />
        <Field label="Reference" name="reference" />
        <Field label="Payer / payee" name="counterparty" />
        <div className="sm:col-span-2">
          <Field label="Description" name="description" required />
        </div>
      </div>
      <Button type="submit" disabled={busy}>
        {busy ? <Loader2 className="size-4 animate-spin" /> : <Plus className="size-4" />} Save entry
      </Button>
    </form>
  );
}

function Field({
  label,
  name,
  ...rest
}: { label: string; name: string } & React.InputHTMLAttributes<HTMLInputElement>) {
  return (
    <div className="space-y-2">
      <Label htmlFor={`fin-${name}`}>{label}</Label>
      <Input id={`fin-${name}`} name={name} {...rest} />
    </div>
  );
}

function ReceiptForm({ onCreated }: { onCreated: (receipt: ReceiptRow) => void }) {
  const create = useServerFn(createReceipt);
  const [busy, setBusy] = useState(false);
  const [items, setItems] = useState<ReceiptItem[]>([
    { description: "", quantity: 1, unitPrice: 0 },
  ]);
  const [issuedTo, setIssuedTo] = useState("");
  const [email, setEmail] = useState("");
  const [currency, setCurrency] = useState("UGX");
  const [method, setMethod] = useState("cash");
  const [notes, setNotes] = useState("");

  const total = useMemo(
    () => items.reduce((s, i) => s + (Number(i.quantity) || 0) * (Number(i.unitPrice) || 0), 0),
    [items],
  );

  function update(index: number, patch: Partial<ReceiptItem>) {
    setItems((prev) => prev.map((item, i) => (i === index ? { ...item, ...patch } : item)));
  }

  async function onSubmit(e: React.FormEvent) {
    e.preventDefault();
    setBusy(true);
    try {
      const receipt = await create({
        data: {
          issued_to: issuedTo,
          issued_to_email: email || undefined,
          items: items.map((i) => ({
            description: i.description,
            quantity: Number(i.quantity),
            unitPrice: Number(i.unitPrice),
          })),
          currency,
          method,
          notes: notes || undefined,
          recordAsIncome: true,
        },
      });
      toast.success(`Receipt ${receipt.receipt_no} generated`);
      setItems([{ description: "", quantity: 1, unitPrice: 0 }]);
      setIssuedTo("");
      setEmail("");
      setNotes("");
      onCreated(receipt);
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Could not generate receipt");
    } finally {
      setBusy(false);
    }
  }

  return (
    <form onSubmit={onSubmit} className="panel space-y-4 p-6">
      <h2 className="text-lg font-semibold">Generate a receipt</h2>
      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        <div className="space-y-2">
          <Label htmlFor="rc-to">Issued to</Label>
          <Input id="rc-to" value={issuedTo} onChange={(e) => setIssuedTo(e.target.value)} required />
        </div>
        <div className="space-y-2">
          <Label htmlFor="rc-email">Client email</Label>
          <Input id="rc-email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} />
        </div>
        <div className="space-y-2">
          <Label htmlFor="rc-currency">Currency</Label>
          <Input id="rc-currency" value={currency} onChange={(e) => setCurrency(e.target.value)} />
        </div>
        <div className="space-y-2">
          <Label htmlFor="rc-method">Payment method</Label>
          <Input id="rc-method" value={method} onChange={(e) => setMethod(e.target.value)} />
        </div>
      </div>

      <div className="space-y-3">
        {items.map((item, index) => (
          <div key={index} className="grid gap-3 sm:grid-cols-[1fr_100px_140px_auto]">
            <Input
              placeholder="Description"
              value={item.description}
              onChange={(e) => update(index, { description: e.target.value })}
              required
            />
            <Input
              type="number"
              min="1"
              placeholder="Qty"
              value={item.quantity}
              onChange={(e) => update(index, { quantity: Number(e.target.value) })}
            />
            <Input
              type="number"
              min="0"
              step="0.01"
              placeholder="Unit price"
              value={item.unitPrice}
              onChange={(e) => update(index, { unitPrice: Number(e.target.value) })}
            />
            <Button
              type="button"
              variant="ghost"
              size="icon"
              aria-label="Remove line"
              onClick={() => setItems((prev) => prev.filter((_, i) => i !== index))}
              disabled={items.length === 1}
            >
              <Trash2 className="size-4" />
            </Button>
          </div>
        ))}
        <Button
          type="button"
          variant="outline"
          size="sm"
          onClick={() => setItems((prev) => [...prev, { description: "", quantity: 1, unitPrice: 0 }])}
        >
          <Plus className="size-4" /> Add line
        </Button>
      </div>

      <div className="space-y-2">
        <Label htmlFor="rc-notes">Notes</Label>
        <Textarea id="rc-notes" value={notes} onChange={(e) => setNotes(e.target.value)} rows={2} />
      </div>

      <div className="flex flex-wrap items-center justify-between gap-4">
        <p className="text-sm text-muted-foreground">
          Total: <span className="font-mono text-foreground">{money(total, currency)}</span>
        </p>
        <Button type="submit" disabled={busy}>
          {busy ? <Loader2 className="size-4 animate-spin" /> : <Printer className="size-4" />}{" "}
          Generate receipt
        </Button>
      </div>
    </form>
  );
}

function FinanceUserForm({ onDone }: { onDone: () => void }) {
  const add = useServerFn(addFinanceUser);
  const [busy, setBusy] = useState(false);
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [makeAdmin, setMakeAdmin] = useState(false);

  return (
    <form
      className="panel space-y-4 p-6"
      onSubmit={async (e) => {
        e.preventDefault();
        setBusy(true);
        try {
          await add({ data: { email, password, makeAdmin } });
          toast.success("Finance user added");
          setEmail("");
          setPassword("");
          onDone();
        } catch (error) {
          toast.error(error instanceof Error ? error.message : "Could not add user");
        } finally {
          setBusy(false);
        }
      }}
    >
      <h2 className="text-lg font-semibold">Add a finance user</h2>
      <div className="grid gap-4 sm:grid-cols-2">
        <div className="space-y-2">
          <Label htmlFor="fu-email">Email</Label>
          <Input
            id="fu-email"
            type="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            required
          />
        </div>
        <div className="space-y-2">
          <Label htmlFor="fu-password">Temporary password</Label>
          <Input
            id="fu-password"
            type="text"
            minLength={10}
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            required
          />
        </div>
      </div>
      <label className="flex items-center gap-2 text-sm">
        <input
          type="checkbox"
          checked={makeAdmin}
          onChange={(e) => setMakeAdmin(e.target.checked)}
        />
        Also grant full admin rights
      </label>
      <Button type="submit" disabled={busy}>
        {busy ? <Loader2 className="size-4 animate-spin" /> : <UserPlus className="size-4" />} Add
        user
      </Button>
    </form>
  );
}

function ReceiptView({ receipt, onClose }: { receipt: ReceiptRow; onClose: () => void }) {
  return (
    <div className="fixed inset-0 z-50 grid place-items-start overflow-y-auto bg-black/70 p-4 print:static print:bg-transparent print:p-0">
      <div className="mx-auto w-full max-w-2xl rounded-lg bg-white p-8 text-black shadow-2xl print:max-w-none print:shadow-none">
        <header className="flex items-start gap-4 border-b-2 border-black pb-4">
          <img src={gazmanLogo.url} alt="" width={72} height={72} className="size-18 object-contain" />
          <div className="text-sm leading-snug">
            <p className="text-lg font-bold">{COMPANY.name}</p>
            <p>{COMPANY.address}</p>
            <p>{COMPANY.tel}</p>
            <p>{COMPANY.email}</p>
            <p>{COMPANY.website}</p>
          </div>
        </header>

        <div className="mt-6 flex flex-wrap justify-between gap-4 text-sm">
          <div>
            <p className="text-xs uppercase">Receipt no.</p>
            <p className="font-mono font-semibold">{receipt.receipt_no}</p>
          </div>
          <div>
            <p className="text-xs uppercase">Date</p>
            <p className="font-semibold">{receipt.issued_on}</p>
          </div>
          <div>
            <p className="text-xs uppercase">Received from</p>
            <p className="font-semibold">{receipt.issued_to}</p>
          </div>
          <div>
            <p className="text-xs uppercase">Method</p>
            <p className="font-semibold">{receipt.method}</p>
          </div>
        </div>

        <table className="mt-6 w-full border-collapse text-sm">
          <thead>
            <tr className="border-y border-black text-left">
              <th className="py-2">Description</th>
              <th className="py-2 text-right">Qty</th>
              <th className="py-2 text-right">Unit price</th>
              <th className="py-2 text-right">Amount</th>
            </tr>
          </thead>
          <tbody>
            {receipt.items.map((item, i) => (
              <tr key={i} className="border-b border-neutral-300">
                <td className="py-2">{item.description}</td>
                <td className="py-2 text-right">{item.quantity}</td>
                <td className="py-2 text-right">{money(item.unitPrice, receipt.currency)}</td>
                <td className="py-2 text-right">
                  {money(item.quantity * item.unitPrice, receipt.currency)}
                </td>
              </tr>
            ))}
            <tr>
              <td colSpan={3} className="py-3 text-right font-semibold">
                Total
              </td>
              <td className="py-3 text-right font-bold">
                {money(receipt.amount, receipt.currency)}
              </td>
            </tr>
          </tbody>
        </table>

        {receipt.notes ? <p className="mt-4 text-sm">Notes: {receipt.notes}</p> : null}

        <div className="mt-10 flex items-end justify-between">
          <div>
            <img src={signature.url} alt="Authorised signature" width={180} height={70} />
            <p className="mt-1 border-t border-black pt-1 text-sm font-semibold">
              Authorised signature
            </p>
            <p className="text-xs">For {COMPANY.name}</p>
          </div>
          <p className="text-xs">Thank you for your business.</p>
        </div>

        <div className="mt-8 flex justify-end gap-2 print:hidden">
          <Button variant="outline" onClick={onClose}>
            Close
          </Button>
          <Button onClick={() => window.print()}>
            <Printer className="size-4" /> Print / save PDF
          </Button>
        </div>
      </div>
    </div>
  );
}
