import { useMemo, useState } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useBacktestReport } from '../../hooks/useMarketRegime';
import { triggerJob } from '../../api/admin';
import type { BacktestCadence, BacktestTargetModel } from '../../api/admin';
import { Button } from '../ui/Button';
import { Callout } from '../ui/Callout';
import { Disclosure } from '../ui/Disclosure';
import { Dropdown } from '../ui/Dropdown';
import { Section } from '../ui/Section';
import { useToast } from '../ui/Toast';
import { BacktestRecommendationCard } from './BacktestRecommendationCard';
import { PortfolioMonitorPanel } from './PortfolioMonitorPanel';

function timeAgo(iso: string): string {
  const mins = Math.floor((Date.now() - new Date(iso).getTime()) / 60_000);
  if (mins < 1) return 'just now';
  if (mins < 60) return `${mins}m ago`;
  const hrs = Math.floor(mins / 60);
  if (hrs < 24) return `${hrs}h ago`;
  return `${Math.floor(hrs / 24)}d ago`;
}

const TARGET_MODEL_OPTIONS = [
  { value: 'production_gtl', label: 'Live GTL — production' },
  { value: 'structural_sr', label: 'Structural S/R — comparison' },
];
const CADENCE_OPTIONS = [
  { value: 'weekly', label: 'Weekly — default' },
  { value: 'daily', label: 'Daily — research' },
];

export function BacktestPanel() {
  const { data: report, isLoading } = useBacktestReport();
  const queryClient = useQueryClient();
  const toast = useToast();
  const [selectedStrategy, setSelectedStrategy] = useState('');
  const [selectedLookback, setSelectedLookback] = useState('');
  const [targetModel, setTargetModel] = useState<BacktestTargetModel>('production_gtl');
  const [cadence, setCadence] = useState<BacktestCadence>('weekly');

  const monitor = report?.portfolio_monitor ?? null;
  const activeStrategy =
    selectedStrategy || monitor?.production_strategy || monitor?.strategies[0]?.strategy || '';
  // Default to the window the recommendation was computed on, so the tiles and
  // the recommendation never open showing different numbers. They used to: the
  // backend preferred "all" while this defaulted to "3y". The 3y fallback is
  // only for reports predating basis_lookback.
  const basisLookback = report?.recommendation?.basis_lookback ?? null;
  const activeLookback =
    selectedLookback ||
    (basisLookback && monitor?.lookbacks.some((l) => l.lookback === basisLookback)
      ? basisLookback
      : monitor?.lookbacks.some((l) => l.lookback === '3y')
        ? '3y'
        : monitor?.lookbacks[0]?.lookback) ||
    '';
  const monitorRun = useMemo(
    () =>
      monitor?.runs.find((row) => row.strategy === activeStrategy && row.lookback === activeLookback) ??
      monitor?.runs.find((row) => row.strategy === activeStrategy) ??
      monitor?.runs[0] ??
      null,
    [monitor, activeStrategy, activeLookback],
  );

  const run = useMutation({
    mutationFn: () => triggerJob('backtest', { target_model: targetModel, cadence }),
    onSuccess: (res) => {
      if (res.status === 'triggered') {
        const label = targetModel === 'production_gtl' ? 'Live GTL' : 'Structural S/R comparison';
        toast.addToast('success', `${label} ${cadence} backtest started — results appear when it finishes.`);
        setTimeout(() => queryClient.invalidateQueries({ queryKey: ['backtest-report'] }), 8000);
      } else {
        toast.addToast('info', res.message || 'Could not start backtest');
      }
    },
    onError: () => toast.addToast('error', 'Failed to start backtest'),
  });

  return (
    <Section title="Is the strategy working?" hint="portfolio simulation of the promoted strategy vs S&P 500">
      <div className="space-y-4">
        {/* Run status and the controls that start a new run, on one line. The
            explainer sits BELOW this row rather than beside it — sharing a flex
            row meant expanding it shoved every control down the page. */}
        <div className="flex flex-wrap items-end justify-between gap-3">
          <div className="min-w-0">
            <p className="section-index">Last run</p>
            {report ? (
              <p className="mt-1 text-xs text-gray-400">
                {timeAgo(report.generated_at)} · {report.tickers} tickers ·{' '}
                {report.candidates} setups ({report.qualified} qualified) ·{' '}
                {report.params.entry_cadence ?? 'weekly'},{' '}
                {report.params.horizon_days}d horizon
                {report.params.cost_per_side_pct != null && (
                  <> · net of {report.params.cost_per_side_pct}%/side</>
                )}
                {' · '}
                <span className={report.params.is_production_target_model === false ? 'text-amber-300' : 'text-blue-300'}>
                  {report.params.target_model_label ?? 'Unknown (legacy report)'}
                </span>
              </p>
            ) : (
              <p className="mt-1 text-xs text-gray-500">Never run</p>
            )}
          </div>

          {/* flex-wrap is load-bearing: two dropdowns plus the button overflow a
              narrow viewport otherwise. */}
          <div className="flex flex-wrap items-end gap-2">
            <div className="flex flex-col gap-1 text-[11px] uppercase tracking-wider text-gray-500">
              <label htmlFor="backtest-target-model">Target model</label>
              <Dropdown
                id="backtest-target-model"
                className="w-56 normal-case tracking-normal"
                value={targetModel}
                onChange={(v) => setTargetModel(v as BacktestTargetModel)}
                options={TARGET_MODEL_OPTIONS}
              />
            </div>
            <div className="flex flex-col gap-1 text-[11px] uppercase tracking-wider text-gray-500">
              <label htmlFor="backtest-cadence">Entry cadence</label>
              <Dropdown
                id="backtest-cadence"
                className="w-44 normal-case tracking-normal"
                value={cadence}
                onChange={(v) => setCadence(v as BacktestCadence)}
                options={CADENCE_OPTIONS}
              />
            </div>
            <Button onClick={() => run.mutate()} loading={run.isPending} className="shrink-0">
              {run.isPending ? 'Starting…' : report ? 'Re-run' : 'Run backtest'}
            </Button>
          </div>
        </div>

        <div>
          <Disclosure summary="How this is measured">
            <p className="max-w-2xl text-xs text-gray-400">
              The backtest replays the current config at the selected cadence — at each point the setup is
              rebuilt using only data up to that day (no lookahead) and the following ~30 trading days decide
              its outcome — then simulates one capital-constrained book against the S&P 500. Sentiment and
              fundamentals are held neutral (no point-in-time history). ~6 months is roughly one market regime,
              so read it as directional.
            </p>
            <p className="mt-2 max-w-2xl text-xs text-gray-400">
              <strong className="text-gray-300">Live GTL</strong> is the exact target path the scanner and the
              scheduled backtest use; <strong className="text-gray-300">Structural S/R</strong> is a comparison
              arm sourcing targets from chart structure. <strong className="text-gray-300">Weekly</strong> steps
              five sessions at a time and is what the server runs; <strong className="text-gray-300">Daily</strong>
              {' '}is roughly 5× the replay work.
            </p>
          </Disclosure>
        </div>

        {/* Only surfaced for non-default choices — zero noise on the common path,
            but a non-production selection still announces itself, which is what
            the old always-amber cards were really for. */}
        {(cadence === 'daily' || targetModel === 'structural_sr') && (
          <div className="space-y-1 text-[11px] text-amber-300/80">
            {cadence === 'daily' && (
              <p>Daily replays ~5× the work — prefer the offline snapshot runner.</p>
            )}
            {targetModel === 'structural_sr' && (
              <p>Comparison arm — not the live scanner's target path.</p>
            )}
          </div>
        )}

        {isLoading && <Callout variant="empty">Loading…</Callout>}

        {!isLoading && !report && (
          <Callout variant="empty">
            No backtest yet. Click “Run backtest” (or trigger it in Admin → Jobs) — it replays every ticker
            over history and takes a minute or two.
          </Callout>
        )}

        {report && (
          <>
            <PortfolioMonitorPanel
              monitor={monitor}
              monitorRun={monitorRun}
              activeStrategy={activeStrategy}
              activeLookback={activeLookback}
              onStrategyChange={setSelectedStrategy}
              onLookbackChange={setSelectedLookback}
              basisLookback={basisLookback}
              basisLookbackLabel={report.recommendation?.basis_lookback_label ?? null}
              productionStrategy={monitor?.production_strategy ?? null}
            />

            {report.recommendation && (
              <BacktestRecommendationCard recommendation={report.recommendation} />
            )}
          </>
        )}
      </div>
    </Section>
  );
}
