import { memo, useEffect, useMemo, useState } from "react";
import { EquityStock } from "@/components/datatable/liststock/columns";
import { RecordModal, formatDisplay, formatNumeric } from "@/components/cash/RecordModal";
import { formatNumber, parseNumber } from "@/lib/common";
import { logger } from "@/lib/logger";
import { useRouter } from "next/navigation";

interface EquityDerivativesModalProps {
  record: EquityStock;
  onClose: () => void;
  onEdit: () => void;
  onDelete?: () => void;
}

export const EquityDerivativesModal = memo(({
  record,
  onClose,
  onEdit,
  onDelete,
}: EquityDerivativesModalProps) => {
  const isIsoDate = (value: string) => /^\d{4}-\d{2}-\d{2}$/.test(value);
  const router = useRouter();
  const [scheduleRows, setScheduleRows] = useState<
    Array<{
      serial: number;
      startDate: string;
      quantity: number;
      strike: number;
      knockLabel: string;
      amount: number;
      quantity2x: number;
      amount2x: number;
      pendingExposure: number;
    }>
  >([]);
  const [maxExposureBase, setMaxExposureBase] = useState(0);

  const isAccumulator = useMemo(() => {
    const type = (record.f_type || "").toLowerCase();
    return type.includes("accumulator");
  }, [record.f_type]);

  useEffect(() => {
    if (!isAccumulator || !record.id) {
      setScheduleRows([]);
      return;
    }

    let cancelled = false;

    const buildSchedule = async () => {
      try {
        const response = await fetch(`/api/equity/derivatives/accumulator/${encodeURIComponent(record.id)}`, {
          credentials: "include",
          cache: "no-store",
        });
        if (!response.ok) {
          throw new Error(`Failed to load accumulator details (${response.status})`);
        }
        const payload = await response.json();
        const data = (payload?.data?.attributes || payload?.data || {}) as Record<string, unknown>;

        const periods = Math.max(0, Math.trunc(parseNumber(String(data.duration || "0"))));
        if (periods <= 0) {
          if (!cancelled) setScheduleRows([]);
          return;
        }

        const strike = parseNumber(String(data.price || "0"));
        const totalQuantity = parseNumber(String(data.quantity || "0"));
        const maxExposure = parseNumber(String(data.amount || "0"));
        const quantityPerPeriod = periods > 0 ? totalQuantity / periods : 0;
        const isSaleTxn = String(data.t_o_t || "") === "1473";
        const signedQuantityPerPeriod = isSaleTxn ? quantityPerPeriod * -1 : quantityPerPeriod;
        const durationStepDays = Math.max(1, Math.trunc(parseNumber(String(data.duration_unit || "1"))));
        const baseDateStr = String(data.c_date || "");
        const baseDate = baseDateStr ? new Date(baseDateStr) : null;
        const knockBase = String(data.knock || data.knock_label || "-");
        const knockLabel = String(data.knock_t || "") === "1" ? `${knockBase}%` : knockBase;

        let runningExposure = maxExposure;
        const rows = Array.from({ length: periods }, (_, index) => {
          const rowAmount = signedQuantityPerPeriod * strike;
          runningExposure = runningExposure - rowAmount;
          const rowDate = baseDate
            ? new Date(baseDate.getTime() + index * durationStepDays * 24 * 60 * 60 * 1000)
            : null;
          const startDate = rowDate ? rowDate.toISOString().slice(0, 10) : "";

          return {
            serial: index + 1,
            startDate,
            quantity: signedQuantityPerPeriod,
            strike,
            knockLabel,
            amount: rowAmount,
            quantity2x: signedQuantityPerPeriod * 2,
            amount2x: rowAmount * 2,
            pendingExposure: runningExposure,
          };
        });

        if (!cancelled) {
          setMaxExposureBase(maxExposure);
          setScheduleRows(rows);
        }
      } catch (error) {
        logger.warn("Failed to load accumulator schedule rows in modal", undefined, { error, id: record.id });
        if (!cancelled) setScheduleRows([]);
      }
    };

    buildSchedule();
    return () => {
      cancelled = true;
    };
  }, [isAccumulator, record.id]);

  const recalculateRows = (
    rows: Array<{
      serial: number;
      startDate: string;
      quantity: number;
      strike: number;
      knockLabel: string;
      amount: number;
      quantity2x: number;
      amount2x: number;
      pendingExposure: number;
    }>
  ) => {
    let runningExposure = maxExposureBase;
    return rows.map((row) => {
      const amount = row.quantity * row.strike;
      runningExposure -= amount;
      return {
        ...row,
        amount,
        quantity2x: row.quantity * 2,
        amount2x: amount * 2,
        pendingExposure: runningExposure,
      };
    });
  };

  const handleQuantityChange = (index: number, value: string) => {
    const parsed = parseNumber(value);
    setScheduleRows((prev) => {
      const next = [...prev];
      if (!next[index]) return prev;
      next[index] = {
        ...next[index],
        quantity: parsed,
      };
      return recalculateRows(next);
    });
  };

  const handleDateChange = (index: number, value: string) => {
    setScheduleRows((prev) => {
      const next = [...prev];
      if (!next[index]) return prev;
      next[index] = {
        ...next[index],
        startDate: value,
      };
      return next;
    });
  };

  const amountColor = useMemo(() => {
    if (!record.amount) return "";
    const normalized = record.amount.replace(/,/g, "").trim();
    const parsed = Number.parseFloat(normalized);
    if (Number.isFinite(parsed)) {
      return parsed >= 0 ? "text-green-600" : "text-red-600";
    }
    return "";
  }, [record.amount]);

  const subtitle = useMemo(
    () =>
      record.ticker
        ? `${record.ticker}${record.isin ? ` (${record.isin})` : ""}`
        : "—",
    [record.ticker, record.isin]
  );

  const metrics = useMemo(
    () => [
      {
        label: "Quantity",
        value: formatNumeric(record.quantity),
      },
      {
        label: "Price / Security",
        value: formatNumeric(record.price),
      },
      {
        label: "Total Amount",
        value: formatNumeric(record.amount),
        colorClass: amountColor,
      },
    ],
    [record.quantity, record.price, record.amount, amountColor]
  );

  const detailItems = useMemo(
    () => [
      { label: "Placement Date", value: formatDisplay(record.t_date) },
      { label: "Bank", value: formatDisplay(record.bank_id) },
      { label: "Execution Type", value: formatDisplay(record.e_t) },
      { label: "Transaction Type", value: formatDisplay(record.t_o_t) },
      { label: "Purchase Currency", value: formatDisplay(record.purchase_currency_code) },
      { label: "Type", value: formatDisplay(record.f_type) },
    ],
    [record.t_date, record.bank_id, record.e_t, record.t_o_t, record.purchase_currency_code, record.f_type]
  );

  const scheduleTable = useMemo(() => {
    if (!isAccumulator || scheduleRows.length === 0) return null;

    const totals = scheduleRows.reduce(
      (acc, row) => {
        acc.quantity += row.quantity;
        acc.amount += row.amount;
        acc.quantity2x += row.quantity2x;
        acc.amount2x += row.amount2x;
        return acc;
      },
      { quantity: 0, amount: 0, quantity2x: 0, amount2x: 0 }
    );

    return (
      <div className="rounded-lg border border-slate-200 overflow-hidden">
        <div className="border-b border-slate-200 bg-slate-50 px-4 py-2">
          <h4 className="text-xs font-semibold uppercase tracking-wide text-slate-600">Accumulator Schedule</h4>
        </div>
        <div className="overflow-x-auto">
          <table className="min-w-full divide-y divide-slate-200 text-xs">
            <thead className="bg-slate-50">
              <tr>
                <th className="px-2 py-2 text-left font-semibold text-slate-600">Serial</th>
                <th className="px-2 py-2 text-left font-semibold text-slate-600">Start Date</th>
                <th className="px-2 py-2 text-left font-semibold text-slate-600">Underlying</th>
                <th className="px-2 py-2 text-right font-semibold text-slate-600">Qty</th>
                <th className="px-2 py-2 text-right font-semibold text-slate-600">Strike</th>
                <th className="px-2 py-2 text-right font-semibold text-slate-600">Knock</th>
                <th className="px-2 py-2 text-right font-semibold text-slate-600">Amount</th>
                <th className="px-2 py-2 text-right font-semibold text-slate-600">Qty (2X)</th>
                <th className="px-2 py-2 text-right font-semibold text-slate-600">Amount (2X)</th>
                <th className="px-2 py-2 text-right font-semibold text-slate-600">Pending Exposure</th>
                <th className="px-2 py-2 text-right font-semibold text-slate-600">Action</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-slate-100">
              {scheduleRows.map((row, index) => (
                <tr key={`acc-schedule-${index}`} className="hover:bg-slate-50/70">
                  <td className="px-2 py-2 text-slate-700">{row.serial}</td>
                  <td className="px-2 py-2 text-slate-700">
                    <input
                      type="date"
                      value={isIsoDate(row.startDate) ? row.startDate : ""}
                      onChange={(event) => handleDateChange(index, event.target.value)}
                      onClick={(event) => {
                        const input = event.currentTarget as HTMLInputElement & {
                          showPicker?: () => void;
                        };
                        try {
                          input.showPicker?.();
                        } catch {
                          // Ignore when browser blocks programmatic picker invocation.
                        }
                      }}
                      className="w-36 rounded border border-slate-200 px-2 py-1 text-xs text-slate-700"
                    />
                  </td>
                  <td className="px-2 py-2 text-slate-700">{record.isin || record.ticker || "-"}</td>
                  <td className="px-2 py-2 text-right text-slate-700">
                    <input
                      type="number"
                      step="0.01"
                      value={row.quantity}
                      onChange={(event) => handleQuantityChange(index, event.target.value)}
                      className="w-24 rounded border border-slate-200 px-2 py-1 text-right text-xs text-slate-700"
                    />
                  </td>
                  <td className="px-2 py-2 text-right text-slate-700">{formatNumber(row.strike)}</td>
                  <td className="px-2 py-2 text-right text-slate-700">{row.knockLabel}</td>
                  <td className="px-2 py-2 text-right text-slate-700">{formatNumber(row.amount)}</td>
                  <td className="px-2 py-2 text-right text-slate-700">{formatNumber(row.quantity2x)}</td>
                  <td className="px-2 py-2 text-right text-slate-700">{formatNumber(row.amount2x)}</td>
                  <td className="px-2 py-2 text-right font-medium text-slate-800">{formatNumber(row.pendingExposure)}</td>
                  <td className="px-2 py-2 text-right">
                    <button
                      type="button"
                      onClick={() => {
                        const pid = String(record.id || "");
                        if (pid) {
                          try {
                            sessionStorage.setItem(
                              "stock_entry_prefill",
                              JSON.stringify({
                                pid,
                                sl: row.serial,
                                date: row.startDate,
                                price: String(row.strike),
                                qty: String(row.quantity),
                                createdAt: Date.now(),
                              })
                            );
                          } catch {
                            // Ignore storage errors and continue with navigation.
                          }
                        }
                        router.push(`/equity/stock/form?pid=${encodeURIComponent(pid)}`);
                      }}
                      className="inline-flex items-center rounded border border-[#428B4D]/40 px-2 py-1 text-[11px] font-semibold text-[#428B4D] hover:bg-[#428B4D] hover:text-white"
                    >
                      Entry
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
            <tfoot className="border-t border-slate-200 bg-slate-50">
              <tr>
                <td className="px-2 py-2 text-slate-700" />
                <td className="px-2 py-2 text-slate-700" />
                <td className="px-2 py-2 text-slate-700" />
                <td className="px-2 py-2 text-right font-semibold text-slate-800">{formatNumber(totals.quantity)}</td>
                <td className="px-2 py-2 text-slate-700" />
                <td className="px-2 py-2 text-slate-700" />
                <td className="px-2 py-2 text-right font-semibold text-slate-800">{formatNumber(totals.amount)}</td>
                <td className="px-2 py-2 text-right font-semibold text-slate-800">{formatNumber(totals.quantity2x)}</td>
                <td className="px-2 py-2 text-right font-semibold text-slate-800">{formatNumber(totals.amount2x)}</td>
                <td className="px-2 py-2 text-slate-700" />
                <td className="px-2 py-2 text-slate-700" />
              </tr>
            </tfoot>
          </table>
        </div>
      </div>
    );
  }, [isAccumulator, scheduleRows, record.isin, record.ticker]);

  return (
    <RecordModal
      record={record}
      onClose={onClose}
      onEdit={onEdit}
      onDelete={onDelete}
      title="Derivative overview"
      subtitle={subtitle}
      metrics={metrics}
      detailItems={detailItems}
      extraContent={scheduleTable}
    />
  );
});

EquityDerivativesModal.displayName = "EquityDerivativesModal";
