// ============================================================
// ROI CALCULATOR · math + inputs
// Math is preserved 1:1 from the original calculator.
// ============================================================

// ---------- MATH ----------
const ROI_CONV_STEPS = (() => {
  const arr = [];
  for (let v = 0; v <= 100000; v += 10000) arr.push(v);
  for (let v = 150000; v <= 2000000; v += 50000) arr.push(v);
  return arr;
})();

const ROI_TIER_BREAKS = [0, 6000, 12000, 21000, 30000, 42000, 50000, 100000, 250000, 500000, 750000, 1000000, 1500000, 2000000];
const ROI_TIER_COSTS  = [0, 12000, 18240, 21600, 27300, 30600, 35100, 54600, 107500, 164500, 218000, 252500, 283500, 304500];

function roiGetConvCostYearly(conv) {
  if (conv <= 0) return 0;
  for (let i = 0; i < ROI_TIER_BREAKS.length - 1; i++) {
    if (conv <= ROI_TIER_BREAKS[i + 1]) {
      const ratio = (conv - ROI_TIER_BREAKS[i]) / (ROI_TIER_BREAKS[i + 1] - ROI_TIER_BREAKS[i]);
      return ROI_TIER_COSTS[i] + ratio * (ROI_TIER_COSTS[i + 1] - ROI_TIER_COSTS[i]);
    }
  }
  return ROI_TIER_COSTS[ROI_TIER_COSTS.length - 1];
}

function roiCompute(state) {
  const score = state.axis1 + state.axis2;
  const impl = 15000 + score * 2500;
  const baseMonthlyFee = 1500 + score * 250;
  const convCostMonthly = roiGetConvCostYearly(state.conversations) / 12;
  const monthlyFee = baseMonthlyFee + convCostMonthly;
  const returnPerFte = baseMonthlyFee * 3;
  const totalReturnPerAgent = returnPerFte * state.fte;
  const netPerEarningMonth = (totalReturnPerAgent - monthlyFee) * state.agents;
  const totalImpl = impl * state.agents;
  const breakeven = netPerEarningMonth > 0
    ? state.ramp + Math.ceil((totalImpl + monthlyFee * state.agents * state.ramp) / netPerEarningMonth)
    : Infinity;
  const earningMonthsY1 = Math.max(0, 12 - state.ramp);
  const yearlyInvestment = totalImpl + monthlyFee * state.agents * 12;
  const yearlyRevenue = totalReturnPerAgent * state.agents * earningMonthsY1;
  const yearlyNet = yearlyRevenue - yearlyInvestment;
  // ROI year 1 (%): yearlyNet / yearlyInvestment
  const roiPct = yearlyInvestment > 0 ? (yearlyNet / yearlyInvestment) * 100 : 0;
  return {
    impl, monthlyFee, totalReturnPerAgent, baseMonthlyFee, convCostMonthly,
    netPerEarningMonth, totalImpl, breakeven,
    yearlyInvestment, yearlyRevenue, yearlyNet, roiPct,
    monthlyFeeTotal: monthlyFee * state.agents,
    totalRevenuePerMonth: totalReturnPerAgent * state.agents,
  };
}

function roiFormatEUR(value, opts = {}) {
  const { sign = false, k = false } = opts;
  if (!isFinite(value)) return '∞';
  if (k && Math.abs(value) >= 10000) {
    const v = value / 1000;
    return '€ ' + (sign && v > 0 ? '+' : '') + new Intl.NumberFormat('nl-NL', {
      minimumFractionDigits: 0, maximumFractionDigits: v < 100 ? 1 : 0
    }).format(v) + 'k';
  }
  return '€ ' + (sign && value > 0 ? '+' : '') + new Intl.NumberFormat('nl-NL', {
    minimumFractionDigits: 0, maximumFractionDigits: 0
  }).format(Math.round(value));
}

// FTE-mapping op basis van axis2 (aantal betrokken personen)
//   0 = 1-2 personen → 1.0 FTE
//   1 = 3-5 personen → 1.5 FTE
//   2 = >5 personen  → 2.0 FTE
function roiDeriveFte(axis2) {
  return [1.0, 1.5, 2.0][axis2] ?? 1.0;
}

// ---------- DEFAULT STATE ----------
const ROI_DEFAULT_STATE = {
  dept: 'sales',
  conversations: 0,
  axis1: 1,
  axis2: 1,
  agents: 1,
  fte: 1.5,
  ramp: 3,
};

// ---------- COMPONENTS ----------

function RoiSegment({ value, onChange, options, columns }) {
  return (
    <div className="roi-segment" style={{ '--cols': columns || options.length }}>
      {options.map(opt => (
        <button
          key={opt.value}
          type="button"
          className={value === opt.value ? 'active' : ''}
          onClick={() => onChange(opt.value)}
        >
          {opt.label}
        </button>
      ))}
    </div>
  );
}

function RoiDeptSegment({ value, onChange }) {
  const options = [
    { value: 'sales', label: 'Sales' },
    { value: 'administratie', label: 'Administratie' },
    { value: 'operatie', label: 'Operatie' },
    { value: 'klantservice', label: 'Klantservice' },
  ];
  return (
    <div className="roi-segment depts" style={{ '--cols': 4 }}>
      {options.map(opt => (
        <button
          key={opt.value}
          type="button"
          className={value === opt.value ? 'active' : ''}
          onClick={() => onChange(opt.value)}
        >
          {opt.label}
        </button>
      ))}
    </div>
  );
}

function RoiSlider({ min, max, step, value, onChange, ticks }) {
  const pct = ((value - min) / (max - min)) * 100;
  return (
    <React.Fragment>
      <input
        type="range"
        className="roi-slider"
        min={min} max={max} step={step}
        value={value}
        onChange={(e) => onChange(parseFloat(e.target.value))}
        style={{ '--value': pct + '%' }}
      />
      {ticks && (
        <div className="roi-slider-ticks">
          {ticks.map((t, i) => {
            const pos = ((t.value - min) / (max - min)) * 100;
            return (
              <span key={i} className="t" style={{ left: pos + '%' }}>
                {t.label}
              </span>
            );
          })}
        </div>
      )}
    </React.Fragment>
  );
}

function RoiInputs({ state, setState }) {
  // Hidden fields agents / fte / ramp staan vast op de defaults; alleen segmenten
  // (afdeling / systemen / personen / [conversaties bij klantservice]) zijn zichtbaar.
  // FTE wordt afgeleid van axis2.
  const setAxis = (k) => (v) => setState(s => {
    const next = { ...s, [k]: v };
    if (k === 'axis2') next.fte = roiDeriveFte(v);
    return next;
  });
  const setDept = (dept) => {
    setState(s => ({
      ...s,
      dept,
      conversations: dept === 'klantservice' ? s.conversations : 0,
    }));
  };
  const reset = () => setState({ ...ROI_DEFAULT_STATE });

  const convIdx = ROI_CONV_STEPS.indexOf(state.conversations);
  const convPos = convIdx >= 0 ? convIdx : 0;

  return (
    <aside className="roi-inputs">
      <div className="roi-inputs-head">
        <div className="eyebrow-big"><span className="bar"></span>Jouw situatie</div>
        <h2>Schuif &amp; klik.<br/>De cijfers volgen.</h2>
        <p>Alles loopt live mee. Pas aan tot het past bij jouw bedrijf.</p>
      </div>

      <div className="roi-field">
        <div className="roi-field-head">
          <span className="roi-field-label">Afdeling</span>
        </div>
        <RoiDeptSegment value={state.dept} onChange={setDept} />
      </div>

      {state.dept === 'klantservice' && (
        <div className="roi-field">
          <div className="roi-field-head">
            <span className="roi-field-label">Conversaties per jaar</span>
            <span className="roi-field-value">{state.conversations.toLocaleString('nl-NL')}</span>
          </div>
          <RoiSlider
            min={0} max={ROI_CONV_STEPS.length - 1} step={1}
            value={convPos}
            onChange={(idx) => setState(s => ({ ...s, conversations: ROI_CONV_STEPS[idx] || 0 }))}
            ticks={[{value: 0, label: '0'}, {value: 16, label: '400k'}, {value: 32, label: '1.2M'}, {value: ROI_CONV_STEPS.length - 1, label: '2M'}]}
          />
        </div>
      )}

      <div className="roi-field">
        <div className="roi-field-head">
          <span className="roi-field-label">Aantal betrokken systemen</span>
        </div>
        <RoiSegment
          value={state.axis1}
          onChange={setAxis('axis1')}
          options={[
            { value: 0, label: '1–2' },
            { value: 1, label: '3–4' },
            { value: 2, label: '> 4' },
          ]}
        />
      </div>

      <div className="roi-field">
        <div className="roi-field-head">
          <span className="roi-field-label">Aantal betrokken personen</span>
        </div>
        <RoiSegment
          value={state.axis2}
          onChange={setAxis('axis2')}
          options={[
            { value: 0, label: '1–2' },
            { value: 1, label: '3–5' },
            { value: 2, label: '> 5' },
          ]}
        />
      </div>

      <button type="button" className="roi-reset" onClick={reset}>
        <span aria-hidden="true">↺</span> Reset naar standaard
      </button>
    </aside>
  );
}

// ---------- Animated counter ----------
function useAnimatedNumber(value, duration = 600) {
  const [display, setDisplay] = React.useState(value);
  const fromRef = React.useRef(value);
  const startRef = React.useRef(0);
  React.useEffect(() => {
    fromRef.current = display;
    startRef.current = performance.now();
    let raf;
    const tick = (t) => {
      const elapsed = t - startRef.current;
      const p = Math.min(1, elapsed / duration);
      // Ease out cubic
      const eased = 1 - Math.pow(1 - p, 3);
      const next = fromRef.current + (value - fromRef.current) * eased;
      setDisplay(next);
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
    // eslint-disable-next-line
  }, [value]);
  return display;
}

Object.assign(window, {
  ROI_DEFAULT_STATE, ROI_CONV_STEPS, roiCompute, roiFormatEUR, roiDeriveFte,
  RoiInputs, useAnimatedNumber,
});
