"use client";

import React, { useMemo, useState } from "react";
import {
  DocumentTextIcon,
  CheckCircleIcon,
  ExclamationTriangleIcon,
  ClockIcon,
} from "@heroicons/react/24/outline";
import { Spinner } from "@/components/atoms";
import { SummaryStats, ClearFiltersButton } from "@/components/molecules";
import type { StatItem } from "@/components/molecules/SummaryStats";
import { AsyncBlock } from "@/components/molecules/AsyncBlock/AsyncBlock";
import { PaginationBar } from "@/components/molecules/PaginationBar/PaginationBar";
import { SearchFilterBar } from "@/components/molecules/SearchFilterBar/SearchFilterBar";
import { InvoiceTable } from "@/features/billing/components/InvoiceTable/InvoiceTable";
import { useInvoices } from "@/features/billing/hooks/useBilling";
import {
  VALID_INVOICE_QUERY_STATUSES,
  type Invoice,
  type InvoiceQueryStatus,
} from "@customer-portal/domain/billing";
import { cn } from "@/shared/utils";

interface InvoicesListProps {
  pageSize?: number;
  compact?: boolean;
  className?: string;
}

const INVOICE_STATUS_OPTIONS = [
  { value: "all", label: "All Statuses" },
  ...VALID_INVOICE_QUERY_STATUSES.map(status => ({
    value: status,
    label: status,
  })),
];

function computeInvoiceStats(invoices: Invoice[]) {
  const result = { total: 0, paid: 0, unpaid: 0, overdue: 0 };
  for (const invoice of invoices) {
    result.total++;
    if (invoice.status === "Paid") result.paid++;
    else if (invoice.status === "Unpaid") result.unpaid++;
    else if (invoice.status === "Overdue") result.overdue++;
  }
  return result;
}

function buildSummaryStatsItems(
  stats: ReturnType<typeof computeInvoiceStats>,
  totalItems?: number
): StatItem[] {
  return [
    {
      icon: <DocumentTextIcon className="h-4 w-4" />,
      label: "Total",
      value: totalItems ?? stats.total,
      tone: "muted",
    },
    {
      icon: <CheckCircleIcon className="h-4 w-4" />,
      label: "Paid",
      value: stats.paid,
      tone: "success",
    },
    {
      icon: <ClockIcon className="h-4 w-4" />,
      label: "Unpaid",
      value: stats.unpaid,
      tone: "warning",
      show: stats.unpaid > 0,
    },
    {
      icon: <ExclamationTriangleIcon className="h-4 w-4" />,
      label: "Overdue",
      value: stats.overdue,
      tone: "warning",
      show: stats.overdue > 0,
    },
  ];
}

function InvoicesListPending() {
  return (
    <div className="bg-card rounded-xl border border-border shadow-[var(--cp-shadow-1)] overflow-hidden">
      <div className="flex items-center justify-center py-16">
        <Spinner size="lg" className="text-primary" />
      </div>
    </div>
  );
}

function InvoicesListError({ error }: { error: unknown }) {
  return (
    <div className="bg-card rounded-xl border border-border shadow-[var(--cp-shadow-1)] overflow-hidden">
      <AsyncBlock isLoading={false} error={error}>
        <div />
      </AsyncBlock>
    </div>
  );
}

function useInvoiceListState(props: InvoicesListProps) {
  const { pageSize = 10 } = props;
  const [searchTerm, setSearchTerm] = useState("");
  const [statusFilter, setStatusFilter] = useState<InvoiceQueryStatus | "all">("all");
  const [currentPage, setCurrentPage] = useState(1);

  const { data, isLoading, isPending, error } = useInvoices({
    page: currentPage,
    limit: pageSize,
    status: statusFilter === "all" ? undefined : statusFilter,
  });

  const rawInvoices = data?.invoices;
  const invoices = useMemo(() => rawInvoices ?? [], [rawInvoices]);
  const pagination = data?.pagination;

  const filtered = useMemo(() => {
    if (!searchTerm) return invoices;
    const term = searchTerm.toLowerCase();
    return invoices.filter(
      inv =>
        inv.number.toLowerCase().includes(term) ||
        (inv.description ? inv.description.toLowerCase().includes(term) : false)
    );
  }, [invoices, searchTerm]);

  const stats = useMemo(() => computeInvoiceStats(invoices), [invoices]);
  const summaryStatsItems = useMemo(
    () => buildSummaryStatsItems(stats, pagination?.totalItems),
    [pagination?.totalItems, stats]
  );

  return {
    isLoading,
    isPending,
    error,
    invoices,
    filtered,
    pagination,
    summaryStatsItems,
    searchTerm,
    setSearchTerm,
    statusFilter,
    setStatusFilter,
    currentPage,
    setCurrentPage,
    hasActiveFilters: searchTerm.trim() !== "" || statusFilter !== "all",
  };
}

export function InvoicesList(props: InvoicesListProps) {
  const { compact = false, className } = props;
  const state = useInvoiceListState(props);

  if (state.isPending) return <InvoicesListPending />;
  if (state.error) return <InvoicesListError error={state.error} />;

  const clearFilters = () => {
    state.setSearchTerm("");
    state.setStatusFilter("all");
    state.setCurrentPage(1);
  };

  return (
    <div className={cn("space-y-4", className)}>
      {state.invoices.length > 0 && (
        <SummaryStats variant="inline" items={state.summaryStatsItems} />
      )}

      <SearchFilterBar
        searchValue={state.searchTerm}
        onSearchChange={state.setSearchTerm}
        searchPlaceholder="Search by invoice number..."
        filterValue={state.statusFilter}
        onFilterChange={(value: string) => {
          state.setStatusFilter(value as InvoiceQueryStatus | "all");
          state.setCurrentPage(1);
        }}
        filterOptions={INVOICE_STATUS_OPTIONS}
        filterLabel="Filter by status"
      >
        <ClearFiltersButton onClick={clearFilters} show={state.hasActiveFilters} />
      </SearchFilterBar>

      <div className="bg-card rounded-xl border border-border shadow-[var(--cp-shadow-1)] overflow-hidden">
        <InvoiceTable
          invoices={state.filtered}
          loading={state.isLoading}
          compact={compact}
          className="border-0 rounded-none shadow-none"
        />
        {state.pagination && state.filtered.length > 0 && (
          <div className="border-t border-border px-6 py-4">
            <PaginationBar
              currentPage={state.currentPage}
              pageSize={props.pageSize ?? 10}
              totalItems={state.pagination.totalItems || 0}
              onPageChange={state.setCurrentPage}
            />
          </div>
        )}
      </div>
    </div>
  );
}

export type { InvoicesListProps };
