import { useMutation, useQueryClient } from '@tanstack/react-query';
import { usePerformance } from '../../hooks/usePerformance';
import { useBacktestReport } from '../../hooks/useMarketRegime';
import { triggerJob, resetTrackRecord } from '../../api/admin';
import { Button } from '../ui/Button';
import { Disclosure } from '../ui/Disclosure';
import { useToast } from '../ui/Toast';
import { BacktestPanel } from './BacktestPanel';
import { MyTradesPanel } from './MyTradesPanel';

// Need at least this many matured setups before the pipeline check means anything;
// below it the live sample is too noisy to compare.
const MIN_MATURED = 20;
// Live expectancy this far (in R) below the backtest counts as drift, not noise.
const DRIFT_TOLERANCE_R = 0.2;

type PipelineStatus = 'building' | 'tracking' | 'drift' | 'no-backtest';

function fmtR(value: number | null): string {
  if (value === null) return '—';
  return `${value > 0 ? '+' : ''}${value.toFixed(2)}R`;
}

function rColor(value: number | null): string {
  if (value === null) return 'text-gray-400';
  if (value > 0) return 'text-emerald-400';
  if (value < 0) return 'text-red-400';
  return 'text-gray-300';
}

function StatusChip({ status }: { status: PipelineStatus }) {
  const styles: Record<PipelineStatus, { cls: string; label: string }> = {
    tracking: { cls: 'border-emerald-500/30 bg-emerald-500/15 text-emerald-300', label: '✓ in sync' },
    drift: { cls: 'border-amber-500/30 bg-amber-500/15 text-amber-300', label: '⚠ drift' },
    building: { cls: 'border-white/10 bg-white/[0.05] text-gray-400', label: 'building' },
    'no-backtest': { cls: 'border-white/10 bg-white/[0.05] text-gray-400', label: 'no backtest' },
  };
  const s = styles[status];
  return <span className={`shrink-0 rounded-full border px-2.5 py-1 text-xs font-medium ${s.cls}`}>{s.label}</span>;
}

export function TrackRecordPanel() {
  const queryClient = useQueryClient();
  const toast = useToast();

  // Setup-outcome pipeline check: does the live outcome evaluator reproduce the
  // backtest's target/stop grading? Both sides use the SAME target/stop/expired
  // model — this is a plumbing/QA signal (no look-ahead, config or data drift),
  // NOT validation of the ATR-trail production strategy shown in the monitor.
  const { data: perf } = usePerformance({ qualified_only: true });
  const { data: report } = useBacktestReport();
  const liveAvgR = perf?.overall.avg_r ?? null;
  const liveN = perf?.overall.total ?? 0;
  const btAvgR = report?.overall_qualified.avg_r ?? null;
  let status: PipelineStatus = 'building';
  if (liveAvgR != null && liveN >= MIN_MATURED) {
    status = btAvgR == null ? 'no-backtest' : liveAvgR >= btAvgR - DRIFT_TOLERANCE_R ? 'tracking' : 'drift';
  }
  const statusNote: Record<PipelineStatus, string> = {
    building: `Fewer than ~${MIN_MATURED} matured setups so far — too few to compare.`,
    'no-backtest': 'Run the backtest to get a target/stop baseline to check against.',
    tracking:
      "Live setup outcomes are resolving in line with the backtest's target/stop model — the outcome-evaluation pipeline shows no look-ahead, config or data drift. (Checks the setup-grading pipeline, not the ATR-trail production book above.)",
    drift:
      "Live setup outcomes are running materially below the backtest's target/stop model — small-sample noise, a regime shift, or a live/backtest pipeline gap. Worth a look.",
  };

  const evaluateMutation = useMutation({
    mutationFn: () => triggerJob('outcome_evaluator'),
    onSuccess: () => {
      toast.addToast('success', 'Outcome evaluation triggered. Stats will refresh shortly.');
      setTimeout(() => queryClient.invalidateQueries({ queryKey: ['performance'] }), 3000);
    },
    onError: () => {
      toast.addToast('error', 'Failed to trigger outcome evaluation');
    },
  });

  const resetMutation = useMutation({
    mutationFn: () => resetTrackRecord(),
    onSuccess: (data) => {
      toast.addToast('success', `Track record reset — ${data.trade_setups} setups cleared. Run the scanner to rebuild.`);
      queryClient.invalidateQueries({ queryKey: ['performance'] });
      queryClient.invalidateQueries({ queryKey: ['trades'] });
    },
    onError: () => {
      toast.addToast('error', 'Failed to reset track record');
    },
  });

  const onReset = () => {
    if (
      window.confirm(
        'Reset the track record? This permanently deletes ALL trade setups and their outcomes. ' +
          'Live setups will regenerate on the next R:R scan. This cannot be undone.',
      )
    ) {
      resetMutation.mutate();
    }
  };

  return (
    <div className="space-y-6">
      {/* Your real, realized results come first; the strategy simulation follows. */}
      <MyTradesPanel />
      <div className="border-t border-white/[0.06]" />
      <BacktestPanel />

      <Disclosure summary="Track-record maintenance">
        <div className="space-y-4 pt-1">
          <p className="max-w-2xl text-xs text-gray-500">
            The live check replays every setup against the daily bars after detection: target before stop =
            win, stop first = loss (both in one bar counts conservatively as a loss), neither within 30
            trading days = expired at 0R. Only setups whose full window has elapsed count; younger ones are
            still maturing (near stops resolve fast, far targets need time, so early numbers skew negative).
            The evaluator scores <span className="text-gray-300">all</span> setups — qualified or not, so
            unqualified ones stay a control group — and runs nightly.
          </p>

          {/* Diagnostic, not strategy validation: live target/stop outcomes vs the backtest's target/stop model. */}
          <div className="glass-sm space-y-2 p-4">
            <div className="flex flex-wrap items-center justify-between gap-x-6 gap-y-2">
              <div className="flex flex-wrap items-baseline gap-x-5 gap-y-1">
                <span className="text-sm text-gray-300">Setup-outcome pipeline check</span>
                <span className="text-sm text-gray-400">
                  Live <span className={`num font-semibold ${rColor(liveAvgR)}`}>{fmtR(liveAvgR)}</span>
                </span>
                <span className="text-sm text-gray-400">
                  Backtest <span className={`num font-semibold ${rColor(btAvgR)}`}>{fmtR(btAvgR)}</span>
                </span>
                <span className="text-xs text-gray-500">
                  {liveN} matured{perf ? ` · ${perf.maturing} maturing` : ''} · qualified target/stop
                </span>
              </div>
              <StatusChip status={status} />
            </div>
            <p className="text-[11px] leading-relaxed text-gray-500">{statusNote[status]}</p>
          </div>

          <div className="flex flex-wrap items-center gap-2">
            <Button onClick={() => evaluateMutation.mutate()} loading={evaluateMutation.isPending}>
              {evaluateMutation.isPending ? 'Evaluating…' : 'Evaluate Now'}
            </Button>
            <Button variant="danger" onClick={onReset} loading={resetMutation.isPending}>
              {resetMutation.isPending ? 'Resetting…' : 'Reset'}
            </Button>
          </div>
        </div>
      </Disclosure>
    </div>
  );
}
