"use client";

import { useCallback, useEffect, useState } from "react";
import { toast } from "sonner";
import Link from "next/link";
import { customerApi } from "@/lib/api/customer";
import { useToken } from "@/lib/auth/useToken";
import type { ApiDashboard, ApiWatchlistItem } from "@/lib/api/types";
import { ShoppingBag, FileText, Clock, CheckCircle2, IndianRupee, Bookmark, PlusCircle, ArrowRight, ChevronRight, Search, BellRing, BadgeCheck, Wallet, Trash2 } from "lucide-react";
import Loader from "@/components/ui/Loader";
import SafeImage from "@/components/ui/SafeImage";
import ConfirmDialog from "@/components/ui/ConfirmDialog";
import { formatDateTime, formatNumber, formatRelativeAge, formatUnit } from "@/lib/utils";
import Figure from "./Figure";
import { rfqStatusLabel } from "@/lib/status";

function StatCard({ label, value, icon: Icon, tone, href }: { label: string; value: string | number; icon: React.ElementType; tone: string; href?: string }) {
  const body = (
    <>
      <div className="flex items-center justify-between">
        <span className="text-[11px] font-semibold uppercase tracking-wide text-gray-500">{label}</span>
        <span className={`flex h-8 w-8 items-center justify-center rounded-lg ${tone}`}>
          <Icon className="h-4 w-4" />
        </span>
      </div>
      <div className="mt-2 truncate text-lg font-bold tabular-nums text-gray-900 sm:text-xl">{value}</div>
    </>
  );
  // A tile opens the list it counts, filtered to the same status.
  return href ? (
    <Link href={href} className="rounded-xl bg-white p-4 shadow-sm ring-1 ring-gray-100 transition hover:ring-[#CC1414]/40">
      {body}
    </Link>
  ) : (
    <div className="rounded-xl bg-white p-4 shadow-sm ring-1 ring-gray-100">{body}</div>
  );
}

function fmtINR(n: number) {
  return new Intl.NumberFormat("en-IN", { style: "currency", currency: "INR", maximumFractionDigits: 0 }).format(n);
}

type Suggestion = { slug: string; name: string };

type Part = { label: string; value: number; color: string; href: string };

/**
 * One total split into its parts: a bar whose segments are the parts, and a
 * legend with each count, linking to the list filtered to it. Replaces the
 * "1 orders = 1 in progress + 0 dispatched + …" sum, which read like a formula.
 */
function Breakdown({
  icon: Icon,
  title,
  total,
  parts,
  emptyText,
  allHref,
}: {
  icon: React.ElementType;
  title: string;
  total: number;
  parts: Part[];
  emptyText: string;
  allHref: string;
}) {
  return (
    <div className="min-w-0">
      <div className="flex items-center justify-between gap-2">
        <Link href={allHref} className="flex items-center gap-1.5 text-sm font-semibold text-gray-900 hover:text-[#CC1414]">
          <Icon className="h-4 w-4 text-[#CC1414]" /> {title}
        </Link>
        <span className="text-xs text-gray-500">
          <span className="text-base font-bold text-gray-900">{total}</span> total
        </span>
      </div>
      <div className="mt-2 flex h-2 overflow-hidden rounded-full bg-gray-100" aria-hidden>
        {total > 0 &&
          parts.map((p) =>
            p.value > 0 ? <div key={p.label} style={{ width: `${(p.value / total) * 100}%`, backgroundColor: p.color }} /> : null
          )}
      </div>
      {total === 0 ? (
        <p className="mt-2 text-xs text-gray-500">{emptyText}</p>
      ) : (
        <ul className="mt-2 space-y-1">
          {parts.map((p) => (
            <li key={p.label}>
              <Link href={p.href} className="flex items-center justify-between gap-2 rounded px-1 py-0.5 text-xs text-gray-600 hover:bg-gray-50 hover:text-[#CC1414]">
                <span className="flex min-w-0 items-center gap-1.5">
                  <span className="h-2 w-2 shrink-0 rounded-full" style={{ backgroundColor: p.color }} />
                  <span className="truncate">{p.label}</span>
                </span>
                <span className="font-semibold tabular-nums text-gray-900">{p.value}</span>
              </Link>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

/** Orders, requirements and wallet at a glance, in words a first-time buyer follows. */
function SummaryCard({ tiles, wallet }: { tiles: NonNullable<ApiDashboard["tiles"]>; wallet: ApiDashboard["wallet"] }) {
  const { orders, rfqs } = tiles;

  return (
    <div className="grid grid-cols-1 gap-5 rounded-xl bg-white p-4 shadow-sm ring-1 ring-gray-100 md:grid-cols-3 md:divide-x md:divide-gray-100">
      <Breakdown
        icon={ShoppingBag}
        title="My Orders"
        total={orders.total}
        allHref="/orders"
        emptyText="No orders yet. Accept a quote to place your first order."
        parts={[
          { label: "In progress", value: orders.in_progress, color: "#fb923c", href: "/orders?status=in_progress" },
          { label: "Dispatched (on the way)", value: orders.dispatched, color: "#6366f1", href: "/orders?status=dispatched" },
          { label: "Delivered", value: orders.delivered, color: "#22c55e", href: "/orders?status=delivered" },
          ...(orders.cancelled > 0 ? [{ label: "Cancelled", value: orders.cancelled, color: "#9ca3af", href: "/orders?status=cancelled" }] : []),
        ]}
      />
      <div className="md:pl-5">
        <Breakdown
          icon={FileText}
          title="My Requirements"
          total={rfqs.total}
          allHref="/rfq"
          emptyText="No requirements yet. Post one to get quotes from sellers."
          parts={[
            { label: rfqStatusLabel("rfq_open", "buyer"), value: rfqs.open, color: "#f59e0b", href: "/rfq?status=rfq_open" },
            { label: rfqStatusLabel("quoted", "buyer"), value: rfqs.quoted, color: "#3b82f6", href: "/rfq?status=quoted" },
            { label: rfqStatusLabel("accepted", "buyer"), value: rfqs.accepted, color: "#10b981", href: "/rfq?status=accepted" },
            ...(rfqs.closed > 0 ? [{ label: "Closed", value: rfqs.closed, color: "#9ca3af", href: "/rfq" }] : []),
          ]}
        />
      </div>
      <div className="md:pl-5">
        <Link href="/wallet" className="flex items-center gap-1.5 text-sm font-semibold text-gray-900 hover:text-[#CC1414]">
          <Wallet className="h-4 w-4 text-[#CC1414]" /> My Wallet
        </Link>
        <dl className="mt-3 grid grid-cols-2 gap-3">
          <div className="rounded-lg bg-emerald-50 px-3 py-2">
            <dt className="text-[11px] text-emerald-700">Cash balance</dt>
            <dd className="truncate text-base font-bold text-gray-900">{fmtINR(wallet.cash_balance)}</dd>
          </div>
          <div className="rounded-lg bg-blue-50 px-3 py-2">
            <dt className="text-[11px] text-blue-700">Credit available</dt>
            <dd className="truncate text-base font-bold text-gray-900">{fmtINR(wallet.credit_balance)}</dd>
          </div>
        </dl>
        <p className="mt-2 text-[11px] text-gray-500">
          Used to pay for orders.{" "}
          {wallet.credit_balance > 0 ? (
            <Link href="/wallet" className="font-medium text-[#CC1414] hover:underline">See wallet</Link>
          ) : (
            <Link href="/credit-request" className="font-medium text-[#CC1414] hover:underline">Ask for credit</Link>
          )}
        </p>
      </div>
    </div>
  );
}

/** "100 MT", "12.5 MT"; null when the seller has not said. */
function qty(value: string | null, unit: string): string {
  if (value === null || value === "") return "—";
  const n = Number(value);
  return `${formatNumber(value, Number.isInteger(n) ? 0 : 2)} ${unit}`;
}

function dispatchIn(days: number | null): string {
  if (days === null) return "—";
  if (days === 0) return "Same day";
  return `${days} day${days === 1 ? "" : "s"}`;
}

const WATCH_STEPS = [
  { icon: Search, title: "Find a product", text: "Search or browse the catalog." },
  { icon: Bookmark, title: "Tap the bookmark", text: "It sits next to the product name." },
  { icon: BellRing, title: "Get price alerts", text: "We tell you when the price changes." },
];

/**
 * Saved products, in plain words: name, today's price per unit, and a tap to
 * open the exact listing that was saved. When nothing is saved yet it explains
 * the idea in one line and three steps, and offers products the buyer has
 * already ordered or asked about, one tap away.
 */
function WatchlistCard({
  items,
  suggestions,
  token,
  onChanged,
}: {
  items: ApiWatchlistItem[];
  suggestions: Suggestion[];
  token: string | null;
  /** Re-reads the list after a removal, so the next saved product moves up. */
  onChanged: () => void;
}) {
  const [removing, setRemoving] = useState<ApiWatchlistItem | null>(null);
  const [busy, setBusy] = useState(false);

  async function confirmRemove() {
    if (!removing || !token) return;
    setBusy(true);
    try {
      const res = await customerApi.removeWatchlist(token, removing.id);
      toast.success(res.message || "Removed from watchlist.");
      setRemoving(null);
      onChanged();
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Could not remove it. Please try again.");
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="rounded-xl bg-white p-4 shadow-sm ring-1 ring-gray-100">
      <div className="mb-3 flex items-start justify-between gap-3">
        <div className="min-w-0">
          <h2 className="flex items-center gap-1.5 text-base font-semibold text-gray-900">
            <Bookmark className="h-4 w-4 text-[#CC1414]" /> My Watchlist
          </h2>
          {items.length > 0 && <p className="text-xs text-gray-500">Today&apos;s Biznie price and terms for the products you saved.</p>}
        </div>
        {items.length > 0 && (
          <Link href="/watchlist" className="flex shrink-0 items-center gap-1 text-xs text-[#CC1414] hover:underline">
            View all <ArrowRight className="h-3 w-3" />
          </Link>
        )}
      </div>

      {items.length === 0 ? (
        <div className="rounded-xl border border-dashed border-red-200 bg-gradient-to-b from-red-50/70 to-white px-4 py-8 text-center sm:px-8">
          <div className="relative mx-auto flex h-14 w-14 items-center justify-center rounded-2xl bg-white shadow-sm ring-1 ring-red-100">
            <Bookmark className="h-7 w-7 text-[#CC1414]" />
            <span className="absolute -right-2 -top-2 flex h-6 w-6 items-center justify-center rounded-full bg-[#CC1414] text-white ring-2 ring-white">
              <BellRing className="h-3.5 w-3.5" />
            </span>
          </div>
          <h3 className="mt-4 text-base font-semibold text-gray-900">Never miss a price change</h3>
          <p className="mx-auto mt-1 max-w-md text-sm text-gray-500">
            Save the products you buy often. We will alert you as soon as their price goes up or down.
          </p>

          <ol className="mx-auto mt-6 grid max-w-3xl grid-cols-1 gap-3 sm:grid-cols-3">
            {WATCH_STEPS.map(({ icon: Icon, title, text }, i) => (
              <li key={title} className="flex items-center gap-3 rounded-xl bg-white p-3 text-left shadow-sm ring-1 ring-gray-100 sm:flex-col sm:p-4 sm:text-center">
                <span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-red-50 text-[#CC1414]">
                  <Icon className="h-5 w-5" />
                </span>
                <span className="min-w-0">
                  <span className="block text-[10px] font-semibold uppercase tracking-wider text-[#CC1414]">Step {i + 1}</span>
                  <span className="block text-sm font-semibold text-gray-900">{title}</span>
                  <span className="block text-xs text-gray-500">{text}</span>
                </span>
              </li>
            ))}
          </ol>

          <Link
            href="/products"
            className="mt-6 inline-flex items-center gap-2 rounded-lg bg-[#CC1414] px-5 py-2.5 text-sm font-semibold text-white shadow-sm transition hover:bg-[#a30f0f]"
          >
            <Search className="h-4 w-4" /> Browse products
          </Link>

          {suggestions.length > 0 && (
            <div className="mt-4 flex flex-wrap items-center justify-center gap-2">
              <span className="text-xs text-gray-500">Or start with what you have bought:</span>
              {suggestions.map((sg) => (
                <Link
                  key={sg.slug}
                  href={`/products/${sg.slug}`}
                  className="inline-flex max-w-full items-center gap-1 rounded-full bg-white px-3 py-1.5 text-xs font-medium text-gray-700 shadow-sm ring-1 ring-gray-200 transition hover:text-[#CC1414] hover:ring-[#CC1414]"
                >
                  <span className="truncate">{sg.name}</span>
                  <ChevronRight className="h-3 w-3 shrink-0" />
                </Link>
              ))}
            </div>
          )}
        </div>
      ) : (
        <ul className="space-y-3">
          {items.map((item) => {
            const product = item.product;
            const offer = item.seller_product;
            const unit = formatUnit(offer?.unit ?? product?.unit?.name);
            const productHref = product?.slug ? `/products/${product.slug}` : "/watchlist";
            // The exact offer shown here, not whichever is cheapest when the page loads.
            const href = offer && product?.slug ? `${productHref}?offer=${offer.id}` : productHref;
            return (
              <li
                key={item.id}
                className="grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 rounded-xl border border-gray-100 p-3 transition hover:border-[#CC1414]/30 hover:shadow-sm xl:grid-cols-[minmax(0,15rem)_minmax(0,1fr)_auto]"
              >
                <div className="flex min-w-0 items-center gap-3">
                  <div className="relative h-14 w-14 shrink-0 overflow-hidden rounded-lg bg-gray-50 ring-1 ring-gray-100">
                    <SafeImage src={product?.thumbnail || "/logo.png"} alt={product?.name ?? "Product"} fill sizes="56px" className="object-cover" />
                  </div>
                  <div className="min-w-0">
                    <Link href={href} className="block truncate text-sm font-semibold text-gray-900 hover:text-[#CC1414]">
                      {product?.name ?? "Product"}
                    </Link>
                    <div className="mt-1 flex flex-wrap items-center gap-1.5">
                      {offer?.sold_by_biznie && (
                        <span className="inline-flex items-center gap-1 rounded bg-emerald-50 px-1.5 py-0.5 text-[10px] font-semibold text-emerald-700">
                          <BadgeCheck className="h-3 w-3" /> Sold by Biznie
                        </span>
                      )}
                      {offer?.brand?.name && (
                        <span className="max-w-full truncate rounded bg-gray-100 px-1.5 py-0.5 text-[10px] font-medium text-gray-600">{offer.brand.name}</span>
                      )}
                    </div>
                    {offer?.price_updated_at && (
                      <p className="mt-0.5 text-[11px] text-gray-400">Price updated {formatRelativeAge(offer.price_updated_at)}</p>
                    )}
                  </div>
                </div>

                {/* Last in the row on wide screens; beside the name otherwise. */}
                <div className="flex shrink-0 items-center gap-1.5 xl:order-last">
                  <Link
                    href={href}
                    className="inline-flex items-center gap-1 rounded-lg border border-[#CC1414] px-3 py-1.5 text-xs font-semibold text-[#CC1414] transition hover:bg-[#CC1414] hover:text-white"
                  >
                    {offer ? "View & buy" : "View"} <ChevronRight className="h-3.5 w-3.5" />
                  </Link>
                  <button
                    type="button"
                    onClick={() => setRemoving(item)}
                    aria-label={`Remove ${product?.name ?? "product"} from watchlist`}
                    title="Remove from watchlist"
                    className="rounded-lg border border-gray-200 p-1.5 text-gray-400 transition hover:border-red-200 hover:bg-red-50 hover:text-[#CC1414]"
                  >
                    <Trash2 className="h-4 w-4" />
                  </button>
                </div>

                {offer ? (
                  <div className="col-span-2 xl:col-span-1">
                    {/* What the seller keeps up to date, as the product page shows it. */}
                    <dl className="grid grid-cols-2 gap-x-4 gap-y-2 sm:grid-cols-3 lg:grid-cols-[repeat(5,minmax(0,1fr))_minmax(0,1.4fr)]">
                      <Figure label={`Ex-Works${offer.city ? ` ${offer.city}` : ""}`}>
                        <span className="font-bold text-[#CC1414]">{fmtINR(offer.ex_works_price)}</span>
                        <span className="text-xs font-normal text-gray-500"> / {unit}</span>
                      </Figure>
                      <Figure label="Base price">{fmtINR(offer.base_price)}</Figure>
                      <Figure label="Available">{qty(offer.quantity, unit)}</Figure>
                      <Figure label="Min. order">{qty(offer.moq, formatUnit(offer.moq_unit ?? unit))}</Figure>
                      <Figure label="Dispatch within">{dispatchIn(offer.load_within)}</Figure>
                      <Figure label="Price valid till">{offer.valid_till ? formatDateTime(offer.valid_till) : "Until changed"}</Figure>
                    </dl>
                    {!offer.is_saved_listing && (
                      <p className="mt-2 text-[11px] text-gray-500">The offer you saved has ended. This is Biznie&apos;s current offer.</p>
                    )}
                  </div>
                ) : (
                  <p className="col-span-2 rounded-lg bg-amber-50 px-3 py-2 text-xs text-amber-800 xl:col-span-1">
                    No live price right now. We will alert you as soon as Biznie lists it again.
                  </p>
                )}
              </li>
            );
          })}
        </ul>
      )}

      <ConfirmDialog
        open={removing !== null}
        title="Remove from your watchlist?"
        description={`${removing?.product?.name ?? "This product"} will be removed and you will stop getting its price alerts. You can save it again any time from the product page.`}
        confirmLabel="Remove"
        cancelLabel="Keep it"
        loading={busy}
        onCancel={() => !busy && setRemoving(null)}
        onConfirm={confirmRemove}
      />
    </div>
  );
}

export default function BuyerDashboard({ title = "Dashboard" }: { title?: string }) {
  const { token, ready } = useToken();
  const [data, setData] = useState<ApiDashboard | null>(null);
  const [watchlist, setWatchlist] = useState<ApiWatchlistItem[]>([]);
  const [err, setErr] = useState<string | null>(null);

  useEffect(() => {
    if (!ready || !token) return;
    Promise.all([
      customerApi.dashboard(token),
      customerApi.watchlist(token, { page: 1, perPage: 6 }),
    ])
      .then(([dashboard, watchlistRes]) => {
        setData(dashboard);
        setWatchlist(watchlistRes.data);
      })
      .catch((e) => setErr(e.message));
  }, [ready, token]);

  const reloadWatchlist = useCallback(() => {
    if (!token) return;
    customerApi
      .watchlist(token, { page: 1, perPage: 6 })
      .then((res) => setWatchlist(res.data))
      .catch(() => {
        /* The row is already gone on the server; the next visit shows the rest. */
      });
  }, [token]);

  if (!ready) {
    return (
      <div className="rounded-xl bg-white p-10 shadow-sm ring-1 ring-gray-100">
        <Loader label="Loading dashboard…" />
      </div>
    );
  }
  if (err) return <div className="rounded-xl bg-red-50 p-6 text-red-700 ring-1 ring-red-100">{err}</div>;
  if (!data) {
    return (
      <div className="rounded-xl bg-white p-10 shadow-sm ring-1 ring-gray-100">
        <Loader label="Loading dashboard…" />
      </div>
    );
  }

  const tiles = data.tiles;
  const suggestions: Suggestion[] = [];
  for (const p of [...data.recent_orders.map((o) => o.product), ...data.recent_enquiries.map((e) => e.product)]) {
    if (p?.slug && !suggestions.some((sg) => sg.slug === p.slug)) suggestions.push({ slug: p.slug, name: p.name });
    if (suggestions.length === 3) break;
  }

  return (
    <div className="space-y-6">
      <header className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <h1 className="text-xl font-bold text-gray-900">{title}</h1>
        <div className="flex flex-wrap gap-2">
          <Link href="/rfq/new" className="inline-flex items-center gap-1.5 rounded-lg border border-[#CC1414] px-3 py-1.5 text-sm font-medium text-[#CC1414] hover:bg-red-50">
            <PlusCircle className="h-4 w-4" /> Post Requirement
          </Link>
          <Link href="/rfq" className="inline-flex items-center gap-1.5 rounded-lg bg-[#CC1414] px-3 py-1.5 text-sm font-medium text-white hover:bg-[#a30f0f]">
            My Requirements
          </Link>
        </div>
      </header>

      {/* Canonical tiles (B25): each row adds up to the total beside it. */}
      <div className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-6">
        <StatCard label="Open RFQs" value={tiles?.rfqs.open ?? 0} icon={Clock} tone="bg-amber-50 text-amber-600" href="/rfq?status=rfq_open" />
        <StatCard label="Quotes received" value={tiles?.rfqs.quoted ?? 0} icon={ShoppingBag} tone="bg-blue-50 text-blue-600" href="/rfq?status=quoted" />
        <StatCard label="In progress" value={tiles?.orders.in_progress ?? 0} icon={Clock} tone="bg-orange-50 text-orange-600" href="/orders?status=in_progress" />
        <StatCard label="Dispatched" value={tiles?.orders.dispatched ?? 0} icon={ShoppingBag} tone="bg-indigo-50 text-indigo-600" href="/orders?status=dispatched" />
        <StatCard label="Delivered" value={tiles?.orders.delivered ?? 0} icon={CheckCircle2} tone="bg-green-50 text-green-600" href="/orders?status=delivered" />
        <StatCard label="Payment due" value={fmtINR(tiles?.orders.payment_due_amount ?? 0)} icon={IndianRupee} tone="bg-red-50 text-red-600" href="/orders" />
      </div>
      {/* Each total with its parts (B25: the parts add up to the total). */}
      {tiles && <SummaryCard tiles={tiles} wallet={data.wallet} />}

      {/* Saved products lead, as My Products does on the seller side. */}
      <WatchlistCard items={watchlist} suggestions={suggestions} token={token} onChanged={reloadWatchlist} />

      <section className="grid grid-cols-1 gap-5 lg:grid-cols-2">
        <div className="rounded-xl bg-white p-4 shadow-sm ring-1 ring-gray-100">
          <div className="mb-3 flex items-center justify-between">
            <h2 className="text-base font-semibold text-gray-900">Recent Orders</h2>
            <Link href="/orders" className="flex items-center gap-1 text-xs text-[#CC1414] hover:underline">View all <ArrowRight className="h-3 w-3" /></Link>
          </div>
          {data.recent_orders.length === 0 ? (
            <p className="py-6 text-center text-sm text-gray-500">No orders yet.</p>
          ) : (
            <ul className="divide-y divide-gray-100">
              {data.recent_orders.map((o) => (
                <li key={o.id} className="flex items-center justify-between py-3">
                  <div className="min-w-0">
                    <Link href={`/orders/${o.id}`} className="block truncate text-sm font-medium text-gray-900 hover:text-[#CC1414]">
                      {o.product?.name ?? "—"}
                    </Link>
                    <div className="text-xs text-gray-500">{o.order_id ?? o.unique_id} · {o.status_label ?? o.status}</div>
                  </div>
                  <div className="text-sm font-semibold text-gray-900">{fmtINR(o.final_amount || o.total_amount)}</div>
                </li>
              ))}
            </ul>
          )}
        </div>

        <div className="rounded-xl bg-white p-4 shadow-sm ring-1 ring-gray-100">
          <div className="mb-3 flex items-center justify-between">
            <h2 className="text-base font-semibold text-gray-900">Recent Enquiries</h2>
            <Link href="/rfq" className="flex items-center gap-1 text-xs text-[#CC1414] hover:underline">View all <ArrowRight className="h-3 w-3" /></Link>
          </div>
          {data.recent_enquiries.length === 0 ? (
            <p className="py-6 text-center text-sm text-gray-500">No enquiries yet.</p>
          ) : (
            <ul className="divide-y divide-gray-100">
              {data.recent_enquiries.map((e) => (
                <li key={e.id} className="flex items-center justify-between py-3">
                  <div className="min-w-0">
                    <Link href={`/rfq/${e.id}`} className="block truncate text-sm font-medium text-gray-900 hover:text-[#CC1414]">
                      {e.product?.name ?? "—"}
                    </Link>
                    <div className="text-xs text-gray-500">{e.unique_id} · {e.status_label ?? e.status}</div>
                  </div>
                  <FileText className="h-4 w-4 text-gray-400" />
                </li>
              ))}
            </ul>
          )}
        </div>
      </section>
    </div>
  );
}
