// Mock data representing a single scored participant, modelled on the v2.5 scored card schema.
const MOCK_PARTICIPANT = {
  respondentId: 'p-001',
  name: 'Arjun Mehta',
  role: 'Co-founder & CEO',
  org: 'Meridian Labs',
  completedAt: '2026-04-18T14:23:00Z',
  scoringPath: 'native',
  responseQuality: { flag: 'CLEAN', reliability: 'HIGH', pctMidpoint: 12, pctAgreement: 48, completionMinutes: 27.4 },
  dimensions: {
    philosophyCohesion: 78,
    driveAlignment: 86,
    bondingIndex: 42,
    adaptiveIntelligence: 81,
    volatilityVector: 71,
    ambiguityTolerance: 74,
    influenceStyle: 82,
    feedbackOrientation: 38,
    temporalOrientation: 64,
    energyResilience: 77,
  },
  scaleMeans: {
    perceptualDepth: 4.21, generativeRange: 4.05, aestheticSensitivity: 3.33, socialPresence: 4.11,
    prosocialDrive: 2.94, relationalTrust: 2.76, goalPersistence: 4.60, executionStriving: 4.67,
    structuralOrder: 4.12, impulseGovernance: 3.21, reactiveImpulse: 4.15, hostileReactivity: 3.05,
    threatSensitivity: 2.32, affectiveVolatility: 2.80, moodDepression: 1.95, forwardDeliberation: 3.05,
    directiveForce: 4.42,
  },
  supplementary: { gritTotal: 4.12, gritPerseverance: 4.50, gritConsistency: 3.75, brcsScore: 17, workEthicTotal: 44 },
  aiPreferences: { informationProcessing: 'A', challengeTolerance: 'A', decisionSupport: 'A', communicationTempo: 'A', cognitiveBlindSpot: 'A' },
  signature: 'Decisive Strategist with Low-Warmth Tilt',
};

const MOCK_PARTNER = {
  respondentId: 'p-002',
  name: 'Lena Sørensen',
  role: 'Co-founder & COO',
  org: 'Meridian Labs',
  dimensions: {
    philosophyCohesion: 72,
    driveAlignment: 81,
    bondingIndex: 78,
    adaptiveIntelligence: 64,
    volatilityVector: 32,
    ambiguityTolerance: 41,
    influenceStyle: 44,
    feedbackOrientation: 72,
    temporalOrientation: 79,
    energyResilience: 58,
  },
  signature: 'Relational Operator, Deliberative Anchor',
};

// Dimension display metadata (IP-protected participant labels)
const DIMS = [
  { id: 'philosophyCohesion', label: 'Philosophy Cohesion', blurb: 'Alignment with mission and long-term direction.' },
  { id: 'driveAlignment', label: 'Drive Alignment', blurb: 'Work ethic, standards, self-direction.' },
  { id: 'bondingIndex', label: 'Bonding Index', blurb: 'Prosocial orientation and relational investment.' },
  { id: 'adaptiveIntelligence', label: 'Adaptive Intelligence', blurb: 'Learning agility and fluid thinking.' },
  { id: 'volatilityVector', label: 'Volatility Vector', blurb: 'Risk tolerance and impulse profile.' },
  { id: 'ambiguityTolerance', label: 'Ambiguity Tolerance', blurb: 'Functioning in open-ended environments.' },
  { id: 'influenceStyle', label: 'Influence Style', blurb: 'Collaborative vs. directive leadership.' },
  { id: 'feedbackOrientation', label: 'Feedback Orientation', blurb: 'Receptivity to direct challenge.' },
  { id: 'temporalOrientation', label: 'Temporal Orientation', blurb: 'Near-term vs. long-horizon bias.' },
  { id: 'energyResilience', label: 'Energy & Resilience', blurb: 'Sustained output, recovery speed.' },
];

const band = (score) => {
  if (score <= 25) return 'Low';
  if (score <= 50) return 'Mid-Low';
  if (score <= 75) return 'Mid-High';
  return 'High';
};

// Pairwise deltas + a single Kalibr cohesion score.
function computePair(a, b) {
  const weights = {
    philosophyCohesion: { w: 1.5, type: 'similarity' },
    driveAlignment: { w: 1.3, type: 'similarity' },
    bondingIndex: { w: 1.2, type: 'similarity' },
    adaptiveIntelligence: { w: 0.8, type: 'complementary' },
    volatilityVector: { w: 0.9, type: 'complementary' },
    ambiguityTolerance: { w: 1.0, type: 'similarity' },
    influenceStyle: { w: 0.7, type: 'complementary' },
    feedbackOrientation: { w: 1.1, type: 'similarity' },
    temporalOrientation: { w: 1.4, type: 'similarity' },
    energyResilience: { w: 0.8, type: 'similarity' },
  };
  const rows = DIMS.map(d => {
    const av = a.dimensions[d.id], bv = b.dimensions[d.id];
    const diff = Math.abs(av - bv);
    const cfg = weights[d.id];
    let score;
    if (cfg.type === 'similarity') score = 100 - diff * 1.2;
    else { const ideal = 25; score = 100 - Math.abs(diff - ideal) * 1.4; }
    score = Math.max(0, Math.min(100, score));
    return { id: d.id, label: d.label, av, bv, diff, type: cfg.type, weight: cfg.w, score };
  });
  const total = rows.reduce((s, r) => s + r.score * r.weight, 0) / rows.reduce((s, r) => s + r.weight, 0);
  return { rows, cohesion: Math.round(total) };
}

// ─── Live score reader ────────────────────────────────────────────────────────
// Reads from window.__kalibr_python_scores (set by bridge) or localStorage fallback.
// Returns the full /score response object, or null if not yet available.

function getKalibrScores() {
  // Priority 1: window.__kalibr_python_scores set by the bridge
  const py = window.__kalibr_python_scores;
  if (py) {
    // Full response object: { dimensions, scaleMeans, supplementary, aiPreferences, quality }
    if (py.dimensions && typeof py.dimensions === 'object') return py;
    // Bridge may have set it directly to the dimensions object
    if (typeof py.philosophyCohesion === 'number') {
      return { dimensions: py, supplementary: {}, aiPreferences: {}, scaleMeans: {}, quality: {} };
    }
  }

  // Priority 2: localStorage — bridge writes dimensions there too
  try {
    const raw = localStorage.getItem('kalibr.be.cards');
    if (raw) {
      const cards = JSON.parse(raw);
      const keys = Object.keys(cards);
      if (keys.length) {
        const entry = cards[keys[keys.length - 1]];
        const card = entry && entry.card;
        if (card && card.dimensions && typeof card.dimensions === 'object') {
          return {
            dimensions: card.dimensions,
            supplementary: card.supplementary || {},
            aiPreferences: card.aiPreferences || {},
            scaleMeans: card.scaleMeans || {},
            quality: card.quality || {},
          };
        }
      }
    }
  } catch (e) { /* silent fail */ }

  return null;
}

// React hook: returns live scores and re-renders when bridge writes new data.

Object.assign(window, { MOCK_PARTICIPANT, MOCK_PARTNER, DIMS, band, computePair, getKalibrScores });
