import { Disclosure } from '../ui/Disclosure';
import type { BacktestRecommendation } from '../../lib/types';

/**
 * The verdict, ahead of the tuning detail.
 *
 * Two problems this solves. All eight findings used to render as equal-weight
 * bullets, so "does this strategy work" sat in the same register as "which
 * cutoff scored best". And the headline — which is a *description of the
 * config*, not a verdict — was the loudest thing on the card while every actual
 * finding was small grey text.
 *
 * So: findings first, each split into a label and its detail; the config
 * description demoted to a footer where it belongs.
 */
const PRIMARY_TOPICS = new Set(['production', 'benchmark', 'robustness']);

/**
 * Mirrors how the backend phrases a bad result — `_build_recommendation` emits
 * "Robustness WARNING: …" and "Book vs SPY: LAGS …". There is deliberately no
 * `severity` field on the payload; if that changes, this is the one place to fix.
 */
function isWarning(text: string): boolean {
  return text.includes('WARNING') || text.includes('LAGS');
}

/**
 * Every backend string self-prefixes ("Gate: keep the R:R floor…"), so the
 * prefix IS the label — no need for a chip that would just repeat it, and no
 * need to reword anything server-side. Split on the first colon; if a string
 * ever stops carrying one, it renders whole as detail.
 */
function splitLabel(text: string): { label: string | null; detail: string } {
  const at = text.indexOf(': ');
  if (at === -1 || at > 48) return { label: null, detail: text };
  return { label: text.slice(0, at), detail: text.slice(at + 2) };
}

function Finding({ text, primary }: { text: string; primary: boolean }) {
  const warn = isWarning(text);
  const { label, detail } = splitLabel(text);
  return (
    <li className="flex flex-col gap-0.5 sm:flex-row sm:gap-3">
      {label && (
        <span
          className={`shrink-0 text-[11px] font-semibold uppercase tracking-wider sm:w-44 sm:pt-0.5 ${
            warn ? 'text-amber-400' : 'text-gray-500'
          }`}
        >
          {label}
        </span>
      )}
      <span
        className={`${primary ? 'text-sm' : 'text-xs'} ${
          warn ? 'text-amber-300' : primary ? 'text-gray-200' : 'text-gray-400'
        }`}
      >
        {detail}
      </span>
    </li>
  );
}

export function BacktestRecommendationCard({
  recommendation,
}: {
  recommendation: BacktestRecommendation;
}) {
  const items = recommendation.items;
  if (items.length === 0) return null;

  // A warning is always visible, whatever its topic — burying "the edge
  // disappears without the top 5% of winners" behind a disclosure would defeat
  // the point of surfacing it at all.
  const primary = items.filter((i) => PRIMARY_TOPICS.has(i.topic) || isWarning(i.text));
  const secondary = items.filter((i) => !PRIMARY_TOPICS.has(i.topic) && !isWarning(i.text));
  const warningCount = items.filter((i) => isWarning(i.text)).length;

  return (
    <div className="space-y-2">
      <div className="glass border border-blue-400/20 p-4">
        <div className="flex flex-wrap items-center justify-between gap-2">
          <p className="section-index">What this backtest recommends</p>
          {/* No headline means the backend found no production monitor row, so
              nothing here describes the production book. Zero keyword warnings
              is then absence of data, not a clean bill of health — a green chip
              beside "this report predates the portfolio monitor" would be a
              success badge for missing data. */}
          {!recommendation.headline ? (
            <span className="rounded-full border border-white/15 bg-white/[0.05] px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-gray-400">
              baseline unavailable
            </span>
          ) : warningCount > 0 ? (
            <span className="rounded-full border border-amber-400/40 bg-amber-400/10 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-amber-300">
              ⚠ {warningCount} warning{warningCount > 1 ? 's' : ''}
            </span>
          ) : (
            <span className="rounded-full border border-emerald-400/30 bg-emerald-400/10 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-emerald-300">
              no warnings
            </span>
          )}
        </div>

        {primary.length > 0 && (
          <ul className="mt-3 space-y-2.5">
            {primary.map((item) => (
              <Finding key={item.topic + item.text} text={item.text} primary />
            ))}
          </ul>
        )}

        {/* The config description, demoted: it says what the strategy IS, which
            is context for the findings above rather than a finding itself. */}
        {recommendation.headline && (
          <div className="mt-3 border-t border-white/[0.06] pt-3">
            <p className="section-index">Configuration under test</p>
            <p className="mt-1 text-xs leading-relaxed text-gray-500">{recommendation.headline}</p>
          </div>
        )}

        {recommendation.note && (
          <p className="mt-2 text-[11px] text-gray-600">{recommendation.note}</p>
        )}
      </div>

      {/* Outside the card body on purpose: Disclosure renders its own glass-sm
          panel, so nesting it inside the bordered card double-frames it. */}
      {secondary.length > 0 && (
        <Disclosure summary={`Gate and cutoff detail (${secondary.length})`}>
          <ul className="space-y-2">
            {secondary.map((item) => (
              <Finding key={item.topic + item.text} text={item.text} primary={false} />
            ))}
          </ul>
        </Disclosure>
      )}
    </div>
  );
}
