const VOCAB = { rep: 'rep', reps: 'reps', contact: 'contact', stage1: 'Application call', stage2: 'Follow-up', outcomes: ['Application', 'Pre-approval', 'Funded'], results: 'Results' };

const RULES = [
  { key: 'R1', label: 'Agent referral push', text: 'Ask the borrower for the name of their real-estate agent and offer to coordinate.', weight: 3, keyRule: true, pass: 22, prev: 16, disputed: 14, na: 'Contact already under contract' },
  { key: 'R2', label: 'Ask assets bank by bank', text: 'Ask for each account by institution, not "how much do you have saved".', weight: 3, keyRule: true, pass: 31, prev: 29, disputed: 4, na: 'Refinance with no cash to close', items: ['Checking', 'Savings', 'Retirement', 'Gift funds'] },
  { key: 'R3', label: 'Cost conversation uses script', text: 'Walk the cost sheet in the scripted order: rate, points, lender fees, third-party fees.', weight: 2, keyRule: false, pass: 44, prev: 47, disputed: 6, na: 'Contact declines cost discussion' },
  { key: 'R7', label: 'Set follow-up date', text: 'Name a specific day and time for the next call before wrap-up.', weight: 2, keyRule: false, pass: 49, prev: 41, disputed: 2, na: '' },
  { key: 'R4', label: 'Opener names the partner agent', text: 'Open with the referring agent\u2019s name within the first 30 seconds.', weight: 1, keyRule: false, pass: 58, prev: 55, disputed: 3, na: 'No referring agent on file' },
  { key: 'R6', label: 'Timeline question', text: 'Ask when the borrower wants to be in the home.', weight: 2, keyRule: false, pass: 63, prev: 60, disputed: 1, na: '' },
  { key: 'R5', label: 'Credit pull disclosure', text: 'Read the credit-pull consent verbatim before pulling.', weight: 3, keyRule: true, pass: 71, prev: 74, disputed: 9, na: 'No credit pulled on this call' },
  { key: 'R8', label: 'No filler phrases', text: 'None of: "to be honest", "basically", "like I said".', weight: 1, keyRule: false, pass: 77, prev: 72, disputed: 0, na: '' },
];
const RULE = Object.fromEntries(RULES.map(r => [r.key, r]));

const REPS = [
  { id: 'maria', name: 'Maria Delgado', calls: 31, followUps: 12, score: 34, delta: -7, app: 38, pre: 21, keyPass: 29, drift: 3, coached: 'Sep 2', worst: 'R1', streak: 0 },
  { id: 'tom', name: 'Tom Reilly', calls: 24, followUps: 9, score: 29, delta: -4, app: 33, pre: 17, keyPass: 24, drift: 5, coached: null, worst: 'R2', streak: 1 },
  { id: 'derek', name: 'Derek Lin', calls: 19, followUps: 6, score: 38, delta: -1, app: 42, pre: 26, keyPass: 35, drift: 1, coached: 'Oct 3', worst: 'R3', streak: 2 },
  { id: 'james', name: 'James Okafor', calls: 28, followUps: 14, score: 47, delta: 3, app: 50, pre: 32, keyPass: 46, drift: 0, coached: 'Oct 6', worst: 'R1', streak: 3 },
  { id: 'ana', name: 'Ana Souza', calls: 22, followUps: 8, score: 44, delta: 5, app: 45, pre: 27, keyPass: 41, drift: 2, coached: 'Sep 28', worst: 'R7', streak: 4 },
  { id: 'sofia', name: 'Sofia Marin', calls: 26, followUps: 10, score: 51, delta: 9, app: 54, pre: 35, keyPass: 55, drift: 1, coached: 'Oct 7', worst: 'R2', streak: 6 },
  { id: 'chris', name: 'Chris Patel', calls: 7, followUps: 2, score: 36, delta: 2, app: null, pre: null, keyPass: 33, drift: 0, coached: null, worst: 'R1', streak: 1, lowSample: true },
  { id: 'priya', name: 'Priya Nair', calls: 30, followUps: 11, score: 58, delta: 12, app: 60, pre: 41, keyPass: 63, drift: 0, coached: 'Oct 8', worst: 'R3', streak: 9 },
];
const REP = Object.fromEntries(REPS.map(r => [r.id, r]));

// per-rep pass rates (rule key -> %)
const REP_RULES = {
  maria: { R1: 10, R2: 26, R3: 39, R7: 42, R4: 55, R6: 61, R5: 68, R8: 80 },
  tom: { R1: 17, R2: 8, R3: 33, R7: 29, R4: 50, R6: 54, R5: 63, R8: 71 },
  derek: { R1: 26, R2: 32, R3: 21, R7: 47, R4: 58, R6: 68, R5: 74, R8: 79 },
  james: { R1: 14, R2: 43, R3: 50, R7: 54, R4: 61, R6: 64, R5: 79, R8: 82 },
  ana: { R1: 27, R2: 36, R3: 45, R7: 23, R4: 59, R6: 66, R5: 73, R8: 77 },
  sofia: { R1: 35, R2: 19, R3: 58, R7: 62, R4: 70, R6: 71, R5: 81, R8: 85 },
  chris: { R1: 14, R2: 29, R3: 43, R7: 43, R4: 57, R6: 57, R5: 71, R8: 71 },
  priya: { R1: 40, R2: 53, R3: 37, R7: 67, R4: 73, R6: 77, R5: 90, R8: 87 },
};

const fmt = s => `${Math.floor(s / 60)}:${String(s % 60).padStart(2, '0')}`;

const CALLS = [
  { id: 'c1041', date: 'Oct 9 · 4:12 pm', rep: 'maria', contact: 'R. Whitaker', type: 'Application call', variant: 'Agent-referred', score: 27, done: 3, applicable: 7, flags: ['Told approved'], outcome: null, duration: 1912, deal: 412000, rubric: 'v4',
    checks: [
      { rule: 'R4', status: 'done', t: 18, note: 'Named Keller agent Dana Ruiz at 0:18.' },
      { rule: 'R6', status: 'done', t: 214, note: '"When are you hoping to be in?" at 3:34.' },
      { rule: 'R2', status: 'missed', t: 702, note: 'Asked "roughly how much in savings"; no bank-by-bank ask.', items: [['Checking', 'skipped'], ['Savings', 'asked'], ['Retirement', 'skipped'], ['Gift funds', 'skipped']] },
      { rule: 'R3', status: 'missed', t: 1120, note: 'Rate then fees; points skipped entirely.' },
      { rule: 'R5', status: 'done', t: 1288, note: 'Consent read verbatim at 21:28.' },
      { rule: 'R1', status: 'missed', t: 1744, note: 'Wrap-up with no mention of the agent. Said "I\u2019ll get you approved" at 28:51.' },
      { rule: 'R7', status: 'missed', t: 1860, note: '"I\u2019ll reach out later this week." No day or time.' },
      { rule: 'R8', status: 'na', t: null, note: 'Not graded for agent-referred variant under v4.' },
    ],
    objections: [{ id: 'O3', text: '"Rates are going to drop, I\u2019ll wait."', handling: 'partial', scripted: 'Acknowledge, then float-down option and lock-and-shop.', said: '"They might, nobody really knows."', t: 1402 }],
    summary: 'Agent-referred application with a borrower under contract. Intake went well through timeline. Assets asked as a lump sum, points skipped in the cost walk, and the referral push never happened. The rep said the borrower was approved before any underwriting decision.' },
  { id: 'c1038', date: 'Oct 9 · 2:40 pm', rep: 'tom', contact: 'L. & K. Ahmed', type: 'Application call', variant: 'Standard', score: 22, done: 2, applicable: 8, flags: ['CRM tag missing'], outcome: null, duration: 1540, deal: 365000, rubric: 'v4' },
  { id: 'c1036', date: 'Oct 9 · 1:05 pm', rep: 'priya', contact: 'D. Fontaine', type: 'Application call', variant: 'Standard', score: 71, done: 6, applicable: 8, flags: [], outcome: 'Application', duration: 2210, deal: 528000, rubric: 'v4' },
  { id: 'c1033', date: 'Oct 9 · 11:30 am', rep: 'james', contact: 'S. Petrova', type: 'Follow-up', variant: 'Standard', score: 52, done: 3, applicable: 5, flags: ['Continues earlier call'], outcome: null, duration: 640, deal: 290000, rubric: 'v4' },
  { id: 'c1029', date: 'Oct 8 · 5:48 pm', rep: 'derek', contact: 'M. Okonkwo', type: 'Application call', variant: 'Dialer intake', score: 39, done: 3, applicable: 7, flags: [], outcome: null, duration: 1388, deal: 445000, rubric: 'v4' },
  { id: 'c1027', date: 'Oct 8 · 3:15 pm', rep: 'sofia', contact: 'B. Castellano', type: 'Application call', variant: 'Agent-referred', score: 63, done: 5, applicable: 7, flags: ['Credit pulled'], outcome: 'Pre-approval', duration: 1990, deal: 610000, rubric: 'v4' },
  { id: 'c1024', date: 'Oct 8 · 10:02 am', rep: 'ana', contact: 'H. Nguyen', type: 'Application call', variant: 'Standard', score: 41, done: 4, applicable: 8, flags: [], outcome: 'Application', duration: 1702, deal: 338000, rubric: 'v4' },
  { id: 'c1019', date: 'Oct 7 · 4:50 pm', rep: 'maria', contact: 'P. Lindqvist', type: 'Application call', variant: 'Standard', score: 44, done: 4, applicable: 8, flags: [], outcome: null, duration: 1811, deal: 402000, rubric: 'v4', superseded: 'c1033' },
  { id: 'c1012', date: 'Oct 6 · 9:20 am', rep: 'chris', contact: 'T. Baros', type: 'Application call', variant: 'Standard', score: 33, done: 3, applicable: 8, flags: ['CRM tag missing'], outcome: null, duration: 1290, deal: 275000, rubric: 'v4' },
  { id: 'c0998', date: 'Oct 1 · 2:11 pm', rep: 'james', contact: 'E. Marsh', type: 'Application call', variant: 'Standard', score: 48, done: 4, applicable: 8, flags: [], outcome: 'Application', duration: 1650, deal: 455000, rubric: 'v3' },
];
// synthesize check lists for calls without one
const STATUS_FOR = (call, i, n) => (i < call.done ? 'done' : i < call.applicable ? 'missed' : 'na');
CALLS.forEach(c => { if (!c.checks) { c.checks = RULES.map((r, i) => ({ rule: r.key, status: STATUS_FOR(c, i, RULES.length), t: i < c.applicable ? Math.round((c.duration / (RULES.length + 1)) * (i + 1)) : null, note: i < c.done ? 'Done, scripted wording.' : i < c.applicable ? 'Not heard on this call.' : 'Does not apply to this variant.' })); c.objections = c.objections || []; c.summary = c.summary || 'Standard application intake. See checklist for the misses.'; } });
const CALL = Object.fromEntries(CALLS.map(c => [c.id, c]));

const DEALS = [
  { call: 'c1041', value: 412000, rule: 'R1' },
  { call: 'c1038', value: 365000, rule: 'R2' },
  { call: 'c1029', value: 445000, rule: 'R5' },
  { call: 'c1012', value: 275000, rule: 'R2' },
];

const SESSIONS = [
  { id: 's21', rep: 'james', date: 'Oct 6', manager: 'Dana Park', focus: ['R1'], note: 'Played c0998 at 27:40. Role-played the referral ask twice.', state: 'after', before: { pass: 12, calls: 26 }, after: { pass: 61, calls: 23 }, team: 22, call: 'c0998' },
  { id: 's20', rep: 'sofia', date: 'Oct 7', manager: 'Dana Park', focus: ['R2'], note: 'Bank-by-bank checklist taped to monitor.', state: 'after', before: { pass: 19, calls: 24 }, after: { pass: 36, calls: 6 }, team: 31, lowSample: true },
  { id: 's19', rep: 'priya', date: 'Oct 8', manager: 'Dana Park', focus: ['R3'], note: 'Points first, every time.', state: 'before', before: { pass: 37, calls: 30 }, after: null, team: 44 },
  { id: 's18', rep: 'derek', date: 'Oct 3', manager: 'Luis Ortega', focus: ['R3', 'R7'], note: 'Cost sheet order and a hard follow-up date.', state: 'complete', before: { pass: 21, calls: 18 }, after: { pass: 49, calls: 19 }, team: 44 },
];

const DISPUTES = [
  { id: 'd77', call: 'c1041', rule: 'R1', status: 'missed', graderNote: 'Wrap-up with no mention of the agent.', reason: 'Borrower said agent is her sister; rep acknowledged at 4:10.', requester: 'Maria Delgado', age: '2h', t: 250 },
  { id: 'd76', call: 'c1027', rule: 'R5', status: 'done', graderNote: 'Consent read verbatim.', reason: 'Rep paraphrased the second sentence. Should be missed.', requester: 'Dana Park', age: '1d', t: 1288 },
  { id: 'd74', call: 'c1024', rule: 'R2', status: 'missed', graderNote: 'Only savings asked.', reason: 'Asked checking and savings; retirement came up on the follow-up.', requester: 'Ana Souza', age: '2d', t: 702 },
  { id: 'd71', call: 'c1012', rule: 'R1', status: 'missed', graderNote: 'No referral ask.', reason: 'Contact is a refinance. Rule should not apply.', requester: 'Chris Patel', age: '4d', t: 1100 },
];

const LIBRARY = [
  { rule: 'R1', call: 'c1036', rep: 'priya', t: 1910, excerpt: '"Before we wrap, who\u2019s your agent? I\u2019d like to send them the pre-approval directly so you\u2019re not stuck in the middle."', note: 'Clean ask, offers a reason, names the deliverable.' },
  { rule: 'R2', call: 'c1027', rep: 'sofia', t: 690, excerpt: '"Let\u2019s go account by account. Checking first, which bank, and roughly what\u2019s in it today?"', note: 'Institution first, then balance.' },
  { rule: 'R3', call: 'c1036', rep: 'priya', t: 1150, excerpt: '"Here\u2019s the order I\u2019ll go in: rate, then points, then our fees, then third parties."', note: 'Announces the order, then follows it.' },
];

const TREND = [34, 33, 36, 35, 38, 37, 39, 41];

const VERSIONS = [
  { v: 'v4', date: 'Oct 2', author: 'Dana Park', diff: 'R2 weight 2→3 · R8 excluded for agent-referred · R7 wording', calls: 1240 },
  { v: 'v3', date: 'Sep 11', author: 'Lotic (implementer)', diff: 'Added R7 Set follow-up date', calls: 2118 },
  { v: 'v2', date: 'Aug 20', author: 'Lotic (implementer)', diff: 'R1 marked key rule', calls: 1874 },
  { v: 'v1', date: 'Jul 30', author: 'Lotic (implementer)', diff: 'Initial rubric from script', calls: 3360 },
];

Object.assign(window, { VOCAB, RULES, RULE, REPS, REP, REP_RULES, CALLS, CALL, DEALS, SESSIONS, DISPUTES, LIBRARY, TREND, VERSIONS, fmt });
