import { useMemo } from "react";
import { format, formatDistanceToNowStrict } from "date-fns";
import { ArrowDownTrayIcon, ArrowTopRightOnSquareIcon } from "@heroicons/react/24/outline";
import { Formatting } from "@customer-portal/domain/toolkit";

const { formatCurrency } = Formatting;
import type { Invoice } from "@customer-portal/domain/billing";
import { Button } from "@/components/atoms/button";
import { StatusPill } from "@/components/atoms/status-pill";
import { cn } from "@/lib/utils";

interface InvoiceSummaryBarProps {
  invoice: Invoice;
  loadingDownload?: boolean;
  loadingPayment?: boolean;
  onDownload?: () => void;
  onPay?: () => void;
}

const statusVariantMap: Partial<
  Record<Invoice["status"], "success" | "warning" | "error" | "neutral">
> = {
  Paid: "success",
  Unpaid: "warning",
  Overdue: "error",
  Cancelled: "neutral",
  Refunded: "neutral",
  Draft: "neutral",
  Pending: "warning",
  Collections: "error",
};

const statusLabelMap: Partial<Record<Invoice["status"], string>> = {
  Paid: "Paid",
  Unpaid: "Unpaid",
  Overdue: "Overdue",
  Refunded: "Refunded",
  Draft: "Draft",
  Cancelled: "Cancelled",
  Pending: "Pending",
  Collections: "Collections",
};

function formatDisplayDate(dateString?: string) {
  if (!dateString) return null;
  const date = new Date(dateString);
  if (Number.isNaN(date.getTime())) return null;
  return format(date, "dd MMM yyyy");
}

function formatRelativeDue(
  dateString: string | undefined,
  status: Invoice["status"],
  daysOverdue?: number
) {
  if (!dateString) return null;
  if (status === "Paid") return null;

  if (status === "Overdue" && daysOverdue) {
    return `${daysOverdue} day${daysOverdue !== 1 ? "s" : ""} overdue`;
  } else if (status === "Unpaid") {
    const dueDate = new Date(dateString);
    if (Number.isNaN(dueDate.getTime())) return null;
    const distance = formatDistanceToNowStrict(dueDate);
    return `due in ${distance}`;
  }

  return null;
}

export function InvoiceSummaryBar({
  invoice,
  loadingDownload,
  loadingPayment,
  onDownload,
  onPay,
}: InvoiceSummaryBarProps) {
  const formattedTotal = useMemo(
    () => formatCurrency(invoice.total, invoice.currency),
    [invoice.currency, invoice.total]
  );

  const dueDisplay = useMemo(() => formatDisplayDate(invoice.dueDate), [invoice.dueDate]);
  const issuedDisplay = useMemo(() => formatDisplayDate(invoice.issuedAt), [invoice.issuedAt]);
  const relativeDue = useMemo(
    () => formatRelativeDue(invoice.dueDate, invoice.status, invoice.daysOverdue),
    [invoice.dueDate, invoice.status, invoice.daysOverdue]
  );

  const statusVariant = statusVariantMap[invoice.status] ?? "neutral";
  const statusLabel = statusLabelMap[invoice.status] ?? invoice.status;

  return (
    <div
      className={cn(
        "sticky top-0 z-10 bg-white/95 backdrop-blur supports-[backdrop-filter]:bg-white/80",
        "border-b border-slate-200 shadow-sm",
        "px-4 sm:px-6 lg:px-8 py-6"
      )}
    >
      <div className="max-w-4xl mx-auto">
        {/* Header layout with proper alignment */}
        <div className="flex flex-col lg:flex-row lg:items-start lg:justify-between gap-6">
          {/* Left section: Amount, currency, and status */}
          <div className="flex-1">
            <div className="flex items-baseline gap-4 mb-3">
              <div className="text-4xl lg:text-5xl font-bold text-slate-900 leading-none">
                {formattedTotal}
              </div>
              <div className="text-lg font-medium text-slate-500 uppercase tracking-wide">
                {invoice.currency?.toUpperCase()}
              </div>
              <StatusPill
                size="md"
                variant={statusVariant}
                label={statusLabel}
                className="font-semibold"
              />
            </div>

            {/* Due date information */}
            {(dueDisplay || relativeDue) && (
              <div className="flex items-center gap-2 text-sm text-slate-600">
                {dueDisplay && <span>Due {dueDisplay}</span>}
                {relativeDue && (
                  <>
                    {dueDisplay && <span className="text-slate-400">•</span>}
                    <span
                      className={cn(
                        "font-medium",
                        invoice.status === "Overdue" ? "text-red-600" : "text-amber-600"
                      )}
                    >
                      {relativeDue}
                    </span>
                  </>
                )}
              </div>
            )}
          </div>

          {/* Right section: Actions and invoice info */}
          <div className="flex flex-col lg:items-end gap-4">
            {/* Action buttons */}
            <div className="flex flex-col sm:flex-row gap-3 lg:flex-row-reverse">
              <Button
                variant="outline"
                onClick={onDownload}
                disabled={!onDownload}
                loading={loadingDownload}
                leftIcon={<ArrowDownTrayIcon className="h-4 w-4" />}
                className="order-2 sm:order-1 lg:order-2"
              >
                Download PDF
              </Button>
              {(invoice.status === "Unpaid" || invoice.status === "Overdue") && (
                <Button
                  onClick={onPay}
                  disabled={!onPay}
                  loading={loadingPayment}
                  rightIcon={<ArrowTopRightOnSquareIcon className="h-4 w-4" />}
                  variant="default"
                  className="order-1 sm:order-2 lg:order-1"
                >
                  Pay Now
                </Button>
              )}
            </div>

            {/* Invoice metadata - inline layout */}
            <div className="flex flex-col sm:flex-row lg:flex-col xl:flex-row gap-2 lg:items-end text-sm text-slate-600">
              <div className="font-semibold text-slate-900">Invoice #{invoice.number}</div>
              {issuedDisplay && (
                <>
                  <span className="hidden sm:inline lg:hidden xl:inline text-slate-400">•</span>
                  <div>Issued {issuedDisplay}</div>
                </>
              )}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

export type { InvoiceSummaryBarProps };
