// OS Builder — data tables for all 12 phases.
// Trades, business models, tools, pain points, modules, automations, pricing rules.

/* ==================== PHASE 1: IDENTITY ==================== */

const TRADES = [
  { id:'hvac',     name:'HVAC',           tag:'Heating · Cooling · IAQ' },
  { id:'plumb',    name:'Plumbing',       tag:'Service · Repipe · Drain' },
  { id:'elec',     name:'Electrical',     tag:'Residential · Panel · EV' },
  { id:'roof',     name:'Roofing',        tag:'Repair · Replace · Storm' },
  { id:'gc',       name:'General Contracting', tag:'Remodel · Build' },
  { id:'tree',     name:'Tree Service',   tag:'Removal · Trim · Storm' },
  { id:'land',     name:'Landscaping',    tag:'Design · Build · Maintain' },
  { id:'pest',     name:'Pest Control',   tag:'Recurring · Termite · WDI' },
  { id:'paint',    name:'Painting',       tag:'Interior · Exterior · Cabinet' },
  { id:'floor',    name:'Flooring',       tag:'Install · Refinish' },
  { id:'window',   name:'Windows & Doors',tag:'Replacement · Custom' },
  { id:'pool',     name:'Pool & Spa',     tag:'Build · Service · Repair' },
  { id:'irrig',    name:'Irrigation',     tag:'Install · Repair · Backflow' },
  { id:'chim',     name:'Chimney',        tag:'Sweep · Inspect · Repair' },
  { id:'handy',    name:'Handyman',       tag:'Small jobs · Recurring' },
  { id:'multi',    name:'Multi-Trade',    tag:'Two or more trades' },
];

const STRUCTURES = [
  { id:'sole',  label:'Sole proprietor', tag:'Just me' },
  { id:'sllc',  label:'Single-location LLC', tag:'One shop, one team' },
  { id:'mllc',  label:'Multi-location LLC', tag:'Regional reach' },
  { id:'scorp', label:'S-Corp', tag:'Owner-operator + payroll' },
  { id:'ptr',   label:'Partnership', tag:'Two or more owners' },
];

const YEARS_BANDS  = ['Under 2','2 – 5','5 – 10','10 – 20','20+'];
const REVENUE_TIERS = [
  { id:'r1', label:'Under $250K' },
  { id:'r2', label:'$250K – $500K' },
  { id:'r3', label:'$500K – $1M' },
  { id:'r4', label:'$1M – $2M' },
  { id:'r5', label:'$2M – $3M' },
  { id:'r6', label:'$3M – $5M' },
  { id:'r7', label:'$5M – $10M' },
  { id:'r8', label:'$10M+' },
];
const TEAM_BANDS = ['Just me','2 – 5','6 – 10','11 – 25','26 – 50','50+'];

const MIX_STREAMS = [
  { id:'res-service', label:'Residential service calls', def:35 },
  { id:'res-install', label:'Residential installs',      def:25 },
  { id:'com-service', label:'Commercial service',        def:10 },
  { id:'com-contract',label:'Commercial contracts',       def:5 },
  { id:'new-const',   label:'New construction',           def:5 },
  { id:'maint-agree', label:'Maintenance agreements',    def:15 },
  { id:'storm',       label:'Insurance & storm',          def:3 },
  { id:'warranty',    label:'Home warranty work',         def:2 },
];

const TOOLS_STACK = [
  { cat:'CRM / Field', items:['Housecall Pro','ServiceTitan','Jobber','FieldEdge','Service Fusion','Workiz'] },
  { cat:'Accounting',  items:['QuickBooks Online','QuickBooks Desktop','Xero','FreshBooks','Wave','Sage'] },
  { cat:'Ads',         items:['Google Ads','Meta Business','LSA','Angi','HomeAdvisor','Thumbtack'] },
  { cat:'Reputation',  items:['Podium','Birdeye','NiceJob','SocialPilot'] },
  { cat:'Calls',       items:['CallRail','RingCentral','Dialpad','OpenPhone'] },
  { cat:'Payroll',     items:['ADP','Gusto','Paychex','QB Payroll'] },
  { cat:'Fleet',       items:['Fleetio','Verizon Connect','Samsara'] },
];

const PAIN_POINTS = [
  { id:'pp01', label:"I don't know my real profit margin" },
  { id:'pp02', label:"My team doesn't close enough jobs" },
  { id:'pp03', label:"I can't tell if my ads are working" },
  { id:'pp04', label:"I'm the only one who can make decisions" },
  { id:'pp05', label:"Cash flow is unpredictable" },
  { id:'pp06', label:"I don't know what my business is worth" },
  { id:'pp07', label:"I can't find and keep good people" },
  { id:'pp08', label:"Customers aren't leaving reviews" },
  { id:'pp09', label:"I work 70 hours a week and feel behind" },
  { id:'pp10', label:"I have no plan if something happens to me" },
  { id:'pp11', label:"Past customers don't come back" },
  { id:'pp12', label:"Estimates take too long to send" },
  { id:'pp13', label:"Supply costs eat my margin" },
  { id:'pp14', label:"My techs go off-script on price" },
  { id:'pp15', label:"Permits and inspections slip through" },
  { id:'pp16', label:"Big jobs don't close — no financing flow" },
  { id:'pp17', label:"Competitors are out-ranking me" },
  { id:'pp18', label:"I don't show up in ChatGPT or Google AI" },
  { id:'pp19', label:"Callbacks are killing margins on certain techs" },
  { id:'pp20', label:"Maintenance agreements stall at renewal" },
];

const GOALS_12MO = [
  { id:'g-rev',   label:'Hit a specific revenue number' },
  { id:'g-hours', label:'Reduce hours worked' },
  { id:'g-team',  label:'Build a team that runs without me' },
  { id:'g-sell',  label:'Get ready to sell in 3 – 5 years' },
  { id:'g-area',  label:'Expand service area' },
  { id:'g-trade', label:'Add a new trade or service line' },
  { id:'g-marg',  label:'Improve profit margin' },
  { id:'g-rev5',  label:'Get more 5-star reviews' },
  { id:'g-domi',  label:'Dominate locally' },
  { id:'g-churn', label:'Reduce turnover' },
  { id:'g-rec',   label:'Build recurring revenue' },
];

/* ==================== PHASE 2: CONNECTIONS ==================== */

const CONNECTIONS = [
  { id:'bank',   group:'Bank',          name:'Banking · Plaid',          tag:'Cash flow, payroll, vendor spend, balances',
    options:['Business checking','Savings','Payroll account','Line of credit'], bi: 12 },
  { id:'qb',     group:'Accounting',    name:'QuickBooks Online',        tag:'Full P&L · invoices · expenses', bi: 10 },
  { id:'xero',   group:'Accounting',    name:'Xero',                     tag:'Full P&L · invoices · expenses', bi: 10 },
  { id:'hcp',    group:'CRM',           name:'Housecall Pro',            tag:'Jobs · customers · techs', bi: 14 },
  { id:'st',     group:'CRM',           name:'ServiceTitan',             tag:'Jobs · customers · dispatch', bi: 14 },
  { id:'jobber', group:'CRM',           name:'Jobber',                   tag:'Jobs · customers · invoicing', bi: 14 },
  { id:'fe',     group:'CRM',           name:'FieldEdge',                tag:'Jobs · service agreements', bi: 14 },
  { id:'gads',   group:'Ads',           name:'Google Ads',               tag:'Real cost-per-lead vs reported', bi: 8 },
  { id:'meta',   group:'Ads',           name:'Meta Business',            tag:'Facebook + Instagram spend & results', bi: 8 },
  { id:'gsc',    group:'Search',        name:'Google Search Console',    tag:'Rankings · queries · clicks', bi: 5 },
  { id:'gbp',    group:'Search',        name:'Google Business Profile',  tag:'Reviews · map pack · velocity', bi: 6 },
  { id:'adp',    group:'Payroll',       name:'ADP',                      tag:'True labor cost per job type', bi: 6 },
  { id:'gusto',  group:'Payroll',       name:'Gusto',                    tag:'True labor cost per job type', bi: 6 },
  { id:'callr',  group:'Calls',         name:'CallRail',                 tag:'Recordings · attribution · sentiment', bi: 5 },
  { id:'fleet',  group:'Fleet',         name:'Fleetio',                  tag:'Maintenance · cost-per-mile', bi: 4 },
  { id:'ferg',   group:'Supply',        name:'Ferguson · Supply House',  tag:'Purchase history · price tracking', bi: 4 },
];

const SCRAPE_TARGETS = [
  { label:'Your website',     detail:'Services, cities, speed, booking form, AI visibility' },
  { label:'Your reviews',     detail:'Every Google review · velocity · sentiment themes' },
  { label:'Top 5 competitors',detail:'Ratings · review count · ad presence · AI presence' },
  { label:'Directory presence',detail:'Yelp · Angi · HomeAdvisor · Thumbtack' },
  { label:'Social media',     detail:'Posting cadence · engagement · follower trend' },
  { label:'AI search presence',detail:'ChatGPT · Claude · Perplexity · Google AI' },
];

/* ==================== PHASE 3: DEPARTMENT BUILDER ==================== */

// Six departments × N modules. Each has a default agent name (editable).
const DEPARTMENTS = [
  { id:'comm', name:'Communications', tag:'Inbound, outbound, every channel', tone:'lilac',
    modules:[
      { id:'comm-ai-call', name:'AI Call Reception', agent:'Ivy',    why:'24/7 inbound · qualify · book', mo: 380, pain:['pp02','pp09'] },
      { id:'comm-text',    name:'Inbound Text & Chat', agent:'Bond',  why:'Web chat + SMS into bookings', mo: 180, pain:['pp02'] },
      { id:'comm-dm',      name:'Social DM Booking',   agent:'Crown', why:'Facebook + Instagram DMs to qualified leads', mo: 120, pain:['pp17'] },
      { id:'comm-followup',name:'Estimate Follow-Up Sequences', agent:'Flash', why:'Open estimates · cold leads · post-job', mo: 220, pain:['pp02'] },
      { id:'comm-reviews', name:'Review Request Engine', agent:'Star', why:'Timed asks · negative catch · response templates', mo: 140, pain:['pp08','pp17'] },
      { id:'comm-reactive',name:'Customer Reactivation', agent:'Chase', why:'18+ month customers back into pipeline', mo: 180, pain:['pp11'] },
    ]
  },
  { id:'ops', name:'Operations', tag:'Dispatch, jobs, quality', tone:'chart',
    modules:[
      { id:'ops-dispatch', name:'Smart Dispatch & Routing', agent:'Flash', why:'Right tech, right job, lowest drive', mo: 260, pain:['pp02'] },
      { id:'ops-monitor',  name:'Real-Time Job Monitor',    agent:'Pulse', why:'Late starts, stuck jobs, exception alerts', mo: 140, pain:['pp02'] },
      { id:'ops-sop',      name:'SOP & Checklist Engine',   agent:'Brief', why:'Job-type checklists · QA · photo proof', mo: 120, pain:['pp19'] },
      { id:'ops-callscore',name:'Call & Job Audio Scoring', agent:'Lens',  why:'Coaching notes back to techs', mo: 180, pain:['pp02','pp14'] },
      { id:'ops-callback', name:'Callback Analytics',       agent:'Pulse', why:'True cost-per-tech quality score', mo: 110, pain:['pp19'] },
      { id:'ops-permit',   name:'Permit & Inspection Tracker', agent:'Stamp', why:'Open permits · municipality SLAs', mo: 130, pain:['pp15'] },
    ]
  },
  { id:'fin', name:'Finance', tag:'Cash, margin, AR, pricing', tone:'chart',
    modules:[
      { id:'fin-cash',     name:'Cash Flow Sentinel',       agent:'Penny', why:'Predict crunches 45-60 days out', mo: 220, pain:['pp05','pp01'] },
      { id:'fin-margin',   name:'True Margin Engine',       agent:'Tide',  why:'Margin by service, tech, neighborhood', mo: 240, pain:['pp01','pp13'] },
      { id:'fin-billing',  name:'Invoice & Billing Automation', agent:'Memo', why:'Send · remind · escalate', mo: 160, pain:['pp01'] },
      { id:'fin-collect',  name:'Collections & AR Engine',  agent:'Memo',  why:'Aging buckets · slow-pay flags', mo: 140, pain:['pp01','pp05'] },
      { id:'fin-rev',      name:'Revenue Forecast & Targets', agent:'Rev',  why:'Plan vs actual, live to plan', mo: 180, pain:['pp05'] },
      { id:'fin-price',    name:'Dynamic Pricing Engine',   agent:'Bid',   why:'Job-by-job recommended price', mo: 260, pain:['pp14','pp13'] },
      { id:'fin-fin',      name:'Financing Prompt',         agent:'Capital',why:'Field financing on jobs over threshold', mo: 120, pain:['pp16'] },
    ]
  },
  { id:'grow', name:'Growth', tag:'Demand, market, retention', tone:'lilac',
    modules:[
      { id:'grow-scout',   name:'Competitor Intelligence',  agent:'Scout', why:'Top 5 watched · alerts on change', mo: 140, pain:['pp17'] },
      { id:'grow-spark',   name:'Growth Opportunity Engine',agent:'Spark', why:'Priority order by dollar impact', mo: 180, pain:['pp03','pp17'] },
      { id:'grow-geo',     name:'GEO & AI Search Dominance',agent:'Atlas', why:'Show up in ChatGPT, Claude, Perplexity', mo: 200, pain:['pp18','pp17'] },
      { id:'grow-pipe',    name:'Lead Nurture Pipeline',    agent:'Flash', why:'Configurable stages · auto at every step', mo: 160, pain:['pp02'] },
      { id:'grow-refer',   name:'Referral Engine',          agent:'Bond',  why:'Track, reward, thank automatically', mo: 110, pain:['pp17'] },
      { id:'grow-real',    name:'Real-Estate Trigger Campaigns', agent:'Rex', why:'Outreach when homes sell in your area', mo: 140, pain:['pp17'] },
    ]
  },
  { id:'ppl', name:'People', tag:'Hire, certify, retain', tone:'lilac',
    modules:[
      { id:'ppl-recruit',  name:'Recruitment & ATS',        agent:'Hire',  why:'Screen, schedule, fill the pipe', mo: 140, pain:['pp07'] },
      { id:'ppl-cred',     name:'Credential & Compliance',  agent:'Guard', why:'NATE, EPA, OSHA, journeyman, drug, BG', mo: 120, pain:['pp15'] },
      { id:'ppl-train',    name:'Training & Knowledge Base',agent:'Brain', why:'Required paths by role · completion', mo: 110, pain:['pp07'] },
      { id:'ppl-brief',    name:'Team Briefings',           agent:'Brief', why:'Morning huddle · weekly recap', mo: 80,  pain:['pp04'] },
      { id:'ppl-retain',   name:'Retention Signal Watch',   agent:'Retain',why:'Pre-resignation early warning', mo: 130, pain:['pp07'] },
    ]
  },
  { id:'inf', name:'Infrastructure', tag:'Glue, security, custom', tone:'chart',
    modules:[
      { id:'inf-hub',      name:'Integration Hub',          agent:'Bridge',why:'Health-check every connection', mo: 80,  pain:[] },
      { id:'inf-vault',    name:'Backup & Security',        agent:'Vault', why:'Daily snapshots · access policies', mo: 60,  pain:['pp10'] },
      { id:'inf-anomaly',  name:'Anomaly & BI Detection',   agent:'Sense', why:'Anything that deviates beyond threshold', mo: 140, pain:['pp01','pp03'] },
      { id:'inf-spend',    name:'Marketing Spend Optimizer',agent:'Blaze', why:'Per-campaign guardrails · pause logic', mo: 130, pain:['pp03'] },
      { id:'inf-photo',    name:'Photo & Documentation',    agent:'Frame', why:'Photo requirements by job type', mo: 60,  pain:[] },
      { id:'inf-custom',   name:'Custom Automation Builder',agent:'Forge', why:'Plain-language rule builder · unlimited', mo: 220, pain:[] },
    ]
  },
];

/* ==================== PHASE 4: AUTOMATIONS ==================== */

// Categories with sample automations (sentence form). Counts as advertised in spec.
const AUTOMATION_CATEGORIES = [
  { id:'cust',  name:'Customer Communication', count:47, sample:[
    'When a new lead comes in, respond within 60 seconds across SMS, email, and chat.',
    'Confirm every appointment 24 hours and 2 hours before the visit.',
    'Send an On-the-way text with live tech location when a job is dispatched.',
    'After a job completes, send a personal thank-you with a payment receipt.',
    'Check in with every customer at their 6-month, 12-month, and anniversary date.',
    'When equipment passes 12 years old, trigger a replacement-conversation sequence.',
  ]},
  { id:'lead',  name:'Lead Nurture', count:31, sample:[
    'If an estimate is opened but not responded to in 48 hours, send a soft nudge.',
    'On a rejected estimate, ask the one question that surfaces the real objection.',
    'Ghost leads get reactivation messages at 7, 14, and 30 days with different angles.',
    'Lost jobs come back with a win-back offer at 90 days.',
    'Price-objection leads enter a value-stacking sequence over 14 days.',
  ]},
  { id:'jobs',  name:'Jobs & Operations', count:38, sample:[
    'Notify dispatch immediately when a tech is running more than 15 minutes late.',
    'When a job is marked complete, push the summary, photos, and next step to the customer.',
    'If a tech misses a check-in window, escalate to dispatcher within 10 minutes.',
    'When a job requires a permit, file the application and track inspection date.',
    'On emergency dispatch, override route logic and pull the closest qualified tech.',
  ]},
  { id:'fin',   name:'Finance & Collections', count:29, sample:[
    'Send the invoice the moment a job is marked complete with photos attached.',
    'At 7 days: soft reminder. 14 days: firm. 30 days: escalation. 60 days: owner pings.',
    'Flag commercial clients pushing 75 days before the next job is dispatched.',
    'Auto-document slow-pay history on every customer record.',
    'Alert the owner if AR over 60 days exceeds a configurable threshold.',
  ]},
  { id:'rev',   name:'Review & Reputation', count:18, sample:[
    'Send the review request 2 hours after a service call, 48 hours after a big install.',
    'Catch negative-experience signals before they post publicly.',
    'Match every positive review with a personalized response within 24 hours.',
    'Alert the owner instantly on any review below 4 stars.',
    'Celebrate review milestones with the technician who earned them.',
  ]},
  { id:'team',  name:'Team & HR', count:22, sample:[
    'Onboard new hires through a 30-day milestone-based sequence.',
    'Chain certification renewals at 90 / 60 / 30 days.',
    'Alert the owner when any tech\'s close rate drops more than 15% in 30 days.',
    'Celebrate anniversaries and milestones automatically.',
    'Trigger a check-in when a tech\'s callback rate spikes.',
  ]},
  { id:'mkt',   name:'Growth & Marketing', count:34, sample:[
    'When a home in your service area sells, trigger an age-based outreach.',
    'Launch seasonal campaigns 6 weeks before historical demand surges.',
    'Pause Google Ads spending on any campaign with cost-per-job above 18%.',
    'Trigger maintenance-agreement renewals 45 days before expiration.',
    'When a competitor gains reviews faster than you for 30 days, trigger your push.',
  ]},
  { id:'comp',  name:'Compliance & Risk', count:16, sample:[
    'License renewals chain at 90, 60, and 30 days with task assignment.',
    'Insurance expirations alert 60 days out to the responsible person.',
    'Subcontractor COIs auto-request 30 days before expiration.',
    'Lien-waiver tracking by job and milestone.',
    'Workers-comp audit preparation auto-bundles documentation.',
  ]},
  { id:'own',   name:'Owner Intelligence', count:24, sample:[
    'Morning briefing delivered at a chosen time with the day\'s 5 most important numbers.',
    'Weekly business briefing summarizes wins, gaps, and the next move.',
    'Cash crunch alert fires 45 days before a projected dip.',
    'Monthly valuation update with three moves that would increase the number.',
    'Anomaly alert on any metric drifting beyond owner-set sensitivity.',
  ]},
  { id:'pred',  name:'Predictive', count:19, sample:[
    'Pre-season demand surge prep starts marketing 6 weeks before historical patterns.',
    'Customer churn prevention fires before they call your competitor.',
    'Equipment replacement timing predicted from age, service history, and weather.',
    'Cash-crisis prevention protocols activate 45 days before a projected crunch.',
    'Weather-event response campaigns auto-launch on storm tracking.',
  ]},
];

/* ==================== PHASE 5: DASHBOARDS ==================== */

const DASH_WIDGETS = {
  owner:[
    { id:'ow-rev',     label:'Revenue waterfall · actual vs target' },
    { id:'ow-cash',    label:'Cash flow projection · 90 days' },
    { id:'ow-close',   label:'Close rate by team member · drill-down' },
    { id:'ow-map',     label:'Active jobs live map' },
    { id:'ow-sent',    label:'Customer sentiment score · trending' },
    { id:'ow-leads',   label:'Lead source breakdown · cost-per-lead' },
    { id:'ow-rev-vel', label:'Review velocity chart' },
    { id:'ow-maint',   label:'Maintenance-agreement pipeline' },
    { id:'ow-ar',      label:'Accounts receivable aging' },
    { id:'ow-comp',    label:'Competitor rating comparison' },
    { id:'ow-val',     label:'Business valuation estimate (monthly)' },
    { id:'ow-hours',   label:'Owner hours worked vs target' },
    { id:'ow-deleg',   label:'Decisions made that could be delegated' },
  ],
  office:[
    { id:'of-sched',   label:"Today's job schedule" },
    { id:'of-leads',   label:'Unresponded leads' },
    { id:'of-est',     label:'Open estimates over 48 hours' },
    { id:'of-locs',    label:'Team member locations' },
    { id:'of-permits', label:'Permits pending inspection' },
    { id:'of-cb',      label:'Customer callbacks needed' },
    { id:'of-ar',      label:'Invoices overdue' },
    { id:'of-cois',    label:'Sub COIs expiring' },
    { id:'of-inbox',   label:'Inbound communication queue' },
  ],
  tech:[
    { id:'tc-list',    label:'Job list with navigation' },
    { id:'tc-hist',    label:'Customer history before arrival' },
    { id:'tc-check',   label:'Required documentation checklist' },
    { id:'tc-fin',     label:'Financing presentation tool' },
    { id:'tc-perf',    label:'Personal performance metrics' },
    { id:'tc-parts',   label:'Parts needed per job' },
    { id:'tc-msg',     label:'Customer communication templates' },
    { id:'tc-photo',   label:'Photo capture & upload' },
    { id:'tc-sign',    label:'Digital sign-off collection' },
  ],
};

/* ==================== PHASE 7: COMPLIANCE ==================== */

const COMPLIANCE_ITEMS = [
  { cat:'Licenses', items:['State contractor license','EPA 608 (HVAC)','Backflow certification','Journeyman','Master license'] },
  { cat:'Insurance', items:['General liability','Workers compensation','Commercial auto','Umbrella','Errors & omissions'] },
  { cat:'Employee certs', items:['NATE','OSHA 10','OSHA 30','Drug test currency','Background check'] },
  { cat:'Subcontractors', items:['Active sub list','COIs on file','License copies','Performance ratings'] },
  { cat:'Permits & inspections', items:['Permits by job type','Municipality SLAs','Closure documentation'] },
  { cat:'Continuity', items:['Owner emergency plan','Bank signing authority','Critical credential vault','Vendor escalation list'] },
];

/* ==================== PHASE 8: ROLES & PERMISSIONS ==================== */

const ROLES = [
  { id:'owner',  name:'Owner' },
  { id:'gm',     name:'General Manager' },
  { id:'office', name:'Office Manager' },
  { id:'disp',   name:'Dispatcher' },
  { id:'lead',   name:'Lead Technician' },
  { id:'tech',   name:'Technician' },
  { id:'app',    name:'Apprentice' },
  { id:'sales',  name:'Sales' },
  { id:'book',   name:'Bookkeeper' },
  { id:'sub',    name:'Subcontractor' },
];

const PERM_FEATURES = [
  'See financial dashboards',
  'Edit pricing & margin',
  'See customer payment history',
  'Run reports & export',
  'Configure automations',
  'Approve refunds',
  'Edit team & permissions',
  'See competitor intelligence',
  'See team performance comparisons',
  'Send outbound campaigns',
  'Override AI recommendations',
  'View business valuation',
];

/* ==================== PHASE 10: PREDICTIVE ==================== */

const PREDICTIVE_MODELS = [
  { id:'pm-cash',   name:'Cash crisis prediction',         desc:'Project 45-90 days out' },
  { id:'pm-churn',  name:'Customer churn prediction',      desc:'Before they call a competitor' },
  { id:'pm-attr',   name:'Technician attrition signal',    desc:'Pre-resignation early warning' },
  { id:'pm-demand', name:'Demand surge forecasting',       desc:'Weather + season + market' },
  { id:'pm-realest',name:'Real-estate trigger campaigns',  desc:'New homeowner outreach' },
  { id:'pm-equip',  name:'Equipment replacement timing',   desc:'Age + service + weather' },
  { id:'pm-warr',   name:'Home-warranty upsell timing',    desc:'When the warranty profile shifts' },
];

const ANOMALY_CATEGORIES = [
  'Revenue drop week over week',
  'Close rate change beyond threshold',
  'Callback rate spike',
  'Customer complaint pattern forming',
  'Ad spend without lead increase',
  'Team-member performance change',
  'Cash flow deviation from projection',
  'Competitor rating change',
  'Review velocity shift',
];

/* ==================== PHASE 12: PRICING ==================== */

// Returns a per-phase computation given the answers blob.
function osBuilderPricing(state) {
  // Base setup + monthly retainer scale with revenue tier and active modules.
  const tier = state.identity?.revenue || 'r3';
  const tierIdx = REVENUE_TIERS.findIndex(t => t.id === tier);
  const baseSetup    = [4500, 6500, 9500, 12500, 17500, 22500, 29500, 38500][Math.max(0, tierIdx)];
  const baseRetainer = [ 850, 1200, 1750, 2500,  3450,  4500,  5800,  7400][Math.max(0, tierIdx)];

  // Module add-ons.
  const activeModules = state.modules ? Object.entries(state.modules).filter(([,v])=>v).map(([k])=>k) : [];
  const moduleMonthly = DEPARTMENTS.flatMap(d=>d.modules)
    .filter(m => activeModules.includes(m.id))
    .reduce((s, m) => s + m.mo, 0);

  // Automations add small per-bundle costs.
  const activeAutos = state.automations ? Object.entries(state.automations).filter(([,v])=>v).map(([k])=>k) : [];
  const autoMonthly = activeAutos.length * 25;

  // Connections.
  const activeConnects = state.connections ? Object.entries(state.connections).filter(([,v])=>v).map(([k])=>k) : [];

  // BI score: connections + modules + automations.
  const bi = Math.min(100,
    activeConnects.reduce((s,id)=>s + ((CONNECTIONS.find(c=>c.id===id)||{}).bi || 0), 0)
    + Math.round(activeModules.length * 1.5)
    + Math.round(activeAutos.length * 0.5)
  );

  // ROI projection — fairly bold but bounded.
  const revBase = [180000, 360000, 720000, 1500000, 2500000, 4000000, 7000000, 14000000][Math.max(0, tierIdx)];
  const moduleLift = Math.min(0.42, activeModules.length * 0.012);
  const autoLift   = Math.min(0.18, activeAutos.length   * 0.004);
  const liftPct    = moduleLift + autoLift;
  const liftDollars = Math.round(revBase * liftPct);

  const successFeeRate = 0.05;
  const successFeeYr   = Math.round(liftDollars * successFeeRate);

  return {
    setup: baseSetup,
    retainer: baseRetainer + moduleMonthly + autoMonthly,
    moduleMonthly,
    autoMonthly,
    moduleCount: activeModules.length,
    automationCount: activeAutos.length,
    connectionCount: activeConnects.length,
    bi,
    liftPct,
    liftDollars,
    successFeeYr,
    revBase,
  };
}

/* Expose */
Object.assign(window, {
  TRADES, STRUCTURES, YEARS_BANDS, REVENUE_TIERS, TEAM_BANDS,
  MIX_STREAMS, TOOLS_STACK, PAIN_POINTS, GOALS_12MO,
  CONNECTIONS, SCRAPE_TARGETS, DEPARTMENTS, AUTOMATION_CATEGORIES,
  DASH_WIDGETS, COMPLIANCE_ITEMS, ROLES, PERM_FEATURES,
  PREDICTIVE_MODELS, ANOMALY_CATEGORIES, osBuilderPricing,
});