import { formatAmount } from "@/lib/pricing/forPrice";

/**
 * Renders the variant / quality / packaging selection a buyer attached to an
 * RFQ from the product detail page.
 *
 * The three columns are JSON blobs on `product_enquiries`, typed `unknown` all
 * the way through the API layer, and their shape has drifted: rows written by
 * the legacy app carry no `ex_price`, and older ones may hold a bare string.
 * Everything below therefore narrows rather than casts, and a row it cannot
 * read is skipped instead of throwing on a page whose real job is the quote.
 */

type Props = {
  variation: unknown;
  quality: unknown;
  packaging: unknown;
  /** Unit label for the quantity column, e.g. "Ton". */
  unit?: string | null;
  /** Content only, for a caller that supplies its own card and heading. */
  bare?: boolean;
  /**
   * Leave out the buyer's indicative prices. The seller's bid page does: those
   * figures come from Biznie's own listing, and a bidding seller should price
   * the requirement, not anchor on a rival's rate.
   */
  hidePrices?: boolean;
  /** Shown instead of nothing when there is no size, quality or packaging. */
  empty?: React.ReactNode;
};

type VariationValue = { name?: unknown; value?: unknown; unit?: { short_name?: unknown } | null };

type ParsedRow = {
  key: string;
  label: string;
  /** No size name was stored for this row (RFQs raised before sizes were kept). */
  unnamed: boolean;
  detail: string | null;
  quantity: string | null;
  exPrice: number | null;
  lineTotal: number | null;
};

function text(value: unknown): string | null {
  if (typeof value === "string" && value.trim() !== "") return value;
  if (typeof value === "number" && Number.isFinite(value)) return String(value);
  return null;
}

function numeric(value: unknown): number | null {
  const parsed = Number(value);
  return Number.isFinite(parsed) && parsed !== 0 ? parsed : null;
}

function valueLabel(entry: VariationValue | undefined): string | null {
  if (!entry) return null;
  const value = text(entry.value);
  if (!value) return null;
  const short = text(entry.unit?.short_name);
  return short ? `${value} ${short}` : value;
}

function parseRows(variation: unknown): ParsedRow[] {
  if (!Array.isArray(variation)) return [];

  return variation.flatMap((raw, index): ParsedRow[] => {
    if (typeof raw === "string") {
      return [{ key: `s-${index}`, label: raw, unnamed: false, detail: null, quantity: null, exPrice: null, lineTotal: null }];
    }
    if (!raw || typeof raw !== "object") return [];

    const row = raw as Record<string, unknown>;
    const values = Array.isArray(row.value) ? (row.value as VariationValue[]) : [];
    const named = valueLabel(values[0]) ?? text(row.name);

    return [
      {
        // Row ids are not guaranteed unique (older rows repeat them or carry 0).
        key: `${text(row.id) ?? "row"}-${index}`,
        label: named ?? `Size ${index + 1}`,
        unnamed: named === null,
        detail: values.slice(1).map(valueLabel).filter(Boolean).join(" · ") || null,
        quantity: text(row.quantity),
        exPrice: numeric(row.ex_price),
        lineTotal: numeric(row.line_total),
      },
    ];
  });
}

/** Sum of the size rows' quantities (0 when there are none). */
export function variationTotal(variation: unknown): number {
  return parseRows(variation).reduce((sum, row) => sum + (Number(row.quantity) || 0), 0);
}

/** `{ name, price }` written by the builder; older rows may be a plain string. */
function parseNamed(raw: unknown, priceKey: string): { name: string; price: number | null } | null {
  if (typeof raw === "string" && raw.trim() !== "") return { name: raw, price: null };
  if (!raw || typeof raw !== "object") return null;

  const obj = raw as Record<string, unknown>;
  const name = text(obj.name);
  if (!name) return null;
  return { name, price: numeric(obj[priceKey]) };
}

export default function RequirementSpec({ variation, quality, packaging, unit, bare = false, hidePrices = false, empty = null }: Props) {
  const rows = parseRows(variation);
  const qualityOption = parseNamed(quality, "price");
  const packagingOption = parseNamed(packaging, "charge");

  if (rows.length === 0 && !qualityOption && !packagingOption) return <>{empty}</>;

  const showPrices = !hidePrices && rows.some((row) => row.exPrice !== null || row.lineTotal !== null);
  const totalQty = rows.reduce((sum, row) => sum + (Number(row.quantity) || 0), 0);
  const totalValue = rows.reduce((sum, row) => sum + (row.lineTotal ?? 0), 0);
  const unnamed = rows.length > 0 && rows.every((row) => row.unnamed);

  return (
    <div className={bare ? "" : "rounded-xl bg-white p-5 shadow-sm ring-1 ring-gray-100"}>
      {!bare && (
        <h2 className="mb-3 text-sm font-semibold uppercase tracking-wide text-gray-500">
          Requirement
        </h2>
      )}

      {(qualityOption || packagingOption) && (
        <div className="mb-3 flex flex-wrap gap-2">
          {qualityOption && (
            <span className="rounded-md bg-gray-100 px-2.5 py-1 text-xs font-medium text-gray-700">
              Quality: {qualityOption.name}
              {qualityOption.price !== null && ` (${formatAmount(qualityOption.price)})`}
            </span>
          )}
          {packagingOption && (
            <span className="rounded-md bg-gray-100 px-2.5 py-1 text-xs font-medium text-gray-700">
              Packaging: {packagingOption.name}
              {packagingOption.price !== null && ` (${formatAmount(packagingOption.price)})`}
            </span>
          )}
        </div>
      )}

      {rows.length > 0 && (
        <div className="overflow-x-auto">
          <table className={`w-full text-left text-xs ${showPrices ? "min-w-[360px]" : ""}`}>
            <thead>
              <tr className="border-b border-gray-200 text-gray-500">
                <th className="py-2 pr-3 font-medium">Size</th>
                <th className="py-2 pr-3 font-medium">Quantity{unit ? ` (${unit})` : ""}</th>
                {showPrices && <th className="py-2 pr-3 font-medium">Ex Price</th>}
                {showPrices && <th className="py-2 font-medium">Total</th>}
              </tr>
            </thead>
            <tbody>
              {rows.map((row) => (
                <tr key={row.key} className="border-b border-gray-100 last:border-0">
                  <td className="py-2 pr-3 text-gray-900">
                    {row.label}
                    {row.detail && <span className="ml-1 text-[11px] text-gray-400">({row.detail})</span>}
                  </td>
                  <td className="py-2 pr-3 text-gray-700">{row.quantity ?? "—"}</td>
                  {showPrices && (
                    <td className="py-2 pr-3 text-gray-700">
                      {row.exPrice !== null ? formatAmount(row.exPrice) : "—"}
                    </td>
                  )}
                  {showPrices && (
                    <td className="py-2 font-semibold text-gray-900">
                      {row.lineTotal !== null ? formatAmount(row.lineTotal) : "—"}
                    </td>
                  )}
                </tr>
              ))}
            </tbody>
            {totalQty > 0 && (
              <tfoot>
                <tr>
                  <td className="pt-2 text-xs font-medium text-gray-500">Total</td>
                  <td className="pt-2 text-xs font-medium text-gray-700">
                    {totalQty}
                    {unit ? ` ${unit}` : ""}
                  </td>
                  {showPrices && <td />}
                  {showPrices && (
                    <td className="pt-2 text-sm font-bold text-gray-900">
                      {totalValue > 0 ? formatAmount(totalValue) : "—"}
                    </td>
                  )}
                </tr>
              </tfoot>
            )}
          </table>
        </div>
      )}

      {unnamed && (
        <p className="mt-2 text-[11px] text-gray-400">
          Size names were not saved for this RFQ; the quantities are as the buyer entered them.
        </p>
      )}

      {showPrices && (
        <p className="mt-2 text-[11px] text-gray-400">
          Buyer&apos;s indicative ex-works figures at the time of enquiry.
        </p>
      )}
    </div>
  );
}
