"use client";

import { useCallback, useState } from "react";
import { Settings, Wallet, AlertCircle, ShieldAlert, Ban } from "lucide-react";
import { useRepositories } from "@/di/repository-provider";
import { useApiQuery } from "@/presentation/hooks/use-api-query";
import { useApiMutation } from "@/presentation/hooks/use-api-mutation";
import { useServerPagination } from "@/presentation/hooks/use-server-pagination";
import { useT, useLocale } from "@/shared/i18n/client";
import { formatDate } from "@/shared/lib/format-date";
import ServerDataTable, {
  type Column,
} from "@/presentation/components/shared/server-data-table";
import StatsCard from "@/presentation/components/shared/stats-card";
import { Button } from "@/presentation/components/ui/button";
import { BillingStatusBadge } from "@/presentation/components/billing/billing-status-badge";
import { BillingSettingsDialog } from "@/presentation/components/billing/billing-settings-dialog";
import { BillingGererDialog } from "@/presentation/components/billing/billing-gerer-dialog";
import type { BillingClientRow } from "@/domain/entities/billing";

export function BillingTab() {
  const t = useT();
  const locale = useLocale();
  const repo = useRepositories().billingRepository;
  const pagination = useServerPagination({ orderBy: "amount_due", order: "DESC" });

  const [settingsOpen, setSettingsOpen] = useState(false);
  const [manageId, setManageId] = useState<number | null>(null);
  const [manageOpen, setManageOpen] = useState(false);

  const { data: stats, refetch: refetchStats } = useApiQuery(() => repo.getStats(), {
    deps: [],
  });
  const { data: options } = useApiQuery(() => repo.getOptions(), { deps: [] });
  const { data: settings, refetch: refetchSettings } = useApiQuery(
    () => repo.getSettings(),
    { deps: [] }
  );
  const { data: response, loading, refetch } = useApiQuery(
    () => repo.findClients(pagination.params),
    { deps: [pagination.params] }
  );

  const refreshAll = useCallback(() => {
    refetch();
    refetchStats();
  }, [refetch, refetchStats]);

  const updateSettingsMutation = useApiMutation(
    (months: number) => repo.updateSettings({ default_tolerance_months: months }),
    {
      successMessage: t.billing.settings.saved,
      onSuccess: () => {
        setSettingsOpen(false);
        refetchSettings();
        refreshAll();
      },
    }
  );

  const fmtMoney = (amount: number, currency = "EUR") =>
    new Intl.NumberFormat(locale === "fr" ? "fr-FR" : "en-US", {
      style: "currency",
      currency,
      maximumFractionDigits: 0,
    }).format(amount);

  const openManage = (id: number) => {
    setManageId(id);
    setManageOpen(true);
  };

  const activeStatus = (pagination.filters.status as string) ?? undefined;

  const columns: Column<BillingClientRow>[] = [
    {
      key: "name",
      label: t.billing.columns.client,
      sortable: true,
      render: (row) => (
        <div className="min-w-0">
          <p className="text-sm font-medium truncate">{row.client.name}</p>
          {row.client.contact && (
            <p className="text-xs text-muted-foreground truncate">{row.client.contact}</p>
          )}
        </div>
      ),
    },
    {
      key: "plan",
      label: t.billing.columns.plan,
      render: (row) => (
        <div className="min-w-0">
          <p className="text-sm truncate">{row.plan?.name ?? "—"}</p>
          {row.plan && (
            <p className="text-xs text-muted-foreground">
              {t.billing.perMonth(fmtMoney(row.plan.monthly_amount, row.plan.currency))}
            </p>
          )}
        </div>
      ),
    },
    {
      key: "vehicles_count",
      label: t.billing.columns.vehicles,
      render: (row) => <span className="text-sm">{row.vehicles_count}</span>,
    },
    {
      key: "status",
      label: t.billing.columns.status,
      render: (row) => <BillingStatusBadge status={row.status} />,
    },
    {
      key: "unpaid_count",
      label: t.billing.columns.unpaid,
      sortable: true,
      render: (row) => (
        <span className="text-sm tabular-nums">
          <span className={row.unpaid_count > 0 ? "font-semibold text-foreground" : ""}>
            {row.unpaid_count}
          </span>
          <span className="text-muted-foreground"> / {row.tolerance_months}</span>
        </span>
      ),
    },
    {
      key: "amount_due",
      label: t.billing.columns.amountDue,
      sortable: true,
      render: (row) => (
        <span
          className={`text-sm font-medium tabular-nums ${
            row.amount_due > 0 ? "text-red-600" : "text-muted-foreground"
          }`}
        >
          {fmtMoney(row.amount_due, row.currency)}
        </span>
      ),
    },
    {
      key: "next_due_date",
      label: t.billing.columns.nextDue,
      render: (row) => (
        <span className="text-sm whitespace-nowrap">
          {row.next_due_date ? formatDate(row.next_due_date, locale) : "—"}
        </span>
      ),
    },
    {
      key: "tolerance_months",
      label: t.billing.columns.tolerance,
      render: (row) => (
        <span className="text-sm whitespace-nowrap">{t.billing.months(row.tolerance_months)}</span>
      ),
    },
    {
      key: "action",
      label: t.billing.columns.action,
      className: "w-20",
      render: (row) => (
        <Button size="sm" variant="outline" onClick={() => openManage(row.id)}>
          {t.billing.manageButton}
        </Button>
      ),
    },
  ];

  return (
    <div className="space-y-6">
      {stats && (
        <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
          <StatsCard
            title={t.billing.stats.totalDue}
            value={fmtMoney(stats.total_due, stats.currency)}
            icon={Wallet}
            accent="red"
            mono
          />
          <StatsCard
            title={t.billing.stats.withUnpaid}
            value={stats.clients_with_unpaid}
            icon={AlertCircle}
            accent="amber"
          />
          <StatsCard
            title={t.billing.stats.atRisk}
            value={stats.at_risk}
            icon={ShieldAlert}
            accent="amber"
          />
          <StatsCard
            title={t.billing.stats.suspended}
            value={stats.suspended}
            icon={Ban}
            accent="red"
          />
        </div>
      )}

      <ServerDataTable
        columns={columns}
        data={response?.items ?? []}
        total={response?.total ?? 0}
        page={pagination.page}
        totalPages={response?.last_page ?? 1}
        loading={loading}
        search={pagination.search}
        onSearchChange={pagination.setSearch}
        onPageChange={pagination.setPage}
        onSortChange={pagination.setSort}
        sortBy={pagination.orderBy}
        sortOrder={pagination.order}
        searchPlaceholder={t.billing.searchPlaceholder}
        emptyMessage={t.billing.empty}
        toolbar={
          <div className="flex items-center gap-2 flex-wrap">
            {(options?.statuses ?? []).map((s) => (
              <Button
                key={s.value}
                size="sm"
                variant={activeStatus === s.value ? "default" : "outline"}
                onClick={() =>
                  pagination.setFilter("status", activeStatus === s.value ? undefined : s.value)
                }
              >
                {s.label}
              </Button>
            ))}
            <Button size="sm" variant="outline" className="gap-1.5" onClick={() => setSettingsOpen(true)}>
              <Settings className="w-4 h-4" />
              {t.billing.settingsButton}
            </Button>
          </div>
        }
      />

      <BillingSettingsDialog
        open={settingsOpen}
        onOpenChange={setSettingsOpen}
        settings={settings}
        loading={updateSettingsMutation.loading}
        onSave={(months) => updateSettingsMutation.mutate(months)}
      />

      <BillingGererDialog
        clientId={manageId}
        open={manageOpen}
        onOpenChange={setManageOpen}
        options={options}
        defaultTolerance={settings?.default_tolerance_months ?? null}
        onChanged={refreshAll}
      />
    </div>
  );
}
