"use client";

import { useCallback, useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { format } from "date-fns";
import {
  DocumentTextIcon,
  CheckCircleIcon,
  ExclamationTriangleIcon,
  ClockIcon,
  ArrowDownTrayIcon,
} from "@heroicons/react/24/outline";
import { DataTable } from "@/components/molecules/DataTable/DataTable";
import { Button } from "@/components/atoms/button";
import { BillingStatusBadge } from "../BillingStatusBadge";
import type { Invoice } from "@customer-portal/domain/billing";
import { Formatting } from "@customer-portal/domain/toolkit";

const { formatCurrency } = Formatting;
import { cn } from "@/lib/utils";
import { useCreateInvoiceSsoLink } from "@/features/billing/hooks/useBilling";
import { openSsoLink } from "@/features/billing/utils/sso";
import { logger } from "@/lib/logger";

interface InvoiceTableProps {
  invoices: Invoice[];
  loading?: boolean;
  onInvoiceClick?: (invoice: Invoice) => void;
  showActions?: boolean;
  compact?: boolean;
  className?: string;
}

const getStatusIcon = (status: string) => {
  switch (status.toLowerCase()) {
    case "paid":
      return <CheckCircleIcon className="h-5 w-5 text-green-500" />;
    case "unpaid":
      return <ClockIcon className="h-5 w-5 text-yellow-500" />;
    case "overdue":
      return <ExclamationTriangleIcon className="h-5 w-5 text-red-500" />;
    case "cancelled":
    case "canceled":
      return <ExclamationTriangleIcon className="h-5 w-5 text-gray-500" />;
    default:
      return <ClockIcon className="h-5 w-5 text-gray-500" />;
  }
};

export function InvoiceTable({
  invoices,
  loading = false,
  onInvoiceClick,
  showActions = true,
  compact = false,
  className,
}: InvoiceTableProps) {
  const router = useRouter();
  const [paymentLoading, setPaymentLoading] = useState<number | null>(null);
  const [downloadLoading, setDownloadLoading] = useState<number | null>(null);
  const createSsoLinkMutation = useCreateInvoiceSsoLink();

  const handleInvoiceClick = useCallback(
    (invoice: Invoice) => {
      if (onInvoiceClick) {
        onInvoiceClick(invoice);
      } else {
        router.push(`/billing/invoices/${invoice.id}`);
      }
    },
    [onInvoiceClick, router]
  );

  const handlePayment = useCallback(
    async (invoice: Invoice, event: React.MouseEvent) => {
      event.stopPropagation(); // Prevent row click
      setPaymentLoading(invoice.id);
      try {
        const ssoLink = await createSsoLinkMutation.mutateAsync({
          invoiceId: invoice.id,
          target: "pay",
        });
        openSsoLink(ssoLink.url, { newTab: true });
      } catch (err) {
        logger.error("Failed to create payment SSO link", err);
      } finally {
        setPaymentLoading(null);
      }
    },
    [createSsoLinkMutation]
  );

  const handleDownload = useCallback(
    async (invoice: Invoice, event: React.MouseEvent) => {
      event.stopPropagation(); // Prevent row click
      setDownloadLoading(invoice.id);
      try {
        const ssoLink = await createSsoLinkMutation.mutateAsync({
          invoiceId: invoice.id,
          target: "download",
        });
        openSsoLink(ssoLink.url, { newTab: false });
      } catch (err) {
        logger.error("Failed to create download SSO link", err);
      } finally {
        setDownloadLoading(null);
      }
    },
    [createSsoLinkMutation]
  );

  const columns = useMemo(() => {
    const baseColumns = [
      {
        key: "invoice",
        header: "Invoice Details",
        className: "w-1/3",
        render: (invoice: Invoice) => {
          const statusIcon = getStatusIcon(invoice.status);
          return (
            <div className="flex items-start space-x-3 py-3">
              <div className="flex-shrink-0 mt-1">{statusIcon}</div>
              <div className="min-w-0 flex-1">
                <div className="font-semibold text-gray-900 text-sm">{invoice.number}</div>
                {!compact && invoice.description && (
                  <div className="text-sm text-gray-600 mt-1.5 line-clamp-2 leading-relaxed">
                    {invoice.description}
                  </div>
                )}
                {!compact && invoice.issuedAt && (
                  <div className="text-xs text-gray-500 mt-2 font-medium">
                    Issued {format(new Date(invoice.issuedAt), "MMM d, yyyy")}
                  </div>
                )}
              </div>
            </div>
          );
        },
      },
      {
        key: "status",
        header: "Status",
        className: "w-36",
        render: (invoice: Invoice) => {
          const renderStatusWithDate = () => {
            switch (invoice.status) {
              case "Paid":
                return (
                  <div className="space-y-2">
                    <span className="inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-green-100 text-green-800 border border-green-200">
                      Paid
                    </span>
                    {invoice.paidDate && (
                      <div className="text-xs text-green-700 font-medium">
                        {format(new Date(invoice.paidDate), "MMM d, yyyy")}
                      </div>
                    )}
                  </div>
                );

              case "Overdue":
                return (
                  <div className="space-y-2">
                    <span className="inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-red-100 text-red-800 border border-red-200">
                      Overdue
                    </span>
                    {invoice.daysOverdue && (
                      <div className="text-xs text-red-700 font-medium">
                        {invoice.daysOverdue} day{invoice.daysOverdue !== 1 ? "s" : ""} overdue
                      </div>
                    )}
                  </div>
                );

              case "Unpaid":
                return (
                  <div className="space-y-2">
                    <span className="inline-flex items-center px-3 py-1 rounded-full text-xs font-semibold bg-yellow-100 text-yellow-800 border border-yellow-200">
                      Unpaid
                    </span>
                    {invoice.dueDate && (
                      <div className="text-xs text-yellow-700 font-medium">
                        Due {format(new Date(invoice.dueDate), "MMM d, yyyy")}
                      </div>
                    )}
                  </div>
                );

              default:
                // Use the existing BillingStatusBadge for other statuses
                return <BillingStatusBadge status={invoice.status} />;
            }
          };

          return <div className="py-3">{renderStatusWithDate()}</div>;
        },
      },
      {
        key: "amount",
        header: "Amount",
        className: "w-32 text-right",
        render: (invoice: Invoice) => (
          <div className="py-3 text-right">
            <div className="font-bold text-gray-900 text-base">
              {formatCurrency(invoice.total, invoice.currency)}
            </div>
          </div>
        ),
      },
    ];

    // Add actions column if enabled
    if (showActions) {
      baseColumns.push({
        key: "actions",
        header: "Actions",
        className: "w-48 text-right",
        render: (invoice: Invoice) => {
          const canPay = invoice.status === "Unpaid" || invoice.status === "Overdue";
          const isPaymentLoading = paymentLoading === invoice.id;
          const isDownloadLoading = downloadLoading === invoice.id;

          return (
            <div className="py-3 flex justify-end items-center space-x-2">
              {/* Payment Button - Only for unpaid invoices - Always on the left */}
              {canPay && (
                <Button
                  size="sm"
                  variant="default"
                  onClick={event => {
                    void handlePayment(invoice, event);
                  }}
                  loading={isPaymentLoading}
                  className="text-xs font-medium shadow-sm"
                >
                  Pay Now
                </Button>
              )}

              {/* Download Button - Always available and always on the right */}
              <Button
                size="sm"
                variant="outline"
                onClick={event => {
                  void handleDownload(invoice, event);
                }}
                loading={isDownloadLoading}
                leftIcon={
                  !isDownloadLoading ? <ArrowDownTrayIcon className="h-4 w-4" /> : undefined
                }
                className="text-xs font-medium border-gray-300 hover:border-gray-400 hover:bg-gray-50"
                title="Download PDF"
              >
                PDF
              </Button>
            </div>
          );
        },
      });
    }

    return baseColumns;
  }, [compact, showActions, paymentLoading, downloadLoading, handlePayment, handleDownload]);

  const emptyState = {
    icon: <DocumentTextIcon className="h-12 w-12" />,
    title: "No invoices found",
    description: "No invoices have been generated yet.",
  };

  if (loading) {
    return (
      <div className={cn("bg-white overflow-hidden", className)}>
        <div className="animate-pulse">
          {/* Header skeleton */}
          <div className="bg-gradient-to-r from-gray-50 to-gray-50/80 px-6 py-4 border-b border-gray-200/80">
            <div className="grid grid-cols-4 gap-4">
              <div className="h-3 bg-gray-200 rounded w-32"></div>
              <div className="h-3 bg-gray-200 rounded w-16"></div>
              <div className="h-3 bg-gray-200 rounded w-20"></div>
              <div className="h-3 bg-gray-200 rounded w-24"></div>
            </div>
          </div>
          {/* Row skeletons */}
          <div className="divide-y divide-gray-100/60">
            {Array.from({ length: 6 }).map((_, i) => (
              <div key={i} className="px-6 py-5">
                <div className="grid grid-cols-4 gap-4 items-center">
                  <div className="flex items-center space-x-3">
                    <div className="h-5 w-5 bg-gray-200 rounded-full"></div>
                    <div className="space-y-2.5 flex-1">
                      <div className="h-4 bg-gray-200 rounded w-28"></div>
                      <div className="h-3 bg-gray-200 rounded w-40"></div>
                      <div className="h-3 bg-gray-200 rounded w-24"></div>
                    </div>
                  </div>
                  <div className="h-6 bg-gray-200 rounded-full w-20"></div>
                  <div className="text-right space-y-2">
                    <div className="h-4 bg-gray-200 rounded w-24 ml-auto"></div>
                    <div className="h-3 bg-gray-200 rounded w-20 ml-auto"></div>
                  </div>
                  <div className="text-right flex justify-end space-x-2">
                    <div className="h-8 bg-gray-200 rounded w-16"></div>
                    <div className="h-8 bg-gray-200 rounded w-20"></div>
                  </div>
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className={cn("bg-white overflow-hidden", className)}>
      <DataTable
        data={invoices}
        columns={columns}
        emptyState={emptyState}
        onRowClick={handleInvoiceClick}
        className={cn(
          "invoice-table",
          // Header styling - cleaner and more modern
          "[&_thead]:bg-gradient-to-r [&_thead]:from-gray-50 [&_thead]:to-gray-50/80",
          "[&_thead_th]:px-6 [&_thead_th]:py-3.5 [&_thead_th]:text-xs [&_thead_th]:font-medium [&_thead_th]:text-gray-600 [&_thead_th]:uppercase [&_thead_th]:tracking-wide",
          "[&_thead_th]:border-b [&_thead_th]:border-gray-200/80",
          // Row styling - enhanced hover and spacing
          "[&_tbody_tr]:border-b [&_tbody_tr]:border-gray-100/60 [&_tbody_tr]:transition-all [&_tbody_tr]:duration-200",
          "[&_tbody_tr:hover]:bg-gradient-to-r [&_tbody_tr:hover]:from-blue-50/30 [&_tbody_tr:hover]:to-indigo-50/20 [&_tbody_tr]:cursor-pointer",
          "[&_tbody_tr:last-child]:border-b-0",
          // Cell styling - better spacing
          "[&_tbody_td]:px-6 [&_tbody_td]:py-1 [&_tbody_td]:align-top",
          // Remove default DataTable styling
          "[&_.divide-y]:divide-transparent"
        )}
      />
    </div>
  );
}

export type { InvoiceTableProps };
