// coPilotData.jsx — single source of truth for the Producer Co-pilot.
// Three lead types, each with its own columns + detail content:
//   • bene_post        — beneficiary, post-claim (received a payout, needs own coverage)
//   • bene_pre         — beneficiary of a LIVING policy owner, needs their own policy
//   • policyholder_gap — existing policyholder who is underinsured (upsell)
//
// The two pre-claim types (bene_pre, policyholder_gap) also carry a PHASE that
// describes how far the person got through Helm's consumer needs-analysis:
//   requested  — finished the analysis AND asked a producer to reach out  (hottest)
//   identified — finished with clear gaps, but did not request contact     (warm)
//   partial    — stopped partway, softer signal                           (cool)
//
// The conversion score, the detail page and the outreach campaign all read
// from these fields so a producer sees the right thing per lead + phase.

const money = (n) => "$" + Number(n).toLocaleString("en-US");

// ----------------------------------------------------------------- meta tables
const TYPE_META = {
  bene_post: {
    label: "Beneficiary · post-claim",
    short: "Beneficiaries · post-claim",
    tab: "Post-claim beneficiaries",
    color: "var(--helm-dark-purple)",
    bg: "rgba(198,179,235,0.30)",
  },
  bene_pre: {
    label: "Beneficiary · pre-claim",
    short: "Beneficiaries · pre-claim",
    tab: "Pre-claim beneficiaries",
    color: "var(--helm-dark-blue)",
    bg: "rgba(161,220,226,0.32)",
  },
  policyholder_gap: {
    label: "Policy owner · coverage gap",
    short: "Policy owners · coverage gap",
    tab: "Policy owner gaps",
    color: "var(--helm-chartreuse-2)",
    bg: "rgba(193,201,131,0.32)",
  },
};

const PHASE_META = {
  requested: {
    label: "Requesting contact",
    color: "var(--helm-chartreuse-2)",
    bg: "rgba(193,201,131,0.32)",
    dot: "var(--helm-chartreuse-2)",
    desc: "Completed the Helm needs analysis and asked a producer to reach out.",
  },
  identified: {
    label: "Needs identified",
    color: "var(--helm-dark-orange)",
    bg: "rgba(255,184,118,0.30)",
    dot: "var(--helm-dark-orange)",
    desc: "Finished the analysis with clear gaps — but hasn't requested contact yet.",
  },
  partial: {
    label: "Partial analysis",
    color: "var(--helm-dark-blue)",
    bg: "rgba(161,220,226,0.32)",
    dot: "var(--helm-dark-blue)",
    desc: "Started the needs analysis but stopped partway — a softer signal.",
  },
};

// Conversion-score tiers (generalized from the old BCRi).
const scoreTier = (s) =>
  s >= 90
    ? { label: "Excellent", wrap: "rgba(193,201,131,0.45)", chip: "var(--helm-chartreuse)", text: "var(--helm-chartreuse-2)" }
    : s >= 80
    ? { label: "Good", wrap: "rgba(255,184,118,0.40)", chip: "var(--helm-orange)", text: "var(--helm-dark-orange)" }
    : { label: "Fair", wrap: "rgba(161,220,226,0.40)", chip: "var(--helm-blue)", text: "var(--helm-dark-blue)" };

// ----------------------------------------------------------------- the leads
// Numeric fields stay numbers so the detail page can lay out coverage bars;
// the table formats them on the way out.
const LEADS = [
  // ===================== POST-CLAIM BENEFICIARIES =====================
  {
    id: "marc", type: "bene_post", name: "Marc Mullins", first: "Marc",
    img: "helm/avatars/marc-mullins.jpg", state: "New Jersey", score: 97,
    owner: "Judah Mullins", relation: "Father", policy: "BL427664",
    prevAgent: "Morgan Pierce", received: 245400, retained: 212200,
    payout: "Aug 4, 2025", claimStatus: "Closed", daysSince: 72,
    occupation: "Teacher", income: "$145,000/yr", recCoverage: 300000, engaged: true,
    campaign: { dayN: 7, dayTotal: 14, stepN: 3, stepTotal: 5 },
    contact: { legal: "Demarcus Samuel Mullins", email: "marc.mullins@gmail.com", phone: "(856) 983-2401", city: "Camden, NJ 08103", street: "4423 Whitelock Dr" },
    hero: { min: 150000, max: 350000, rec: 300000 },
    bespoke: {
      blurb: "Recent activity and income suggest Marc needs his own coverage in this range.",
      signals: [
        { dir: "up", text: "$180k left on mortgage", tag: "Strong signal", strong: true },
        { dir: "up", text: "Two children heading to college", tag: "1 week ago" },
        { dir: "down", text: "Added childcare support funds" },
      ],
      activity: [
        { icon: "bank", title: "Transferred $212,200 into Helm Cash account", date: "Aug 10, 2025" },
        { icon: "mail", title: "Opened Helm Cash email drip #2", date: "Aug 7, 2025" },
        { icon: "search", title: "Searched for \u201CCollege expenses\u201D", date: "Aug 7, 2025" },
      ],
      notes: "Morgan has been agent of record on Judah's policy for years and guided Marc through the claim this summer.",
    },
  },
  {
    id: "emma", type: "bene_post", name: "Emmaline Cho", first: "Emmaline",
    img: "helm/avatars/emmaline-cho.jpg", state: "New Jersey", score: 96,
    owner: "Abe Cho", relation: "Father", policy: "BL392154",
    prevAgent: "Morgan Pierce", received: 230000, retained: 194500,
    payout: "Aug 1, 2025", claimStatus: "Closed", daysSince: 75,
    occupation: "Nurse practitioner", income: "$132,000/yr", recCoverage: 275000, engaged: true,
    contact: { legal: "Emmaline Joon Cho", email: "emmaline.cho@gmail.com", phone: "(201) 774-9920", city: "Hoboken, NJ 07030", street: "88 Garden St, Apt 4B" },
    hero: { min: 150000, max: 350000, rec: 275000 },
  },
  {
    id: "carter", type: "bene_post", name: "Carter Berry", first: "Carter",
    img: "helm/avatars/mono/carter.png", state: "New York", score: 91,
    owner: "Shepard Berry", relation: "Father", policy: "BL588921",
    prevAgent: "Morgan Pierce", received: 190000, retained: 163000,
    payout: "Aug 10, 2025", claimStatus: "Closed", daysSince: 66,
    occupation: "Software engineer", income: "$168,000/yr", recCoverage: 250000, engaged: true,
    campaign: { dayN: 11, dayTotal: 14, stepN: 4, stepTotal: 5 },
    contact: { legal: "Carter James Berry", email: "carter.berry@gmail.com", phone: "(917) 552-1188", city: "Brooklyn, NY 11215", street: "240 7th Ave" },
  },
  {
    id: "sofia", type: "bene_post", name: "Sofia Reyes", first: "Sofia",
    img: "helm/avatars/mono/sofia.png", state: "Illinois", score: 84,
    owner: "Hector Reyes", relation: "Father", policy: "BL622884",
    prevAgent: "Morgan Pierce", received: 268000, retained: 221400,
    payout: "Jul 20, 2025", claimStatus: "Closed", daysSince: 87,
    occupation: "Small-business owner", income: "$98,000/yr", recCoverage: 240000, engaged: true,
    contact: { legal: "Sofia Marisol Reyes", email: "sofia.reyes@gmail.com", phone: "(312) 690-4471", city: "Chicago, IL 60622", street: "1714 W Division St" },
  },
  {
    id: "dwight", type: "bene_post", name: "Dwight Carver", first: "Dwight",
    img: null, state: "Pennsylvania", score: 61, engaged: false,
    owner: "Eunice Carver", relation: "Mother", policy: "BL704559",
    prevAgent: "Morgan Pierce", received: 175000, retained: 0,
    payout: "Feb 18, 2026", claimStatus: "Closed", daysSince: 102,
    occupation: "Warehouse supervisor", income: "$72,000/yr", recCoverage: 200000, estimated: true,
    contact: { legal: "Dwight Earl Carver", email: "dwight.carver@gmail.com", phone: "(412) 555-0148", city: "Pittsburgh, PA 15203", street: "1140 E Carson St" },
  },

  // ===================== POLICYHOLDER COVERAGE GAPS =====================
  {
    id: "michael", type: "policyholder_gap", name: "Michael Olansky", first: "Michael",
    img: "helm/avatars/michael-olansky.jpg", state: "Connecticut", score: 95, phase: "requested",
    policy: "BL458013", currentCoverage: 250000, recCoverage: 600000,
    premium: "$62/mo", policyAge: "6 yrs", agent: "Morgan Pierce", lastAnalysis: "3 days ago",
    occupation: "Financial analyst", income: "$210,000/yr",
    campaign: { dayN: 2, dayTotal: 8, stepN: 1, stepTotal: 4 },
    contact: { legal: "Michael David Olansky", email: "michael.olansky@gmail.com", phone: "(203) 449-7720", city: "Stamford, CT 06902", street: "37 Bedford St, Unit 12" },
    bespoke: {
      blurb: "Michael finished the Helm needs analysis and asked to add coverage — his protection now trails his income and obligations.",
      signals: [
        { dir: "up", text: "Requested additional coverage in-app", tag: "3 days ago", strong: true },
        { dir: "up", text: "New child added to household", tag: "Strong signal", strong: true },
        { dir: "up", text: "Base income up 18% YoY" },
      ],
      activity: [
        { icon: "ai", title: "Completed Helm coverage needs analysis", date: "May 27, 2026" },
        { icon: "search", title: "Requested a call with a producer", date: "May 27, 2026" },
        { icon: "mail", title: "Saved a $600k Term 20 illustration", date: "May 27, 2026" },
      ],
      notes: "Bought the original $250k term in 2020 before his promotion and second child. Open to converting to a larger term.",
    },
  },
  {
    id: "priya", type: "policyholder_gap", name: "Priya Nair", first: "Priya",
    img: "helm/avatars/mono/priya.png", state: "Massachusetts", score: 86, phase: "identified",
    policy: "BL501277", currentCoverage: 300000, recCoverage: 550000,
    premium: "$48/mo", policyAge: "4 yrs", agent: "Morgan Pierce", lastAnalysis: "1 week ago",
    occupation: "Pharmacist", income: "$158,000/yr",
    campaign: { dayN: 7, dayTotal: 14, stepN: 3, stepTotal: 5 },
    contact: { legal: "Priya Anjali Nair", email: "priya.nair@gmail.com", phone: "(617) 332-8841", city: "Newton, MA 02458", street: "62 Court St" },
  },
  {
    id: "daniel", type: "policyholder_gap", name: "Daniel Okafor", first: "Daniel",
    img: "helm/avatars/mono/daniel.png", state: "Texas", score: 82, phase: "identified",
    policy: "BL710233", currentCoverage: 400000, recCoverage: 750000,
    premium: "$71/mo", policyAge: "5 yrs", agent: "Morgan Pierce", lastAnalysis: "2 weeks ago",
    occupation: "Operations director", income: "$192,000/yr",
    contact: { legal: "Daniel Chinedu Okafor", email: "daniel.okafor@gmail.com", phone: "(512) 884-0190", city: "Austin, TX 78704", street: "1209 Bouldin Ave" },
  },
  {
    id: "rebecca", type: "policyholder_gap", name: "Rebecca Stern", first: "Rebecca",
    img: null, state: "Ohio", score: 71, phase: "partial",
    policy: "BL664120", currentCoverage: 150000, recCoverage: 400000,
    premium: "$33/mo", policyAge: "8 yrs", agent: "Morgan Pierce", lastAnalysis: "Incomplete",
    occupation: "Marketing manager", income: "$118,000/yr",
    contact: { legal: "Rebecca Lynn Stern", email: "rebecca.stern@gmail.com", phone: "(614) 770-2245", city: "Columbus, OH 43215", street: "415 N High St" },
  },

  // ===================== PRE-CLAIM BENEFICIARIES =====================
  {
    id: "hannah", type: "bene_pre", name: "Hannah Whitfield", first: "Hannah",
    img: "helm/avatars/mono/hannah.png", state: "California", score: 93, phase: "requested",
    owner: "Robert Whitfield", relation: "Daughter", ownerPolicy: "BL330788",
    recCoverage: 300000, occupation: "Product designer", income: "$162,000/yr", dependents: "2",
    campaign: { dayN: 3, dayTotal: 9, stepN: 2, stepTotal: 4 },
    contact: { legal: "Hannah Claire Whitfield", email: "hannah.whitfield@gmail.com", phone: "(415) 220-7781", city: "Oakland, CA 94612", street: "510 14th St, Apt 9" },
    bespoke: {
      blurb: "Hannah is named on her father's policy and asked Helm to connect her with a producer about her own coverage.",
      signals: [
        { dir: "up", text: "Requested own-coverage consult", tag: "2 days ago", strong: true },
        { dir: "up", text: "Recently bought a home — $540k mortgage", tag: "Strong signal", strong: true },
        { dir: "up", text: "First child, 8 months old" },
      ],
      activity: [
        { icon: "ai", title: "Completed Helm coverage needs analysis", date: "May 29, 2026" },
        { icon: "search", title: "Requested a producer introduction", date: "May 29, 2026" },
        { icon: "mail", title: "Compared Term 20 vs Term 30 options", date: "May 28, 2026" },
      ],
      notes: "Listed as primary beneficiary on Robert Whitfield's $500k whole-life policy. Wants coverage that matches her new mortgage.",
    },
  },
  {
    id: "liam", type: "bene_pre", name: "Liam Donovan", first: "Liam",
    img: null, state: "Washington", score: 84, phase: "identified",
    owner: "Patricia Donovan", relation: "Son", ownerPolicy: "BL455190",
    recCoverage: 250000, occupation: "Civil engineer", income: "$138,000/yr", dependents: "1",
    campaign: { dayN: 4, dayTotal: 14, stepN: 2, stepTotal: 5 },
    contact: { legal: "Liam Patrick Donovan", email: "liam.donovan@gmail.com", phone: "(206) 553-9014", city: "Seattle, WA 98103", street: "4420 Wallingford Ave N" },
  },
  {
    id: "grace", type: "bene_pre", name: "Grace Albright", first: "Grace",
    img: null, state: "Florida", score: 79, phase: "identified",
    owner: "Theodore Albright", relation: "Spouse", ownerPolicy: "BL288471",
    recCoverage: 400000, occupation: "Dentist", income: "$224,000/yr", dependents: "3",
    contact: { legal: "Grace Eleanor Albright", email: "grace.albright@gmail.com", phone: "(305) 661-3398", city: "Coral Gables, FL 33134", street: "2701 Granada Blvd" },
  },
  {
    id: "noah", type: "bene_pre", name: "Noah Bennett", first: "Noah",
    img: null, state: "Colorado", score: 68, phase: "partial",
    owner: "Carol Bennett", relation: "Son", ownerPolicy: "BL519602",
    recCoverage: 200000, occupation: "Graphic designer", income: "$84,000/yr", dependents: "0",
    contact: { legal: "Noah Alexander Bennett", email: "noah.bennett@gmail.com", phone: "(720) 410-5567", city: "Denver, CO 80205", street: "3155 Larimer St" },
  },
];

const leadById = (id) => LEADS.find((l) => l.id === id);
const leadsByType = (type) => LEADS.filter((l) => l.type === type);

// initials helper for the avatar fallback
const initials = (name) => name.split(" ").map((n) => n[0]).join("").slice(0, 2);

// ----------------------------------------------------------------- detail builder
// Produces everything the LeadDetail page needs, branching on type + phase.
// Hand-authored `bespoke` content on a lead wins; otherwise sensible defaults
// are generated from the lead's structured fields.
function buildDetail(lead) {
  const t = lead.type;
  const phase = lead.phase ? PHASE_META[lead.phase] : null;
  const b = lead.bespoke || {};

  // ---- hero (coverage bar) ----
  let hero;
  if (t === "policyholder_gap") {
    const max = Math.round(lead.recCoverage * 1.25 / 50000) * 50000;
    hero = {
      label: "Coverage gap",
      blurb: b.blurb || `${lead.first}'s current ${money(lead.currentCoverage)} policy now trails the protection their income and obligations suggest.`,
      min: 0, max, rec: lead.recCoverage, current: lead.currentCoverage, recLabel: "Recommended",
    };
  } else if (t === "bene_pre") {
    hero = {
      label: "Recommended coverage",
      blurb: b.blurb || `As a named beneficiary, ${lead.first} has identified a need for their own coverage in this range.`,
      min: Math.max(0, Math.round((lead.recCoverage - 200000) / 50000) * 50000),
      max: Math.round((lead.recCoverage + 200000) / 50000) * 50000, rec: lead.recCoverage, recLabel: "Recommended",
    };
  } else {
    const eng = lead.engaged !== false;
    hero = {
      label: eng ? "Coverage need" : "Estimated coverage need",
      blurb: b.blurb || (eng
        ? `Recent activity and income suggest ${lead.first} needs their own coverage in this range.`
        : `${lead.first} hasn't engaged with Helm's planning tools yet. This is a rough estimate from income; a producer touch could re-engage them and pin down the real number.`),
      min: lead.hero ? lead.hero.min : 100000,
      max: lead.hero ? lead.hero.max : 350000,
      rec: lead.recCoverage, recLabel: eng ? "Recommended" : "Estimate",
    };
  }

  // ---- key data ----
  let keyData;
  if (t === "bene_post") {
    const eng = lead.engaged !== false;
    keyData = [
      ["Occupation", lead.occupation], ["Income", lead.income],
      ["Policy owner", lead.owner], ["Relation", lead.relation],
      ["Payout date", lead.payout], ["Benefits received", money(lead.received)],
      ["Benefits retained", money(lead.retained)],
      ["Identified need", eng ? money(lead.recCoverage) : "N/A"],
      ["Helm planning", eng ? "Engaged" : "Not engaged"],
      ["Claim status", lead.claimStatus],
    ];
  } else if (t === "policyholder_gap") {
    keyData = [
      ["Occupation", lead.occupation], ["Income", lead.income],
      ["Current coverage", money(lead.currentCoverage)], ["Recommended", money(lead.recCoverage)],
      ["Coverage gap", money(lead.recCoverage - lead.currentCoverage)], ["Current premium", lead.premium],
      ["Policy #", lead.policy], ["Policy age", lead.policyAge],
      ["Agent of record", lead.agent], ["Needs analysis", lead.lastAnalysis],
    ];
  } else {
    keyData = [
      ["Occupation", lead.occupation], ["Income", lead.income],
      ["Policy owner", lead.owner], ["Relationship", lead.relation],
      ["Owner's policy", lead.ownerPolicy], ["Recommended coverage", money(lead.recCoverage)],
      ["Dependents", lead.dependents], ["Needs analysis", phase ? phase.label : "—"],
    ];
  }

  // ---- signals (default per type/phase if not bespoke) ----
  let signals = b.signals;
  if (!signals) {
    if (t === "policyholder_gap") {
      signals = phaseSignalsGap(lead);
    } else if (t === "bene_pre") {
      signals = phaseSignalsBenePre(lead);
    } else {
      const eng = lead.engaged !== false;
      signals = eng ? [
        { dir: "up", text: `${money(lead.retained)} retained from claim`, tag: "Strong signal", strong: true },
        { dir: "up", text: "Recently received payout", tag: lead.daysSince + " days ago" },
        { dir: "down", text: "No current individual policy" },
      ] : [
        { dir: "up", text: `${money(lead.received)} claim paid out`, tag: lead.daysSince + " days ago" },
        { dir: "down", text: "Not engaged with Helm planning", tag: "Low intent" },
        { dir: "down", text: "No needs analysis completed" },
      ];
    }
  }

  // ---- activity ----
  let activity = b.activity;
  if (!activity) {
    if (t === "policyholder_gap") {
      activity = [
        { icon: "ai", title: lead.phase === "partial" ? "Started Helm coverage needs analysis" : "Completed Helm coverage needs analysis", date: lead.lastAnalysis === "Incomplete" ? "2 weeks ago" : lead.lastAnalysis },
        { icon: "search", title: `Reviewed a ${money(lead.recCoverage)} term illustration`, date: "Recently" },
        { icon: "mail", title: "Opened Helm coverage review email", date: "Recently" },
      ];
    } else if (t === "bene_pre") {
      activity = [
        { icon: "ai", title: lead.phase === "partial" ? "Started Helm coverage needs analysis" : "Completed Helm coverage needs analysis", date: "Recently" },
        { icon: "search", title: `Explored ${money(lead.recCoverage)} term options`, date: "Recently" },
        { icon: "mail", title: "Opened Helm beneficiary guide", date: "Recently" },
      ];
    } else {
      const eng = lead.engaged !== false;
      activity = eng ? [
        { icon: "bank", title: `Transferred ${money(lead.retained)} into Helm Cash account`, date: lead.payout },
        { icon: "mail", title: "Opened Helm Cash email drip #2", date: lead.payout },
        { icon: "search", title: "Searched for \u201CFamily coverage\u201D", date: lead.payout },
      ] : [
        { icon: "bank", title: "Claim paid out to external account", date: lead.payout },
        { icon: "mail", title: "Has not opened Helm planning emails", date: "No activity" },
        { icon: "search", title: "No Helm account activity since payout", date: `${lead.daysSince} days` },
      ];
    }
  }

  // ---- left-rail relationship/anchor fields ----
  let anchor;
  if (t === "bene_post") {
    anchor = { label: "Policy owner's agent", value: `${lead.prevAgent} (you)`, sub: `Agent of record on ${lead.owner}'s policy` };
  } else if (t === "policyholder_gap") {
    anchor = { label: "Agent of record", value: `${lead.agent} (you)`, sub: `Policy ${lead.policy} · ${money(lead.currentCoverage)} · ${lead.premium}` };
  } else {
    anchor = { label: "Policy owner", value: `${lead.owner} · ${lead.relation}`, sub: `Owner's policy ${lead.ownerPolicy} · you are agent of record` };
  }

  return {
    type: TYPE_META[t], phase, hero, keyData, signals, activity, anchor,
    notes: b.notes || defaultNotes(lead),
  };
}

const agentEmail = (n) => n.toLowerCase().split(" ").map((p, i) => i === 0 ? p[0] : p).join(".").replace(/[^a-z.]/g, "") + "@partner.com";

function defaultNotes(lead) {
  if (lead.type === "bene_post") return `${lead.first} is the beneficiary on ${lead.owner}'s policy (${lead.relation}). Claim closed ${lead.payout}.`;
  if (lead.type === "policyholder_gap") return `${lead.first} holds policy ${lead.policy} (${money(lead.currentCoverage)}). Helm flagged a ${money(lead.recCoverage - lead.currentCoverage)} gap.`;
  return `${lead.first} is named on ${lead.owner}'s policy (${lead.ownerPolicy}) and may need their own coverage.`;
}

function phaseSignalsGap(lead) {
  const gap = money(lead.recCoverage - lead.currentCoverage);
  if (lead.phase === "requested") return [
    { dir: "up", text: "Requested additional coverage in-app", tag: "Hot", strong: true },
    { dir: "up", text: `Identified ${gap} coverage gap`, tag: "Strong signal", strong: true },
    { dir: "up", text: "Income outpacing current policy" },
  ];
  if (lead.phase === "identified") return [
    { dir: "up", text: `Identified ${gap} coverage gap`, tag: "Strong signal", strong: true },
    { dir: "up", text: "Completed Helm needs analysis" },
    { dir: "down", text: "Has not yet requested contact" },
  ];
  return [
    { dir: "up", text: `Possible ${gap} gap surfaced`, tag: "Partial", },
    { dir: "down", text: "Stopped partway through analysis" },
    { dir: "down", text: "Softer conversion signal" },
  ];
}

function phaseSignalsBenePre(lead) {
  const rec = money(lead.recCoverage);
  if (lead.phase === "requested") return [
    { dir: "up", text: "Requested own-coverage consult", tag: "Hot", strong: true },
    { dir: "up", text: `Identified need near ${rec}`, tag: "Strong signal", strong: true },
    { dir: "up", text: `Named beneficiary on ${lead.owner}'s policy` },
  ];
  if (lead.phase === "identified") return [
    { dir: "up", text: `Identified need near ${rec}`, tag: "Strong signal", strong: true },
    { dir: "up", text: "Completed Helm needs analysis" },
    { dir: "down", text: "Has not yet requested contact" },
  ];
  return [
    { dir: "up", text: `Possible need near ${rec}` },
    { dir: "down", text: "Stopped partway through analysis" },
    { dir: "down", text: "Softer conversion signal" },
  ];
}

Object.assign(window, {
  CP_LEADS: LEADS, CP_money: money, CP_TYPE_META: TYPE_META, CP_PHASE_META: PHASE_META,
  CP_scoreTier: scoreTier, CP_leadById: leadById, CP_leadsByType: leadsByType,
  CP_initials: initials, CP_buildDetail: buildDetail,
});
