import { redirect } from "next/navigation";

import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { listApprovedConnections } from "@/lib/appwrite/connection-queries";
import { listFinanceEntries, summarizeFinance } from "@/lib/appwrite/finance-queries";
import {
  computeBalancesByCounterpart,
  filterPendingForConfirmation,
  listIncomingPayments,
  listPayments,
} from "@/lib/appwrite/payment-queries";
import { requireTenant } from "@/lib/appwrite/tenant-guard";
import { BalancesCard } from "./components/balances-card";
import { FinanceTable } from "./components/finance-table";
import { MyPendingPaymentsCard } from "./components/my-pending-payments-card";
import { PendingPaymentsCard } from "./components/pending-payments-card";

export const metadata = {
  title: "DLS — Finans",
};

function formatMoney(amount: number, currency: string): string {
  try {
    return new Intl.NumberFormat("tr-TR", { style: "currency", currency }).format(amount);
  } catch {
    return `${amount.toFixed(2)} ${currency}`;
  }
}

export default async function FinancePage() {
  let ctx;
  try {
    ctx = await requireTenant();
  } catch {
    redirect("/onboarding");
  }
  if (!ctx.kind) redirect("/onboarding");
  const kind = ctx.kind;

  const [entries, ownPayments, incomingPayments, connections] = await Promise.all([
    listFinanceEntries(ctx.tenantId),
    listPayments(ctx.tenantId),
    listIncomingPayments(ctx.tenantId),
    listApprovedConnections(ctx.tenantId),
  ]);

  // Same physical payment can show up in both lists for the same tenant in
  // pathological cases; dedupe by $id to be safe.
  const seenIds = new Set<string>();
  const payments = [...ownPayments, ...incomingPayments].filter((p) =>
    seenIds.has(p.$id) ? false : (seenIds.add(p.$id), true),
  );

  const stats = summarizeFinance(entries);
  const isLab = kind === "lab";
  const defaultCurrency = ctx.settings?.defaultCurrency ?? "TRY";

  const balances = computeBalancesByCounterpart({
    kind,
    selfTenantId: ctx.tenantId,
    entries,
    payments,
  });
  const pendingForApproval = filterPendingForConfirmation(payments, ctx.tenantId, kind);
  // Clinic-side: payments this clinic submitted that are either still waiting
  // for the lab to confirm, or were rejected. Both shapes are useful so the
  // clinic can chase the lab or fix a wrong submission.
  const myPendingOrRejected = payments
    .filter(
      (p) =>
        p.tenantId === ctx.tenantId &&
        (p.status === "pending" || p.status === "rejected"),
    )
    .sort((a, b) => (a.paymentDate < b.paymentDate ? 1 : -1));

  const counterpartNames: Record<string, string> = {};
  for (const c of connections) {
    const id = isLab ? c.clinicTenantId : c.labTenantId;
    counterpartNames[id] = c.counterpart?.companyName ?? "—";
  }

  const totalPaid = payments.reduce((sum, p) => {
    if (p.status && p.status !== "confirmed") return sum;
    const ownInflow = p.tenantId === ctx.tenantId && p.direction === (isLab ? "inflow" : "outflow");
    const incoming =
      p.counterpartTenantId === ctx.tenantId &&
      p.direction === (isLab ? "outflow" : "inflow");
    return sum + (ownInflow || incoming ? p.amount : 0);
  }, 0);
  const totalOpen = balances.reduce(
    (sum, b) => sum + (b.open > 0 ? b.open : 0),
    0,
  );

  return (
    <div className="flex-1 space-y-6 px-6">
      <div className="flex flex-col gap-1">
        <h1 className="text-2xl font-bold tracking-tight">Finans</h1>
        <p className="text-muted-foreground text-sm">
          {isLab
            ? "Klinik bazlı açık bakiye ve toplu tahsilat."
            : "Laboratuvar bazlı borç ve ödeme akışı."}
        </p>
      </div>

      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        <StatCard
          label={isLab ? "Toplam Açık Alacak" : "Toplam Açık Borç"}
          value={formatMoney(totalOpen, defaultCurrency)}
          tone={isLab ? "positive" : "negative"}
        />
        <StatCard
          label={isLab ? "Tahsil Edilen" : "Ödenen"}
          value={formatMoney(totalPaid, defaultCurrency)}
          tone="neutral"
        />
        <StatCard
          label="Bu Ay Gelir"
          value={formatMoney(stats.incomeThisMonth, stats.currency)}
          tone="positive"
        />
        <StatCard
          label="Bu Ay Gider"
          value={formatMoney(stats.expenseThisMonth, stats.currency)}
          tone="negative"
        />
      </div>

      <PendingPaymentsCard rows={pendingForApproval} counterpartNames={counterpartNames} />

      {!isLab && (
        <MyPendingPaymentsCard
          rows={myPendingOrRejected}
          counterpartNames={counterpartNames}
        />
      )}

      <BalancesCard
        balances={balances}
        counterpartNames={counterpartNames}
        selfKind={kind}
        defaultCurrency={defaultCurrency}
      />

      <Card>
        <CardHeader>
          <CardTitle>Hareketler</CardTitle>
          <CardDescription>
            Tamamlanan işlerden otomatik oluşturulan finansal kayıtlar.
          </CardDescription>
        </CardHeader>
        <CardContent>
          <FinanceTable rows={entries} />
        </CardContent>
      </Card>
    </div>
  );
}

function StatCard({
  label,
  value,
  tone,
}: {
  label: string;
  value: string;
  tone: "positive" | "negative" | "neutral";
}) {
  const color =
    tone === "positive"
      ? "text-emerald-600 dark:text-emerald-400"
      : tone === "negative"
        ? "text-rose-600 dark:text-rose-400"
        : "text-foreground";
  return (
    <Card>
      <CardHeader className="pb-2">
        <CardDescription className="text-xs uppercase tracking-wide">
          {label}
        </CardDescription>
      </CardHeader>
      <CardContent>
        <p className={`text-2xl font-semibold tabular-nums ${color}`}>{value}</p>
      </CardContent>
    </Card>
  );
}
