"use client";

import * as React from "react";
import Link from "next/link";
import { useActionState } from "react";
import { toast } from "sonner";
import { Decimal } from "decimal.js";
import {
  AlertTriangle,
  CheckCircle2,
  Eraser,
  Info,
  ListChecks,
  Loader2,
  Rocket,
  XCircle,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { StatusBadge } from "@/components/shared/status-badge";
import { submitMassOrderAction } from "@/lib/actions/bulk";
import { formatNumber, truncateLink } from "@/lib/format";
import { money } from "@/lib/serialize";
import { bulkTexts } from "@/lib/i18n/bulk";
import {
  MASS_ORDER_MAX_LINES,
  buildMassOrderPreview,
  type MassOrderServiceDTO,
  type MassOrderState,
} from "@/lib/validation/bulk";
import { cn } from "@/lib/utils";

function SummaryRow({
  label,
  value,
  tone,
}: {
  label: string;
  value: React.ReactNode;
  tone?: "default" | "muted" | "danger" | "success";
}) {
  return (
    <div className="flex items-baseline justify-between gap-3 text-sm">
      <span className="text-muted-foreground">{label}</span>
      <span
        className={cn(
          "font-mono font-medium tabular-nums",
          tone === "danger" && "text-red-600 dark:text-red-400",
          tone === "success" && "text-emerald-600 dark:text-emerald-400",
          tone === "muted" && "text-muted-foreground",
        )}
      >
        {value}
      </span>
    </div>
  );
}

export function MassOrderForm({
  services,
  balance,
}: {
  services: MassOrderServiceDTO[];
  /** Plain decimal string of the user's balance. */
  balance: string;
}) {
  const [text, setText] = React.useState("");
  const [state, formAction, pending] = useActionState<MassOrderState, FormData>(
    submitMassOrderAction,
    null,
  );
  const [dismissed, setDismissed] = React.useState(false);
  const seen = React.useRef<MassOrderState>(null);

  const serviceMap = React.useMemo(
    () => new Map(services.map((s) => [s.id, s] as const)),
    [services],
  );
  const preview = React.useMemo(
    () => buildMassOrderPreview(text, serviceMap),
    [text, serviceMap],
  );

  const lowBalance = React.useMemo(() => {
    try {
      return new Decimal(preview.total).greaterThan(new Decimal(balance || "0"));
    } catch {
      return false;
    }
  }, [preview.total, balance]);

  React.useEffect(() => {
    if (state === seen.current) return;
    seen.current = state;
    setDismissed(false);
    if (!state) return;
    if (state.ok) {
      const report = state.data;
      if (!report) return;
      if (report.failed === 0) toast.success(bulkTexts.massDone(report.created, 0));
      else if (report.created === 0) toast.error(bulkTexts.massDone(0, report.failed));
      else toast.warning(bulkTexts.massDone(report.created, report.failed));
    } else {
      toast.error(state.error);
    }
  }, [state]);

  const report = state && state.ok ? (state.data ?? null) : null;
  const showResults = report !== null && !dismissed;
  const blocked = preview.overLimit || preview.validCount === 0;

  return (
    <form action={formAction} className="grid gap-5 xl:grid-cols-[minmax(0,1fr)_320px]">
      <div className="space-y-5">
        {showResults && report ? (
          <section className="overflow-hidden rounded-2xl border bg-card shadow-sm">
            <header className="flex flex-wrap items-center justify-between gap-3 border-b px-4 py-3">
              <div className="flex items-center gap-2">
                <ListChecks className="size-4 text-primary" />
                <h2 className="font-display text-sm font-semibold">
                  {bulkTexts.massResultsTitle}
                </h2>
              </div>
              <div className="flex flex-wrap items-center gap-3 text-xs">
                <span className="inline-flex items-center gap-1 text-emerald-600 dark:text-emerald-400">
                  <CheckCircle2 className="size-3.5" />
                  {bulkTexts.massResultsCreated}:{" "}
                  <span className="font-mono tabular-nums">{report.created}</span>
                </span>
                <span className="inline-flex items-center gap-1 text-red-600 dark:text-red-400">
                  <XCircle className="size-3.5" />
                  {bulkTexts.massResultsFailed}:{" "}
                  <span className="font-mono tabular-nums">{report.failed}</span>
                </span>
                <span className="text-muted-foreground">
                  {bulkTexts.massResultsCharged}:{" "}
                  <span className="font-mono tabular-nums">{report.totalCharge}</span>
                </span>
              </div>
            </header>

            <div className="max-h-[320px] overflow-auto">
              <Table className="text-sm">
                <TableBody>
                  {report.results.map((line) => (
                    <TableRow key={`${line.lineNo}-${line.raw}`}>
                      <TableCell className="w-10 font-mono text-xs text-muted-foreground tabular-nums">
                        {line.lineNo}
                      </TableCell>
                      <TableCell className="max-w-[280px]">
                        <div className="truncate" title={line.raw}>
                          {line.serviceName ?? line.raw}
                        </div>
                        <div className="truncate font-mono text-xs text-muted-foreground">
                          {truncateLink(line.link, 40)}
                        </div>
                      </TableCell>
                      <TableCell className="text-right whitespace-nowrap">
                        {line.ok ? (
                          <div className="space-y-0.5">
                            <div className="font-mono text-sm text-emerald-600 tabular-nums dark:text-emerald-400">
                              {bulkTexts.massResultsOrder} #{line.orderId}
                            </div>
                            <div className="font-mono text-xs text-muted-foreground">
                              {line.charge}
                            </div>
                          </div>
                        ) : (
                          <span className="text-xs text-red-600 dark:text-red-400">
                            {line.error}
                          </span>
                        )}
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>

            <footer className="flex flex-wrap items-center justify-end gap-2 border-t px-4 py-3">
              <Button variant="outline" size="sm" asChild>
                <Link href="/orders">{bulkTexts.massResultsViewOrders}</Link>
              </Button>
              <Button
                type="button"
                variant="ghost"
                size="sm"
                onClick={() => setDismissed(true)}
              >
                {bulkTexts.massResultsAgain}
              </Button>
            </footer>
          </section>
        ) : null}

        <section className="space-y-3 rounded-2xl border bg-card p-4 shadow-sm">
          <div className="flex items-center justify-between gap-3">
            <label
              htmlFor="mass-lines"
              className="font-display text-sm font-semibold"
            >
              {bulkTexts.massTextareaLabel}
            </label>
            <Button
              type="button"
              variant="ghost"
              size="xs"
              onClick={() => setText("")}
              disabled={pending || text.length === 0}
            >
              <Eraser className="size-3" />
              {bulkTexts.massClear}
            </Button>
          </div>

          <Textarea
            id="mass-lines"
            name="lines"
            value={text}
            onChange={(event) => setText(event.target.value)}
            disabled={pending}
            spellCheck={false}
            rows={12}
            placeholder={bulkTexts.massTextareaPlaceholder}
            className="min-h-[220px] font-mono text-[13px] leading-relaxed"
          />

          <p className="text-xs text-muted-foreground">
            <span className="font-mono">{bulkTexts.massFormatLine}</span> —{" "}
            {bulkTexts.massFormatHint}
          </p>

          {preview.overLimit ? (
            <div className="flex items-start gap-2 rounded-xl border border-red-200 bg-red-50 p-3 text-sm text-red-700 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-400">
              <AlertTriangle className="mt-0.5 size-4 shrink-0" />
              <div>
                <p className="font-medium">
                  {bulkTexts.massTooManyTitle(MASS_ORDER_MAX_LINES)}
                </p>
                <p className="text-xs opacity-80">{bulkTexts.massTooManyHint}</p>
              </div>
            </div>
          ) : null}

          {!preview.overLimit && lowBalance && preview.validCount > 0 ? (
            <div className="flex items-start gap-2 rounded-xl border border-amber-200 bg-amber-50 p-3 text-sm text-amber-700 dark:border-amber-500/30 dark:bg-amber-500/10 dark:text-amber-400">
              <AlertTriangle className="mt-0.5 size-4 shrink-0" />
              <div className="space-y-1">
                <p className="font-medium">{bulkTexts.massLowBalanceTitle}</p>
                <p className="text-xs opacity-80">{bulkTexts.massLowBalanceHint}</p>
                <Link
                  href="/addfunds"
                  className="inline-flex text-xs font-medium underline underline-offset-2"
                >
                  {bulkTexts.massAddFunds}
                </Link>
              </div>
            </div>
          ) : null}
        </section>

        <section className="overflow-hidden rounded-2xl border bg-card shadow-sm">
          <header className="flex items-center justify-between gap-3 border-b px-4 py-3">
            <h2 className="font-display text-sm font-semibold">
              {bulkTexts.massPreviewTitle}
            </h2>
            <span className="font-mono text-xs text-muted-foreground tabular-nums">
              {preview.lines.length}
            </span>
          </header>

          {preview.lines.length === 0 ? (
            <p className="px-4 py-10 text-center text-sm text-muted-foreground">
              {bulkTexts.massPreviewEmpty}
            </p>
          ) : (
            <div className="max-h-[420px] overflow-auto">
              <Table className="text-sm">
                <TableHeader className="bg-card">
                  <TableRow className="hover:bg-transparent">
                    <TableHead className="w-10">{bulkTexts.massColLine}</TableHead>
                    <TableHead>{bulkTexts.massColService}</TableHead>
                    <TableHead>{bulkTexts.massColLink}</TableHead>
                    <TableHead className="text-right">
                      {bulkTexts.massColQuantity}
                    </TableHead>
                    <TableHead className="text-right">
                      {bulkTexts.massColCharge}
                    </TableHead>
                    <TableHead className="text-right">{bulkTexts.massColState}</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {preview.lines.map((line) => (
                    <TableRow
                      key={`${line.lineNo}-${line.raw}`}
                      className={cn(!line.valid && "bg-red-50/50 dark:bg-red-500/5")}
                    >
                      <TableCell className="font-mono text-xs text-muted-foreground tabular-nums">
                        {line.lineNo}
                      </TableCell>
                      <TableCell className="max-w-[220px]">
                        <div className="truncate">
                          {line.serviceName ?? (
                            <span className="text-muted-foreground">—</span>
                          )}
                        </div>
                        {line.serviceId ? (
                          <div className="font-mono text-xs text-muted-foreground">
                            #{line.serviceId}
                          </div>
                        ) : null}
                      </TableCell>
                      <TableCell className="max-w-[200px] truncate font-mono text-xs text-muted-foreground">
                        {line.link ? truncateLink(line.link, 32) : "—"}
                      </TableCell>
                      <TableCell className="text-right font-mono tabular-nums">
                        {line.effectiveQuantity
                          ? formatNumber(line.effectiveQuantity)
                          : "—"}
                      </TableCell>
                      <TableCell className="text-right font-mono tabular-nums">
                        {line.charge ? money(line.charge) : "—"}
                      </TableCell>
                      <TableCell className="text-right">
                        {line.valid ? (
                          <StatusBadge status="COMPLETED" label={bulkTexts.massValid} />
                        ) : (
                          <span
                            className="text-xs text-red-600 dark:text-red-400"
                            title={line.error}
                          >
                            {line.error ?? bulkTexts.massInvalid}
                          </span>
                        )}
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
          )}
        </section>
      </div>

      <aside className="space-y-4 xl:sticky xl:top-4 xl:self-start">
        <div className="space-y-3 rounded-2xl border bg-card p-4 shadow-sm">
          <h2 className="font-display text-sm font-semibold">
            {bulkTexts.massSummaryTotal}
          </h2>
          <p className="font-mono text-2xl font-semibold tabular-nums">
            {money(preview.total)}
          </p>

          <div className="space-y-1.5 border-t pt-3">
            <SummaryRow
              label={bulkTexts.massSummaryLines}
              value={preview.lines.length}
              tone="muted"
            />
            <SummaryRow
              label={bulkTexts.massSummaryValid}
              value={preview.validCount}
              tone={preview.validCount > 0 ? "success" : "muted"}
            />
            <SummaryRow
              label={bulkTexts.massSummaryInvalid}
              value={preview.invalidCount}
              tone={preview.invalidCount > 0 ? "danger" : "muted"}
            />
            <SummaryRow
              label={bulkTexts.massSummaryBalance}
              value={money(balance)}
              tone={lowBalance ? "danger" : "muted"}
            />
          </div>

          <Button type="submit" className="w-full" disabled={pending || blocked}>
            {pending ? (
              <>
                <Loader2 className="size-3.5 animate-spin" />
                {bulkTexts.massSubmitting}
              </>
            ) : (
              <>
                <Rocket className="size-3.5" />
                {bulkTexts.massSubmit}
              </>
            )}
          </Button>

          {preview.validCount === 0 && preview.lines.length > 0 && !preview.overLimit ? (
            <p className="text-center text-xs text-muted-foreground">
              {bulkTexts.massNothingValid}
            </p>
          ) : null}
        </div>

        <div className="space-y-2 rounded-2xl border bg-card p-4 text-sm shadow-sm">
          <div className="flex items-center gap-2">
            <Info className="size-4 text-primary" />
            <h2 className="font-display text-sm font-semibold">
              {bulkTexts.massFormatTitle}
            </h2>
          </div>
          <code className="block rounded-lg bg-muted px-2.5 py-2 font-mono text-xs">
            {bulkTexts.massFormatLine}
          </code>
          <p className="text-xs text-muted-foreground">
            {bulkTexts.massFormatExample}
          </p>
          <code className="block rounded-lg bg-muted px-2.5 py-2 font-mono text-[11px] leading-relaxed whitespace-pre-wrap">
            {bulkTexts.massTextareaPlaceholder}
          </code>
          <p className="text-xs text-muted-foreground">
            {bulkTexts.massFormatUnsupported}
          </p>
        </div>
      </aside>
    </form>
  );
}

export default MassOrderForm;
