"use client";

import * as React from "react";
import { ArrowRightLeft, Info } from "lucide-react";

import { Button } from "@/components/ui/button";
import {
  Popover,
  PopoverContent,
  PopoverDescription,
  PopoverHeader,
  PopoverTitle,
  PopoverTrigger,
} from "@/components/ui/popover";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
import { formatAmount } from "@/lib/format/numbers";
import { cn } from "@/lib/utils";

import type {
  StructuredProductDateSeries,
  StructuredProductLegacyField,
  StructuredProductReportRow,
} from "../../_lib/structured-product-types";

export const UNDERLYING_FIELDS = new Set<StructuredProductLegacyField>([
  "Industry",
  "Sector",
  "UnderlyingISIN1",
  "Underlying1",
  "InitialLevel",
  "StrikeLevel",
  "KOPrice",
  "BreakEvenPrice",
  "CMP",
  "away_from_Strike1",
  "away_from_Initial1",
]);

/** Collapse API group rows into one UI row per product (underlyings stack in-cell). */
export function groupStructuredProductRows(rows: StructuredProductReportRow[]) {
  const groups: StructuredProductReportRow[][] = [];
  let index = 0;
  while (index < rows.length) {
    const head = rows[index];
    const declaredSize = Math.max(1, Number(head.groupSize) || 1);
    if (declaredSize > 1 || head.isFirstInGroup) {
      const size = Math.min(declaredSize, rows.length - index);
      groups.push(rows.slice(index, index + size));
      index += size;
      continue;
    }

    // Fallback when groupSize is missing: fold consecutive legs of the same product.
    const productKey = head.productId || String(head.structureId) || head.id;
    let end = index + 1;
    while (end < rows.length) {
      const next = rows[end];
      const nextKey = next.productId || String(next.structureId) || next.id;
      if (nextKey !== productKey || next.isFirstInGroup || (Number(next.groupSize) || 1) > 1) {
        break;
      }
      end += 1;
    }
    groups.push(rows.slice(index, end));
    index = end;
  }
  return groups;
}

const TWO_DECIMAL_PERCENT_FIELDS = new Set<StructuredProductLegacyField>([
  "StrikePercentage",
  "KOBarrier",
  "Coupon",
  "away_from_Strike1",
  "away_from_Initial1",
]);

const TWO_DECIMAL_AMOUNT_FIELDS = new Set<StructuredProductLegacyField>([
  "IndicativeCoupon",
  "Notional",
  "InitialLevel",
  "StrikeLevel",
  "KOPrice",
  "BreakEvenPrice",
  "IndicativeAnnualCoupon",
]);

export function reportCellValue(row: StructuredProductReportRow, field: StructuredProductLegacyField) {
  let value = row.values[field];
  if (field === "KOPrice" && (value === "" || value == null)) {
    value = row.ko_price;
  }
  if (field === "EarlyRedm" || field === "Delivery") {
    return Number(value) === 1 ? "1" : "0";
  }
  if (TWO_DECIMAL_PERCENT_FIELDS.has(field)) {
    const numeric = Number.parseFloat(String(value ?? "").replace(/[,%]/g, ""));
    return Number.isFinite(numeric) ? `${numeric.toFixed(2)}%` : "";
  }
  if (TWO_DECIMAL_AMOUNT_FIELDS.has(field)) {
    const numeric = Number.parseFloat(String(value ?? "").replace(/,/g, ""));
    return Number.isFinite(numeric)
      ? formatAmount(numeric, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
      : "";
  }
  return value === "" || value == null ? "" : String(value);
}

export function reportCellClass(row: StructuredProductReportRow, field: StructuredProductLegacyField) {
  if (field !== "away_from_Strike1" && field !== "away_from_Initial1") return undefined;
  const value = Number.parseFloat(String(row.values[field] ?? "").replace(/[,%]/g, ""));
  if (!Number.isFinite(value)) return "text-muted-foreground";
  return value < 0 ? "font-medium text-red-600" : "font-medium text-emerald-600";
}

export const RIGHT_ALIGNED_FIELDS = new Set<StructuredProductLegacyField>([
  "StrikePercentage",
  "KOBarrier",
  "Coupon",
  "IndicativeCoupon",
  "Notional",
  "InitialLevel",
  "StrikeLevel",
  "KOPrice",
  "BreakEvenPrice",
  "CMP",
  "away_from_Strike1",
  "away_from_Initial1",
  "IndicativeAnnualCoupon",
]);

function StructuredProductDateSeriesCell({
  series,
  label,
}: {
  series: StructuredProductDateSeries;
  label: string;
}) {
  const hiddenCount = Math.max(0, series.all.length - series.visible.length);
  const hasNonCallDetails = series.all.some((item) => item.nonCall);
  const showPopover = hiddenCount > 0 || hasNonCallDetails;

  return (
    <div className="flex items-start gap-1.5">
      <div className="min-w-0 space-y-0.5">
        {series.visible.map((item) => (
          <div
            key={item.date}
            className={cn(
              "whitespace-nowrap text-xs leading-4",
              item.isPast && "text-muted-foreground",
            )}
          >
            {item.formatted}
          </div>
        ))}
      </div>
      {showPopover ? (
        <Popover>
          <PopoverTrigger asChild>
            <Button
              type="button"
              variant="ghost"
              size="sm"
              className="h-5 shrink-0 gap-1 px-1 text-blue-600 hover:bg-blue-50 hover:text-blue-700"
              aria-label={`View all ${label.toLowerCase()}`}
              onClick={(event) => event.stopPropagation()}
            >
              <Info className="size-3.5" strokeWidth={2.5} />
              {hiddenCount > 0 ? <span className="text-[10px] font-medium">+{hiddenCount}</span> : null}
            </Button>
          </PopoverTrigger>
          <PopoverContent align="start" side="bottom" className="w-60 p-0">
            <PopoverHeader className="border-b px-3 py-2">
              <PopoverTitle className="text-xs">{label}</PopoverTitle>
              <PopoverDescription className="text-[11px]">
                {series.all.length} {series.all.length === 1 ? "date" : "dates"}
              </PopoverDescription>
            </PopoverHeader>
            <div className="max-h-56 overflow-y-auto px-3 py-2">
              <div className="space-y-1">
                {series.all.map((item) => (
                  <div
                    key={item.date}
                    className="flex items-center justify-between gap-2 text-xs leading-4"
                  >
                    <span className={cn(item.isPast && "text-muted-foreground")}>
                      {item.formatted}
                    </span>
                    {item.nonCall ? (
                      <span className="shrink-0 rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground">
                        non-call
                      </span>
                    ) : null}
                  </div>
                ))}
              </div>
            </div>
          </PopoverContent>
        </Popover>
      ) : null}
    </div>
  );
}

export function StructuredProductCell({
  row,
  field,
}: {
  row: StructuredProductReportRow;
  field: StructuredProductLegacyField;
}) {
  if (field === "product_typeAbsolute") {
    return (
      <div className="leading-tight">
        <div className="font-medium">{row.product.name || reportCellValue(row, field)}</div>
        {row.product.absoluteCoupon ? (
          <div className="mt-0.5 text-[11px] text-muted-foreground">
            Abs. coupon{" "}
            <span className="font-semibold text-emerald-600">
              {reportCellValue(row, "IndicativeCoupon")}
            </span>
          </div>
        ) : null}
      </div>
    );
  }
  if (field === "Observationdates" || field === "CouponDates") {
    const series =
      field === "Observationdates" ? row.dates.observations : row.dates.coupons;
    return (
      <StructuredProductDateSeriesCell
        series={series}
        label={field === "Observationdates" ? "Observation dates" : "Coupon dates"}
      />
    );
  }
  if (field === "NextObservationdate") {
    return row.dates.nextObservation?.formatted ?? "";
  }
  if (field === "UnderlyingISIN1" && row.underlyingMeta.currencyMismatch) {
    return (
      <span className="inline-flex items-center gap-1">
        {reportCellValue(row, field)}
        <TooltipProvider>
          <Tooltip>
            <TooltipTrigger asChild>
              <ArrowRightLeft
                className="size-3 cursor-help text-orange-500"
                onClick={(event) => event.stopPropagation()}
              />
            </TooltipTrigger>
            <TooltipContent>{row.underlyingMeta.currencyMismatchMessage}</TooltipContent>
          </Tooltip>
        </TooltipProvider>
      </span>
    );
  }
  return reportCellValue(row, field);
}
