import React, { useEffect, useRef, useState } from "react";
import { useQuery, useMutation } from "@tanstack/react-query";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Checkbox } from "@/components/ui/checkbox";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { DateInput } from "@/components/ui/dateInput";
import { formatLocalDate, parseLocalDate, formatDateToHumanReadable } from "@/utils/dateUtils";
import { apiRequest, queryClient } from "@/lib/queryClient";
import { useToast } from "@/hooks/use-toast";
import { DollarSign } from "lucide-react";
import { NpiProvider } from "@repo/db/types";

interface EligiblePayment {
  id: number;
  claimNumber: string | null;
  patientName: string;
  serviceDate: string | null;
  mhPaidAmount: number;
  copayment: number;
  collectionAmount: number;
  paymentDate: string;
  isOcr: boolean;
}

interface CommissionBatch {
  id: number;
  providerName: string;
  totalCollection: number;
  commissionAmount: number;
  notes: string | null;
  createdAt: string;
  itemCount: number;
}

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

export default function CommissionSection() {
  const { toast } = useToast();
  const printRef = useRef<HTMLDivElement>(null);

  // Filters
  const [fromDate, setFromDate] = useState<string>(() => {
    const d = new Date();
    d.setMonth(d.getMonth() - 1);
    return d.toISOString().split("T")[0] ?? "";
  });
  const [toDate, setToDate] = useState<string>(
    () => new Date().toISOString().split("T")[0] ?? ""
  );
  const [selectedProviderId, setSelectedProviderId] = useState<number | null>(null);

  // Selection
  const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set());

  // Pay modal
  const [showModal, setShowModal] = useState(false);
  const [commissionAmount, setCommissionAmount] = useState("");
  const [notes, setNotes] = useState("");

  // Providers
  const { data: providers = [] } = useQuery<NpiProvider[]>({
    queryKey: ["/api/npiProviders/"],
    queryFn: async () => {
      const res = await apiRequest("GET", "/api/npiProviders/");
      return res.json();
    },
    staleTime: 60_000,
  });

  // Eligible payments
  const {
    data: payments = [],
    isLoading,
    isError,
  } = useQuery<EligiblePayment[]>({
    queryKey: ["/api/commissions/eligible", selectedProviderId, fromDate, toDate],
    queryFn: async () => {
      const params = new URLSearchParams();
      params.set("npiProviderId", String(selectedProviderId));
      if (fromDate) params.set("from", fromDate);
      if (toDate) params.set("to", toDate);
      const res = await apiRequest("GET", `/api/commissions/eligible?${params}`);
      if (!res.ok) throw new Error("Failed to fetch eligible payments");
      return res.json();
    },
    enabled: !!selectedProviderId,
  });

  // Past batches
  const { data: batches = [] } = useQuery<CommissionBatch[]>({
    queryKey: ["/api/commissions/batches", selectedProviderId],
    queryFn: async () => {
      const params = selectedProviderId
        ? `?npiProviderId=${selectedProviderId}`
        : "";
      const res = await apiRequest("GET", `/api/commissions/batches${params}`);
      if (!res.ok) throw new Error("Failed to fetch batches");
      return res.json();
    },
  });

  // Reset selection when provider/dates change
  useEffect(() => {
    setSelectedIds(new Set());
  }, [selectedProviderId, fromDate, toDate]);

  // Create commission batch mutation
  const createMutation = useMutation({
    mutationFn: async (payload: {
      npiProviderId: number;
      paymentIds: number[];
      totalCollection: number;
      commissionAmount: number;
      notes?: string;
    }) => {
      const res = await apiRequest("POST", "/api/commissions", payload);
      if (!res.ok) {
        const err = await res.json().catch(() => null);
        throw new Error(err?.message ?? "Failed to save commission");
      }
      return res.json();
    },
    onSuccess: () => {
      toast({ title: "Commission saved", description: "Payments have been marked as commissioned." });
      setShowModal(false);
      setSelectedIds(new Set());
      queryClient.invalidateQueries({ queryKey: ["/api/commissions/eligible"] });
      queryClient.invalidateQueries({ queryKey: ["/api/commissions/batches"] });
    },
    onError: (err: any) => {
      toast({ title: "Error", description: err?.message ?? "Failed to save", variant: "destructive" });
    },
  });

  const selectedPayments = payments.filter((p) => selectedIds.has(p.id));
  const totalCollection = selectedPayments.reduce((s, p) => s + p.collectionAmount, 0);

  // Sync commission amount when selection changes
  useEffect(() => {
    setCommissionAmount(totalCollection.toFixed(2));
  }, [totalCollection]);

  const allSelected = payments.length > 0 && selectedIds.size === payments.length;
  const someSelected = selectedIds.size > 0 && !allSelected;

  const toggleAll = () => {
    if (allSelected) {
      setSelectedIds(new Set());
    } else {
      setSelectedIds(new Set(payments.map((p) => p.id)));
    }
  };

  const toggleOne = (id: number) => {
    setSelectedIds((prev) => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      return next;
    });
  };

  const handlePrint = () => {
    const provider = providers.find((p) => p.id === selectedProviderId);
    const win = window.open("", "_blank");
    if (!win) return;
    win.document.write(`
      <html><head><title>Commission Summary</title>
      <style>
        body { font-family: Arial, sans-serif; padding: 24px; font-size: 13px; }
        h1 { font-size: 18px; margin-bottom: 4px; }
        p { margin: 2px 0; color: #555; }
        table { width: 100%; border-collapse: collapse; margin-top: 16px; }
        th { background: #f3f4f6; text-align: left; padding: 8px; border: 1px solid #e5e7eb; }
        td { padding: 8px; border: 1px solid #e5e7eb; }
        .total { font-weight: bold; margin-top: 16px; font-size: 15px; }
        .footer { margin-top: 24px; color: #888; font-size: 11px; }
      </style></head><body>
      <h1>Commission Summary — ${provider?.providerName ?? "Provider"}</h1>
      <p>Date Range: ${fromDate || "—"} to ${toDate || "—"}</p>
      <p>Generated: ${new Date().toLocaleDateString()}</p>
      <table>
        <thead><tr>
          <th>#</th><th>Claim / Source</th><th>Patient</th>
          <th>Service Date</th><th>MH Paid</th><th>Copayment</th><th>Collection</th>
        </tr></thead>
        <tbody>
          ${selectedPayments
            .map(
              (p, i) => `<tr>
              <td>${i + 1}</td>
              <td>${p.claimNumber ?? (p.isOcr ? "PDF Import" : "—")}</td>
              <td>${p.patientName}</td>
              <td>${p.serviceDate ? new Date(p.serviceDate).toLocaleDateString() : "—"}</td>
              <td>${fmt(p.mhPaidAmount)}</td>
              <td>${fmt(p.copayment)}</td>
              <td>${fmt(p.collectionAmount)}</td>
            </tr>`
            )
            .join("")}
        </tbody>
      </table>
      <p class="total">Total Collection: ${fmt(totalCollection)}</p>
      <p class="total">Commission Amount: ${fmt(Number(commissionAmount) || 0)}</p>
      ${notes ? `<p style="margin-top:12px"><b>Notes:</b> ${notes}</p>` : ""}
      <p class="footer">Summit Dental Care — Commission Record</p>
      </body></html>
    `);
    win.document.close();
    win.print();
  };

  const handleSave = () => {
    if (!selectedProviderId || selectedPayments.length === 0) return;
    const amount = Number(commissionAmount);
    if (isNaN(amount) || amount < 0) {
      toast({ title: "Invalid amount", description: "Enter a valid commission amount.", variant: "destructive" });
      return;
    }
    createMutation.mutate({
      npiProviderId: selectedProviderId,
      paymentIds: selectedPayments.map((p) => p.id),
      totalCollection,
      commissionAmount: amount,
      notes: notes.trim() || undefined,
    });
  };

  const fromDateObj = fromDate ? (() => { try { return parseLocalDate(fromDate); } catch { return null; } })() : null;
  const toDateObj = toDate ? (() => { try { return parseLocalDate(toDate); } catch { return null; } })() : null;

  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center gap-2">
          <DollarSign className="h-5 w-5" /> Commission
        </CardTitle>
      </CardHeader>

      <CardContent className="space-y-6">
        {/* Filters */}
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
          <DateInput
            label="Start Date"
            value={fromDateObj}
            onChange={(d) => setFromDate(d ? formatLocalDate(d) : "")}
            disableFuture
          />
          <DateInput
            label="End Date"
            value={toDateObj}
            onChange={(d) => setToDate(d ? formatLocalDate(d) : "")}
            disableFuture
          />
          <div className="space-y-2">
            <Label>Provider</Label>
            <Select
              value={selectedProviderId?.toString() ?? ""}
              onValueChange={(v) => setSelectedProviderId(Number(v))}
            >
              <SelectTrigger>
                <SelectValue placeholder="Select a provider" />
              </SelectTrigger>
              <SelectContent>
                {providers.map((p) => (
                  <SelectItem key={p.id} value={p.id.toString()}>
                    {p.providerName}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
        </div>

        {/* Eligible payments table */}
        {selectedProviderId && (
          <div>
            <div className="flex items-center justify-between mb-2">
              <p className="text-sm text-gray-500">
                {isLoading
                  ? "Loading…"
                  : `${payments.length} eligible payment(s) — not yet commissioned`}
              </p>
              {selectedIds.size > 0 && (
                <Button
                  size="sm"
                  onClick={() => setShowModal(true)}
                  className="bg-green-600 hover:bg-green-700 text-white"
                >
                  Pay Commission ({selectedIds.size} selected — {fmt(totalCollection)})
                </Button>
              )}
            </div>

            {isError && (
              <p className="text-sm text-red-500">Failed to load payments.</p>
            )}

            {!isLoading && !isError && payments.length === 0 && (
              <p className="text-sm text-gray-400 py-4 text-center">
                No uncommissioned payments found for this provider and date range.
              </p>
            )}

            {payments.length > 0 && (
              <div className="overflow-x-auto rounded-lg border border-gray-200">
                <table className="w-full text-sm">
                  <thead className="bg-gray-50">
                    <tr>
                      <th className="px-3 py-2 text-left w-10">
                        <Checkbox
                          checked={allSelected}
                          data-state={someSelected ? "indeterminate" : undefined}
                          onCheckedChange={toggleAll}
                        />
                      </th>
                      <th className="px-3 py-2 text-left">Claim / Source</th>
                      <th className="px-3 py-2 text-left">Patient</th>
                      <th className="px-3 py-2 text-left">Service Date</th>
                      <th className="px-3 py-2 text-right">MH Paid</th>
                      <th className="px-3 py-2 text-right">Copayment</th>
                      <th className="px-3 py-2 text-right font-semibold">Collection</th>
                    </tr>
                  </thead>
                  <tbody>
                    {payments.map((p) => (
                      <tr
                        key={p.id}
                        className={`border-t border-gray-100 hover:bg-gray-50 cursor-pointer ${
                          selectedIds.has(p.id) ? "bg-green-50" : ""
                        }`}
                        onClick={() => toggleOne(p.id)}
                      >
                        <td className="px-3 py-2">
                          <Checkbox
                            checked={selectedIds.has(p.id)}
                            onCheckedChange={() => toggleOne(p.id)}
                            onClick={(e) => e.stopPropagation()}
                          />
                        </td>
                        <td className="px-3 py-2 font-mono text-xs">
                          {p.claimNumber ?? (p.isOcr ? (
                            <span className="bg-blue-100 text-blue-700 px-1.5 py-0.5 rounded text-xs">PDF Import</span>
                          ) : "—")}
                        </td>
                        <td className="px-3 py-2">{p.patientName}</td>
                        <td className="px-3 py-2 text-gray-500">
                          {p.serviceDate
                            ? new Date(p.serviceDate).toLocaleDateString()
                            : "—"}
                        </td>
                        <td className="px-3 py-2 text-right text-green-700">{fmt(p.mhPaidAmount)}</td>
                        <td className="px-3 py-2 text-right text-blue-700">{fmt(p.copayment)}</td>
                        <td className="px-3 py-2 text-right font-semibold">{fmt(p.collectionAmount)}</td>
                      </tr>
                    ))}
                  </tbody>
                  {selectedIds.size > 0 && (
                    <tfoot className="bg-gray-50 border-t-2 border-gray-200">
                      <tr>
                        <td colSpan={6} className="px-3 py-2 text-right font-semibold text-gray-700">
                          Selected Total ({selectedIds.size} items):
                        </td>
                        <td className="px-3 py-2 text-right font-bold text-green-700 text-base">
                          {fmt(totalCollection)}
                        </td>
                      </tr>
                    </tfoot>
                  )}
                </table>
              </div>
            )}
          </div>
        )}

        {/* Past commissions */}
        {batches.length > 0 && (
          <div>
            <h4 className="text-sm font-semibold text-gray-700 mb-2">Past Commission Batches</h4>
            <div className="overflow-x-auto rounded-lg border border-gray-200">
              <table className="w-full text-sm">
                <thead className="bg-gray-50">
                  <tr>
                    <th className="px-3 py-2 text-left">Date Paid</th>
                    <th className="px-3 py-2 text-left">Provider</th>
                    <th className="px-3 py-2 text-right">Claims</th>
                    <th className="px-3 py-2 text-right">Total Collection</th>
                    <th className="px-3 py-2 text-right">Commission Paid</th>
                    <th className="px-3 py-2 text-left">Notes</th>
                  </tr>
                </thead>
                <tbody>
                  {batches.map((b) => (
                    <tr key={b.id} className="border-t border-gray-100">
                      <td className="px-3 py-2">{formatDateToHumanReadable(b.createdAt)}</td>
                      <td className="px-3 py-2">{b.providerName}</td>
                      <td className="px-3 py-2 text-right">{b.itemCount}</td>
                      <td className="px-3 py-2 text-right">{fmt(b.totalCollection)}</td>
                      <td className="px-3 py-2 text-right font-semibold text-green-700">{fmt(b.commissionAmount)}</td>
                      <td className="px-3 py-2 text-gray-500">{b.notes ?? "—"}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>
        )}
      </CardContent>

      {/* Pay Commission Modal */}
      <Dialog open={showModal} onOpenChange={setShowModal}>
        <DialogContent className="sm:max-w-[680px] max-h-[90vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>Pay Commission</DialogTitle>
            <DialogDescription>
              Review the selected payments and confirm the commission amount.
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-4">
            {/* Selected rows summary */}
            <div className="overflow-x-auto rounded-lg border border-gray-200 max-h-64">
              <table className="w-full text-sm">
                <thead className="bg-gray-50 sticky top-0">
                  <tr>
                    <th className="px-3 py-2 text-left">Claim / Source</th>
                    <th className="px-3 py-2 text-left">Patient</th>
                    <th className="px-3 py-2 text-right">MH Paid</th>
                    <th className="px-3 py-2 text-right">Copayment</th>
                    <th className="px-3 py-2 text-right font-semibold">Collection</th>
                  </tr>
                </thead>
                <tbody>
                  {selectedPayments.map((p) => (
                    <tr key={p.id} className="border-t border-gray-100">
                      <td className="px-3 py-1.5 font-mono text-xs">
                        {p.claimNumber ?? (p.isOcr ? "PDF Import" : "—")}
                      </td>
                      <td className="px-3 py-1.5">{p.patientName}</td>
                      <td className="px-3 py-1.5 text-right">{fmt(p.mhPaidAmount)}</td>
                      <td className="px-3 py-1.5 text-right">{fmt(p.copayment)}</td>
                      <td className="px-3 py-1.5 text-right font-medium">{fmt(p.collectionAmount)}</td>
                    </tr>
                  ))}
                </tbody>
                <tfoot className="bg-gray-50 border-t-2 border-gray-200">
                  <tr>
                    <td colSpan={4} className="px-3 py-2 text-right font-semibold">Total Collection:</td>
                    <td className="px-3 py-2 text-right font-bold text-green-700">{fmt(totalCollection)}</td>
                  </tr>
                </tfoot>
              </table>
            </div>

            {/* Commission amount input */}
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
              <div className="space-y-1">
                <Label>Commission Amount ($)</Label>
                <Input
                  type="number"
                  min="0"
                  step="0.01"
                  value={commissionAmount}
                  onChange={(e) => setCommissionAmount(e.target.value)}
                  placeholder="Enter commission amount"
                />
                <p className="text-xs text-gray-400">Defaults to total collection. Adjust if using a rate.</p>
              </div>
              <div className="space-y-1">
                <Label>Notes (optional)</Label>
                <Input
                  value={notes}
                  onChange={(e) => setNotes(e.target.value)}
                  placeholder="e.g. May 2026 commission @ 20%"
                />
              </div>
            </div>

            <div className="flex justify-end gap-2 pt-2">
              <Button variant="outline" onClick={handlePrint}>
                Print
              </Button>
              <Button variant="outline" onClick={() => setShowModal(false)}>
                Cancel
              </Button>
              <Button
                onClick={handleSave}
                disabled={createMutation.isPending}
                className="bg-green-600 hover:bg-green-700 text-white"
              >
                {createMutation.isPending ? "Saving…" : "Save & Mark as Commissioned"}
              </Button>
            </div>
          </div>
        </DialogContent>
      </Dialog>
    </Card>
  );
}
