import { redirect } from "next/navigation";
import { inArray } from "drizzle-orm";
import { db } from "@db/client";
import { users, payoutAccounts } from "@db/schema";
import { getCurrentRole } from "@/lib/auth";
import { formatPrice } from "@/lib/format";
import { getPlatformSettlements } from "@db/queries/payouts";
import { getPayoutRates } from "@db/queries/settings";
import { Wallet, ShoppingBag, Users as UsersIcon, TrendingUp, Coins, Smartphone, Landmark } from "lucide-react";
import { PageHeader, StatCard, TableShell, StatusPill, EmptyState } from "@/components/ui";

export const metadata = { title: "Earnings · Admin" };

// Admin-only: the full deduction breakdown per organizer. Organizers only
// ever see their ticket sales and payout (db/queries/settlement.ts).
export default async function AdminEarningsPage() {
  const { isAdmin } = await getCurrentRole();
  if (!isAdmin) redirect("/dashboard");

  const [settlements, rates] = await Promise.all([getPlatformSettlements(), getPayoutRates()]);
  const earnings = settlements.filter((s) => s.gross_cents > 0 || s.deductions_cents > 0);

  const ids = earnings.map((e) => e.organizer_id);
  const [profiles, accounts] = ids.length
    ? await Promise.all([
        db.select({ id: users.id, name: users.name, email: users.email }).from(users).where(inArray(users.id, ids)),
        db.select({ organizerId: payoutAccounts.organizerId, type: payoutAccounts.type, verified: payoutAccounts.verified }).from(payoutAccounts).where(inArray(payoutAccounts.organizerId, ids)),
      ])
    : [[], []];

  const nameById = new Map(profiles.map((p) => [p.id, p.name?.trim() || p.email]));
  const acctById = new Map(accounts.map((a) => [a.organizerId, a]));

  const currency = earnings[0]?.currency ?? "kes";
  const sum = (k: "gross_cents" | "deductions_cents" | "net_cents" | "merch_gross_cents" | "merch_orders") => earnings.reduce((s, e) => s + e[k], 0);
  const money = (c: number, cur = currency) => formatPrice(c, cur);

  return (
    <div className="space-y-8">
      <PageHeader
        icon={Wallet}
        title="Earnings"
        description="What each organizer is owed, and what VibePass deducts. Only admins see this breakdown."
      />

      <section className="grid grid-cols-2 gap-3 sm:grid-cols-5">
        <StatCard icon={UsersIcon} label="Organizers earning" value={earnings.length.toString()} />
        <StatCard icon={TrendingUp} label="Gross sales" value={money(sum("gross_cents"))} />
        <StatCard
          icon={ShoppingBag}
          label="of which merch"
          value={money(sum("merch_gross_cents"))}
          hint={`${sum("merch_orders")} order${sum("merch_orders") === 1 ? "" : "s"}`}
        />
        <StatCard icon={Coins} label="Deductions (VibePass)" value={money(sum("deductions_cents"))} accent="gold" />
        <StatCard icon={Wallet} label="Owed to organizers" value={money(sum("net_cents"))} />
      </section>

      <p className="text-xs text-be-muted">
        Deductions: each event&apos;s commission (default 4%) + {rates.commission_tax_pct}% tax on it (merch sales are charged the organizer&apos;s latest event rate, with the same tax) · KES{" "}
        {rates.email_kes}/email and KES {rates.sms_kes}/SMS sent for an event (ticket confirmations, resends, change
        notices) · campaigns KES {rates.campaign_sms_kes}/SMS, KES {rates.campaign_email_kes}/email. Change the rates in
        Settings.
      </p>

      <section>
        {earnings.length === 0 ? (
          <EmptyState icon={Wallet} title="No paid orders yet" body="Organizer earnings appear once orders are paid." />
        ) : (
          <TableShell>
            <thead>
              <tr>
                <th>Organizer</th>
                <th>Payout</th>
                <th className="text-right">Orders</th>
                <th className="text-right">Gross</th>
                <th className="text-right">Merch</th>
                <th className="text-right">Commission</th>
                <th className="text-right">Tax</th>
                <th className="text-right">Emails / SMS</th>
                <th className="text-right">Campaigns</th>
                <th className="text-right">Net owed</th>
              </tr>
            </thead>
            <tbody>
              {earnings.map((e) => {
                const acct = acctById.get(e.organizer_id);
                const cur = e.currency ?? currency;
                return (
                  <tr key={e.organizer_id}>
                    <td className="font-medium text-be-text">
                      {nameById.get(e.organizer_id) || <span className="text-be-muted opacity-70">Unnamed</span>}
                    </td>
                    <td>
                      {acct ? (
                        <span className="inline-flex items-center gap-2 text-be-text">
                          <span className="inline-flex items-center gap-1">
                            {acct.type === "mpesa" ? (
                              <Smartphone className="h-3.5 w-3.5 text-be-muted" />
                            ) : (
                              <Landmark className="h-3.5 w-3.5 text-be-muted" />
                            )}
                            {acct.type === "mpesa" ? "M-Pesa" : "Bank"}
                          </span>
                          <StatusPill tone={acct.verified ? "ok" : "warn"}>{acct.verified ? "Verified" : "Pending"}</StatusPill>
                        </span>
                      ) : (
                        <span className="text-xs text-be-muted opacity-70">Not set up</span>
                      )}
                    </td>
                    <td className="text-right tabular-nums text-be-text">{e.paid_orders}</td>
                    <td className="text-right tabular-nums text-be-text">{money(e.gross_cents, cur)}</td>
                    <td className="text-right tabular-nums text-be-muted">
                      {e.merch_orders > 0 ? (
                        <>
                          {money(e.merch_gross_cents, cur)}
                          <span className="block text-xs opacity-70">
                            {e.merch_orders} order{e.merch_orders === 1 ? "" : "s"}
                          </span>
                        </>
                      ) : (
                        "—"
                      )}
                    </td>
                    <td className="text-right tabular-nums text-be-muted">{money(e.commission_cents, cur)}</td>
                    <td className="text-right tabular-nums text-be-muted">{money(e.commission_tax_cents, cur)}</td>
                    <td className="text-right tabular-nums text-be-muted" title={`${e.emails} emails, ${e.sms} SMS`}>
                      {money(e.messaging_cents, cur)}
                      <span className="block text-xs opacity-70">
                        {e.emails} email · {e.sms} SMS
                      </span>
                    </td>
                    <td
                      className="text-right tabular-nums text-be-muted"
                      title={`${e.campaign_sms} campaign SMS, ${e.campaign_emails} campaign emails`}
                    >
                      {money(e.campaign_cents, cur)}
                      {(e.campaign_sms > 0 || e.campaign_emails > 0) && (
                        <span className="block text-xs opacity-70">
                          {e.campaign_sms} SMS · {e.campaign_emails} email
                        </span>
                      )}
                    </td>
                    <td
                      className={`text-right font-medium tabular-nums ${e.net_cents < 0 ? "text-[color:var(--pill-danger-fg)]" : "text-be-text"}`}
                    >
                      {money(e.net_cents, cur)}
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </TableShell>
        )}
      </section>

      <p className="text-xs text-be-muted">
        Net owed is lifetime; the Payouts page subtracts what&apos;s already been paid out. A negative net (e.g. a free
        event whose confirmation emails cost more than its sales) means nothing is paid out.
      </p>
    </div>
  );
}
