"use client";

import { Fragment, useState } from "react";
import { ChevronDown, ChevronLeft, ChevronRight, ChevronUp } from "lucide-react";
import { StatusBadge } from "@/components/shared/status-badge";
import { Button } from "@/components/ui/button";
import { useQueryUpdate } from "@/components/shared/query-controls";
import type { Pagination } from "@/lib/list-query";
import type { WalletActivityEntry } from "./types";

const metadataLabels: Record<string, string> = {
  charge_point_id: "Charge point",
  charging_session_id: "Charging session",
  connector_id: "Connector",
  duration_minutes: "Duration (minutes)",
  energy_kwh: "Energy delivered (kWh)",
  idle_minutes: "Idle time (minutes)",
  transaction_id: "OCPP transaction ID",
  payment_method: "Payment method",
  reference_id: "Reference ID",
  reference_type: "Reference type",
  source: "Source",
};

function formatCurrency(value: number, currency: string) {
  try {
    return new Intl.NumberFormat("id-ID", {
      style: "currency",
      currency,
      maximumFractionDigits: 2,
    }).format(value);
  } catch {
    return `${currency} ${value.toLocaleString("id-ID", { maximumFractionDigits: 2 })}`;
  }
}

function formatChangedAt(value: string) {
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return "—";
  return new Intl.DateTimeFormat("en-GB", {
    day: "2-digit",
    month: "short",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
    timeZone: "Asia/Jakarta",
  }).format(date);
}

function formatLabel(key: string) {
  return metadataLabels[key] ?? key.replaceAll("_", " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
}

function formatMetadataValue(value: string | number | boolean | null) {
  if (value === null) return "—";
  if (typeof value === "number") return value.toLocaleString("id-ID", { maximumFractionDigits: 2 });
  return String(value);
}

function isReferenceMetadata(key: string) {
  const normalized = key.replace(/[^a-z0-9]/gi, "").toLowerCase();
  return normalized === "referencetype" || normalized === "referenceid";
}

export function WalletActivityPanel({
  entries,
  currency,
  pagination,
  error,
  previewOnly = false,
}: {
  entries: WalletActivityEntry[];
  currency: string;
  pagination?: Pagination;
  error?: string;
  previewOnly?: boolean;
}) {
  const [expandedAuditId, setExpandedAuditId] = useState<string | null>(null);
  const updateQuery = useQueryUpdate();

  return (
    <section className="space-y-4">
      <div className="flex flex-wrap items-start justify-between gap-3">
        <div>
          <h3 className="text-base font-semibold">Wallet Activity</h3>
          <p className="mt-1 text-sm text-muted-foreground">
            Wallet credits, debits, and their transaction references.
          </p>
        </div>
        {previewOnly && <StatusBadge tone="info">Mock data</StatusBadge>}
      </div>

      {error ? (
        <div role="alert" className="rounded-xl border border-destructive/30 bg-destructive/5 px-5 py-4">
          <p className="font-medium text-destructive">Wallet activity unavailable</p>
          <p className="mt-1 text-sm text-destructive">{error}</p>
        </div>
      ) : entries.length ? (
        <>
          <div className="overflow-x-auto rounded-xl border border-border">
            <table className="data-table min-w-[940px]">
              <caption className="sr-only">Wallet activity</caption>
              <thead>
                <tr>
                  <th>Date</th>
                  <th>Reference</th>
                  <th className="text-right">Balance before</th>
                  <th className="text-right">Amount</th>
                  <th className="text-right">Balance after</th>
                  <th><span className="sr-only">Details</span></th>
                </tr>
              </thead>
              <tbody>
                {entries.map((entry) => {
                  const expanded = expandedAuditId === entry.auditId;
                  const detailsId = `wallet-activity-details-${entry.auditId}`;
                  return (
                    <Fragment key={entry.auditId}>
                      <tr>
                        <td className="whitespace-nowrap">{formatChangedAt(entry.changedAt)}</td>
                        <td className="min-w-64">
                          <span className="block text-sm capitalize">
                            {entry.referenceType.replaceAll("_", " ")}
                          </span>
                          {entry.referenceId && (
                            <span className="mt-1 block break-all text-xs text-muted-foreground">
                              {entry.referenceId}
                            </span>
                          )}
                        </td>
                        <td className="whitespace-nowrap text-right">{formatCurrency(entry.balanceBefore, currency)}</td>
                        <td className={`whitespace-nowrap text-right font-medium ${entry.entryType === "credit" ? "text-success" : "text-destructive"}`}>
                          {entry.entryType === "credit" ? "+" : "−"}{formatCurrency(entry.amount, currency)}
                        </td>
                        <td className="whitespace-nowrap text-right">{formatCurrency(entry.balanceAfter, currency)}</td>
                        <td className="text-right">
                          <button
                            type="button"
                            aria-expanded={expanded}
                            aria-controls={detailsId}
                            className="inline-flex items-center gap-1 rounded-md px-2 py-1 text-sm font-medium text-primary hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
                            onClick={() => setExpandedAuditId(expanded ? null : entry.auditId)}
                          >
                            {expanded ? "Hide" : "Details"}
                            {expanded ? <ChevronUp className="size-4" aria-hidden="true" /> : <ChevronDown className="size-4" aria-hidden="true" />}
                          </button>
                        </td>
                      </tr>
                      {expanded && (
                        <tr hidden={!expanded}>
                          <td id={detailsId} colSpan={6} className="bg-muted/30 px-5 py-4">
                            <dl className="grid gap-x-6 gap-y-4 sm:grid-cols-2 xl:grid-cols-4">
                              <div className="min-w-0 sm:col-span-2 xl:col-span-4">
                                <dt className="text-xs text-muted-foreground">Description</dt>
                                <dd className="mt-1 whitespace-pre-wrap break-words text-sm font-medium">
                                  {entry.description || "—"}
                                </dd>
                              </div>
                              {Object.entries(entry.metadata).filter(([key]) => !isReferenceMetadata(key)).map(([key, value]) => (
                                <div key={key} className="min-w-0">
                                  <dt className="text-xs text-muted-foreground">{formatLabel(key)}</dt>
                                  <dd className="mt-1 break-words text-sm font-medium">{formatMetadataValue(value)}</dd>
                                </div>
                              ))}
                            </dl>
                          </td>
                        </tr>
                      )}
                    </Fragment>
                  );
                })}
              </tbody>
            </table>
          </div>
          {pagination && (pagination.pages > 1 || pagination.total > pagination.limit) && (
            <div className="flex flex-wrap items-center justify-between gap-3 border-t border-border pt-4">
              <p className="text-sm text-muted-foreground">
                Showing {pagination.start}–{pagination.end} of {pagination.total} entries
              </p>
              <div className="ml-auto flex items-center gap-2">
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  disabled={pagination.page <= 1}
                  onClick={() => updateQuery({ paginate_page: String(pagination.page - 1) })}
                >
                  <ChevronLeft aria-hidden="true" />Previous
                </Button>
                <span className="whitespace-nowrap text-sm text-muted-foreground">
                  Page {pagination.page} of {pagination.pages}
                </span>
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  disabled={pagination.page >= pagination.pages}
                  onClick={() => updateQuery({ paginate_page: String(pagination.page + 1) })}
                >
                  Next<ChevronRight aria-hidden="true" />
                </Button>
              </div>
            </div>
          )}
          {previewOnly && (
            <p className="text-xs text-muted-foreground">
              Preview only · {entries.length} illustrative entries · Not connected to the wallet audit API.
            </p>
          )}
        </>
      ) : (
        <div className="rounded-xl border border-border bg-background px-5 py-10 text-center">
          <p className="font-medium">No wallet activity</p>
          <p className="mt-1 text-sm text-muted-foreground">
            {previewOnly ? "There are no wallet changes to display." : "No wallet changes were recorded for this customer."}
          </p>
        </div>
      )}
    </section>
  );
}
