import React, { useCallback, useEffect, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { apiRequest } from "@/lib/queryClient";
import type { PatientBalanceRow } from "@repo/db/types";
import PatientsBalancesList from "./patients-balances-list";
import ExportReportButton from "./export-button";

type Resp = {
  balances: PatientBalanceRow[];
  totalCount?: number;
  nextCursor?: string | null;
  hasMore?: boolean;
  totalCharges?: number;
  totalCollected?: number;
};

function fmtCurrency(v: number) {
  return new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(v);
}

export default function PatientsNoBalanceReport({
  startDate,
  endDate,
  npiProviderId,
}: {
  startDate: string;
  endDate: string;
  npiProviderId?: number | null;
}) {
  const balancesPerPage = 10;
  const [cursorStack, setCursorStack] = useState<(string | null)[]>([null]);
  const [cursorIndex, setCursorIndex] = useState(0);
  const currentCursor = cursorStack[cursorIndex] ?? null;
  const pageIndex = cursorIndex + 1;

  const { data, isLoading, isError, refetch } = useQuery<Resp, Error>({
    queryKey: [
      "/api/payments-reports/patients-with-zero-balances",
      currentCursor,
      balancesPerPage,
      startDate,
      endDate,
      npiProviderId ?? "all",
    ],
    queryFn: async () => {
      const params = new URLSearchParams();
      params.set("limit", String(balancesPerPage));
      if (currentCursor) params.set("cursor", currentCursor);
      if (startDate) params.set("from", startDate);
      if (endDate) params.set("to", endDate);
      if (npiProviderId) params.set("npiProviderId", String(npiProviderId));
      const res = await apiRequest(
        "GET",
        `/api/payments-reports/patients-with-zero-balances?${params.toString()}`
      );
      if (!res.ok) {
        const body = await res.json().catch(() => ({ message: "Failed to load" }));
        throw new Error(body.message || "Failed to load zero-balance patients");
      }
      return res.json();
    },
    enabled: true,
  });

  const balances = data?.balances ?? [];
  const totalCount = data?.totalCount ?? undefined;
  const nextCursor = data?.nextCursor ?? null;
  const hasMore = data?.hasMore ?? false;
  const totalCharges = data?.totalCharges ?? 0;
  const totalCollected = data?.totalCollected ?? 0;

  useEffect(() => {
    setCursorStack([null]);
    setCursorIndex(0);
    refetch();
  }, [startDate, endDate, npiProviderId]);

  const handleNext = useCallback(() => {
    const isLastKnown = cursorIndex === cursorStack.length - 1;
    if (isLastKnown) {
      if (nextCursor) {
        setCursorStack((s) => [...s, nextCursor]);
        setCursorIndex((i) => i + 1);
      }
    } else {
      setCursorIndex((i) => i + 1);
    }
  }, [cursorIndex, cursorStack.length, nextCursor]);

  const handlePrev = useCallback(() => {
    setCursorIndex((i) => Math.max(0, i - 1));
  }, []);

  const normalized = balances.map((b) => {
    const currentBalance = Number(b.currentBalance ?? 0);
    const totalChargesRow = Number(b.totalCharges ?? 0);
    const totalPayments =
      b.totalPayments != null
        ? Number(b.totalPayments)
        : Number(totalChargesRow - currentBalance);
    return {
      id: b.patientId,
      name: `${b.firstName ?? "Unknown"} ${b.lastName ?? ""}`.trim(),
      currentBalance,
      totalCharges: totalChargesRow,
      totalPayments,
    };
  });

  return (
    <div>
      <div className="mb-4">
        <PatientsBalancesList
          rows={normalized}
          reportType="patients_no_balance"
          loading={isLoading}
          error={isError ? "Failed to load zero-balance patients." : false}
          emptyMessage="No patients with zero balance for the selected date range."
          pageIndex={pageIndex}
          perPage={balancesPerPage}
          total={totalCount}
          onPrev={handlePrev}
          onNext={handleNext}
          hasPrev={cursorIndex > 0}
          hasNext={hasMore}
          headerRight={
            <ExportReportButton
              reportType="patients_no_balance"
              from={startDate}
              to={endDate}
              className="mr-2"
            />
          }
        />
      </div>

      {/* Aggregate summary for the full zero-balance set */}
      {!isLoading && !isError && (totalCount ?? 0) > 0 && (
        <div className="bg-green-50 border border-green-200 rounded-lg px-5 py-3 flex flex-wrap gap-6 text-sm">
          <div>
            <span className="text-gray-500">Total patients paid in full: </span>
            <span className="font-semibold text-green-700">{totalCount}</span>
          </div>
          <div>
            <span className="text-gray-500">Total charges billed: </span>
            <span className="font-semibold text-gray-800">{fmtCurrency(totalCharges)}</span>
          </div>
          <div>
            <span className="text-gray-500">Total collected: </span>
            <span className="font-semibold text-green-700">{fmtCurrency(totalCollected)}</span>
          </div>
        </div>
      )}
    </div>
  );
}
