"use client";

import * as React from "react";

import { useFormContext, useWatch } from "react-hook-form";

import type { FilterOption } from "@/app/customer/_lib/customer-asset-filter-options";
import type { StockFormOptions } from "@/app/customer/[tenant]/stock/_lib/stock-form-options";
import { Badge } from "@/components/ui/badge";
import { formatAmount } from "@/lib/format/numbers";
import { YII_TRANSACTION } from "@/config/yii-transaction";
import { cn } from "@/lib/utils";

export const PURCHASE_TRANSACTION_TYPE = YII_TRANSACTION.purchase;

export function parseAmount(value: unknown) {
  if (typeof value === "number" && Number.isFinite(value)) return value;
  if (typeof value === "string" && value.trim() !== "") {
    const parsed = Number(value.replace(/,/g, ""));
    return Number.isFinite(parsed) ? parsed : 0;
  }
  return 0;
}

/** Shared by the transaction summary panels; renders an em dash for unset fields. */
export function formatMoney(value: number | undefined) {
  if (value === undefined || Number.isNaN(value)) return "—";
  return formatAmount(value);
}

export function labelForOption(options: FilterOption[], value: string | undefined) {
  if (!value) return "";
  return options.find((option) => option.value === value)?.label ?? value;
}

export function SummaryRow({ label, value, mono }: { label: string; value: string; mono?: boolean }) {
  return (
    <div className="flex items-baseline justify-between gap-4 py-2">
      <span className="text-muted-foreground text-xs">{label}</span>
      <span
        className={cn(
          "text-right font-medium text-foreground text-sm",
          mono && "font-mono text-[0.8125rem] tracking-tight tabular-nums",
        )}
      >
        {value || "—"}
      </span>
    </div>
  );
}

type AmountSummaryFormValues = {
  ticker?: string;
  isin?: string;
  quantity?: number | string;
  price?: number | string;
  transaction?: string;
  commission?: number | string;
  b_1?: string;
  b_2?: string;
  bank?: string;
  t_date?: string;
  p_date?: string;
  m_date?: string;
  c_date?: string;
  r_no?: string;
  p_currency?: string;
  a_type?: string;
  t_o_o?: string;
  o_s?: string;
  execution_type?: string;
  amount?: number | string;
};

type SummaryFormOptions = Pick<
  StockFormOptions,
  "banks" | "transactionTypes" | "executionTypes" | "currencies" | "assetTypes"
> & {
  optionTypes?: FilterOption[];
  optionStyles?: FilterOption[];
};

type TransactionAmountSummarySidebarProps = {
  formOptions: SummaryFormOptions;
  headlineField?: keyof AmountSummaryFormValues;
  subheadlineField?: keyof AmountSummaryFormValues;
  showEffectiveDate?: boolean;
  effectiveDateField?: keyof AmountSummaryFormValues;
  effectiveDateLabel?: string;
  showExecutionBadge?: boolean;
  secondaryBadgeField?: keyof AmountSummaryFormValues;
  secondaryBadgeOptions?: FilterOption[];
  netMode?: "subtract" | "add";
  grossLabel?: string;
  netLabel?: string;
  useMaturityGrossLabel?: boolean;
};

const MATURITY_EXECUTION_TYPE = "1477";

export function TransactionAmountSummarySidebar({
  formOptions,
  headlineField = "ticker",
  subheadlineField = "a_type",
  showEffectiveDate = true,
  effectiveDateField = "p_date",
  effectiveDateLabel = "Effective date",
  showExecutionBadge = true,
  secondaryBadgeField,
  secondaryBadgeOptions = [],
  netMode = "subtract",
  grossLabel,
  netLabel = "Net Amount",
  useMaturityGrossLabel = false,
}: TransactionAmountSummarySidebarProps) {
  const { control, setValue } = useFormContext<AmountSummaryFormValues>();
  const watched = useWatch({ control });

  const qty = parseAmount(watched.quantity);
  const px = parseAmount(watched.price);
  const signedQty = watched.transaction === PURCHASE_TRANSACTION_TYPE ? -Math.abs(qty) : qty;
  const gross = px * signedQty;
  const commissionNum = parseAmount(watched.commission);
  const chargesNum = parseAmount(watched.b_1);
  const taxNum = parseAmount(watched.b_2);
  const fees = commissionNum + chargesNum + taxNum;
  const net = netMode === "add" ? gross + fees : gross - fees;

  React.useEffect(() => {
    const nextAmount = Number(gross.toFixed(8));
    if (typeof watched.amount === "string") {
      setValue("amount", String(nextAmount), { shouldValidate: false, shouldDirty: false });
    } else {
      setValue("amount", nextAmount, { shouldValidate: false, shouldDirty: false });
    }
  }, [gross, setValue, watched.amount]);

  const headline = String(watched[headlineField] ?? "").trim();
  const subheadlineValue = watched[subheadlineField];
  const subheadline =
    subheadlineField === "a_type"
      ? labelForOption(formOptions.assetTypes, String(subheadlineValue ?? ""))
      : subheadlineField === "t_o_o"
        ? labelForOption(formOptions.optionTypes ?? [], String(subheadlineValue ?? ""))
        : subheadlineField === "o_s"
          ? labelForOption(formOptions.optionStyles ?? [], String(subheadlineValue ?? ""))
          : String(subheadlineValue ?? "").trim();

  const bankLabel = labelForOption(formOptions.banks, watched.bank) || watched.bank?.trim();
  const transactionLabel = labelForOption(formOptions.transactionTypes, watched.transaction);
  const executionLabel = labelForOption(formOptions.executionTypes, watched.execution_type);
  const secondaryBadgeValue = secondaryBadgeField ? watched[secondaryBadgeField] : undefined;
  const secondaryBadgeLabel = secondaryBadgeField
    ? labelForOption(secondaryBadgeOptions, String(secondaryBadgeValue ?? ""))
    : "";
  const currencyLabel =
    labelForOption(formOptions.currencies, watched.p_currency) || watched.p_currency?.trim() || "—";
  const effectiveDateValue = String(watched[effectiveDateField] ?? "").trim();
  const resolvedGrossLabel =
    grossLabel ??
    (useMaturityGrossLabel && watched.execution_type === MATURITY_EXECUTION_TYPE
      ? "Max Exposure"
      : "Gross Amount");

  return (
    <aside className="xl:sticky xl:top-6 xl:self-start">
      <div className="overflow-hidden rounded-xl border border-border/60 bg-card shadow-sm">
        <div className="border-b border-border/50 bg-muted/25 px-5 py-4">
          <div className="flex items-center justify-between gap-2">
            <p className="font-medium text-muted-foreground text-[11px] uppercase tracking-wider">
              Live preview
            </p>
            <span className="relative flex size-2">
              <span className="absolute inline-flex size-full animate-ping rounded-full bg-emerald-400 opacity-60" />
              <span className="relative inline-flex size-2 rounded-full bg-emerald-500" />
            </span>
          </div>
          <p className="mt-3 font-mono font-semibold text-2xl tracking-tight">{headline || "—"}</p>
          <p className="mt-1.5 text-muted-foreground text-sm leading-snug">
            {subheadline || "Instrument details pending"}
          </p>
          <div className="mt-3 flex flex-wrap gap-1.5">
            {transactionLabel ? (
              <Badge variant="secondary" className="font-normal text-[11px]">
                {transactionLabel}
              </Badge>
            ) : null}
            {showExecutionBadge && executionLabel ? (
              <Badge variant="outline" className="font-normal text-[11px]">
                {executionLabel}
              </Badge>
            ) : null}
            {secondaryBadgeLabel ? (
              <Badge variant="outline" className="font-normal text-[11px]">
                {secondaryBadgeLabel}
              </Badge>
            ) : null}
          </div>
        </div>

        <div className="px-5 py-4">
          <SummaryRow label="Bank" value={bankLabel || "—"} />
          <SummaryRow label="Trade date" value={watched.t_date || "—"} mono />
          {showEffectiveDate ? (
            <SummaryRow label={effectiveDateLabel} value={effectiveDateValue || "—"} mono />
          ) : null}
          <SummaryRow label="Reference" value={watched.r_no || "—"} mono />
        </div>

        <div className="border-t border-border/50 px-5 py-4">
          <SummaryRow label={resolvedGrossLabel} value={formatMoney(gross)} mono />
          <SummaryRow label="Commission" value={formatMoney(commissionNum)} mono />
          <SummaryRow label="Charges" value={formatMoney(chargesNum)} mono />
          <SummaryRow label="Tax" value={formatMoney(taxNum)} mono />
        </div>

        <div className="border-t border-border/50 bg-gradient-to-br from-primary/5 via-transparent to-transparent px-5 py-5">
          <p className="text-muted-foreground text-xs uppercase tracking-wider">{netLabel}</p>
          <p className="mt-2 font-mono font-semibold text-3xl tracking-tight tabular-nums">
            {formatMoney(net)}
          </p>
          <p className="mt-0.5 font-medium text-muted-foreground text-sm">{currencyLabel}</p>
          <div className="mt-5 grid grid-cols-2 gap-3">
            <div className="rounded-lg border border-border/50 bg-muted/20 px-3 py-2.5">
              <p className="text-muted-foreground text-[11px] uppercase tracking-wide">Quantity</p>
              <p className="mt-1 font-mono font-medium text-sm tabular-nums">
                {formatMoney(parseAmount(watched.quantity))}
              </p>
            </div>
            <div className="rounded-lg border border-border/50 bg-muted/20 px-3 py-2.5">
              <p className="text-muted-foreground text-[11px] uppercase tracking-wide">Price</p>
              <p className="mt-1 font-mono font-medium text-sm tabular-nums">
                {formatMoney(parseAmount(watched.price))}
              </p>
            </div>
          </div>
        </div>
      </div>
    </aside>
  );
}
