/* RheinDA online price calculator */
const { useState, useMemo, useRef, useEffect } = React;

const SERVICES = [
  { id:'fenster',       title:'Fenster',       sub:'& Glasreinigung' },
  { id:'garten',        title:'Garten',        sub:'& Landschaft'    },
  { id:'entruempelung', title:'Entrümpelung',  sub:'& Auflösung'     },
  { id:'reparatur',     title:'Reparatur',     sub:'kleinere Arbeiten' },
  { id:'montage',       title:'Montage',       sub:'Möbel & Geräte'  },
];

const ICONS = {
  fenster: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
      <rect x="3" y="3" width="18" height="18" rx="1"/><path d="M3 12h18M12 3v18"/>
    </svg>
  ),
  garten: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
      <path d="M12 22V10"/><path d="M12 10c0-4 3-7 8-7-1 5-4 8-8 7z"/><path d="M12 14c0-3-2-5-6-5 1 3 3 6 6 5z"/>
    </svg>
  ),
  entruempelung: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
      <rect x="4" y="7" width="14" height="12" rx="1"/><path d="M18 11h3v8h-3"/>
      <circle cx="9" cy="20" r="1.5"/><circle cx="17" cy="20" r="1.5"/>
    </svg>
  ),
  reparatur: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
      <path d="M14.5 4l5.5 5.5-3 3-5.5-5.5z"/><path d="M11 7L3 15v4h4l8-8"/>
    </svg>
  ),
  montage: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
      <rect x="3" y="3" width="8" height="8" rx="1"/><rect x="13" y="3" width="8" height="8" rx="1"/>
      <rect x="3" y="13" width="8" height="8" rx="1"/><rect x="13" y="13" width="8" height="8" rx="1"/>
    </svg>
  ),
};

const DEFAULTS = {
  fenster:       { count: 8, side: 'beides', frames: true, floors: 1 },
  garten:        { size: 200, tasks: ['rasen'], hedge: 10, recurring: 'einmalig' },
  entruempelung: { rooms: 2, fill: 'normal', sperrmuell: false },
  reparatur:     { hours: 'short', material: 'mit' },
  montage:       { type: 'schrank', count: 1 },
};

function calcPrice(s, p) {
  let mid = 0;
  if (s === 'fenster') {
    mid = p.count <= 8 ? 10 * p.count : 80 + 5 * (p.count - 8);
    if (p.side !== 'beides') mid *= 0.7;
    if (p.frames) mid *= 1.15;
    mid *= 1 + (p.floors - 1) * 0.12;
  } else if (s === 'garten') {
    if (p.tasks.includes('rasen')) mid += 50 + p.size * 0.35;
    if (p.tasks.includes('hecke')) mid += 30 + Math.max(0, p.hedge) * 4;
    if (p.tasks.includes('beet'))  mid += 80;
    if (mid === 0) mid = 80;
    if (p.recurring === 'monatlich') mid *= 0.78;
  } else if (s === 'entruempelung') {
    const per = [0, 250, 400, 550, 700, 840, 970, 1080, 1180];
    mid = per[Math.min(p.rooms, 8)] || p.rooms * 150;
    if (p.fill === 'voll') mid *= 1.4;
    else if (p.fill === 'leer') mid *= 0.7;
    if (p.sperrmuell) mid += 120;
  } else if (s === 'reparatur') {
    mid = ({ short: 90, half: 220, full: 380 })[p.hours] || 90;
    if (p.material === 'durch_uns') mid += 60;
  } else if (s === 'montage') {
    const u = { schrank: 80, bett: 95, kueche: 280, lampen: 45, anderes: 90 };
    mid = (u[p.type] || 80) * p.count;
    if (p.type === 'kueche' && p.count > 1) mid *= 1.2;
  }
  mid = Math.max(40, Math.round(mid));
  const r5 = (n) => Math.round(n / 5) * 5;
  return { mid: r5(mid), low: r5(mid * 0.88), high: r5(mid * 1.18) };
}

function summary(s, p) {
  if (s === 'fenster')
    return `${p.count} Fenster, ${p.side === 'beides' ? 'innen & außen' : (p.side === 'innen' ? 'nur innen' : 'nur außen')}, ${p.frames ? 'mit Rahmen' : 'ohne Rahmen'}, ${p.floors} ${p.floors === 1 ? 'Etage' : 'Etagen'}`;
  if (s === 'garten') {
    const tnames = { rasen:'Rasenpflege', hecke:'Heckenschnitt', beet:'Beetpflege' };
    const tasks = p.tasks.map(t => tnames[t]).join(', ') || 'allgemeine Pflege';
    return `${p.size} m², ${tasks}${p.tasks.includes('hecke') ? `, Hecke ca. ${p.hedge} m` : ''}, ${p.recurring === 'monatlich' ? 'regelmäßig (monatlich)' : 'einmalig'}`;
  }
  if (s === 'entruempelung')
    return `${p.rooms} ${p.rooms === 1 ? 'Raum' : 'Räume'}, Füllung „${p.fill}"${p.sperrmuell ? ', inkl. Sperrmüll' : ''}`;
  if (s === 'reparatur') {
    const h = { short: 'unter 2 Stunden', half: 'halber Tag', full: 'ganzer Tag' }[p.hours];
    return `Aufwand ${h}, Material ${p.material === 'mit' ? 'durch mich' : 'durch RheinDA'}`;
  }
  if (s === 'montage') {
    const n = { schrank:'Schrank', bett:'Bett', kueche:'Küche', lampen:'Lampen', anderes:'Anderes' }[p.type];
    return `${p.count}× ${n}`;
  }
  return '';
}

function bullets(s, p) {
  if (s === 'fenster')
    return [
      `${p.count} Fenster · ${p.side === 'beides' ? 'innen & außen' : p.side === 'innen' ? 'nur innen' : 'nur außen'}`,
      `${p.frames ? 'Rahmen inklusive' : 'ohne Rahmenreinigung'}`,
      `${p.floors} ${p.floors === 1 ? 'Etage' : 'Etagen'} · Köln & Umgebung`,
    ];
  if (s === 'garten') {
    const t = { rasen:'Rasen', hecke:`Hecke ${p.hedge} m`, beet:'Beete' };
    return [
      `Grundstück ${p.size} m²`,
      `Leistungen: ${p.tasks.length ? p.tasks.map(x => t[x]).join(' · ') : 'individuell'}`,
      p.recurring === 'monatlich' ? 'Regelmäßig (monatlich)' : 'Einmaliger Einsatz',
    ];
  }
  if (s === 'entruempelung')
    return [
      `${p.rooms} ${p.rooms === 1 ? 'Raum' : 'Räume'} · Füllung „${p.fill}"`,
      `${p.sperrmuell ? 'Inkl. Sperrmüll-Entsorgung' : 'Sperrmüll separat'}`,
      'Mit Entsorgungsnachweis',
    ];
  if (s === 'reparatur') {
    const h = { short:'Unter 2 Stunden', half:'Halber Tag (2–4 h)', full:'Ganzer Tag (4–8 h)' }[p.hours];
    return [ h, p.material === 'mit' ? 'Material durch Sie' : 'Material besorgen wir', 'Anfahrt inklusive (Köln)' ];
  }
  if (s === 'montage') {
    const n = { schrank:'Schrank-Aufbau', bett:'Bett-Aufbau', kueche:'Küchen-Montage', lampen:'Lampen-Montage', anderes:'Individuelle Montage' }[p.type];
    return [ `${p.count}× ${n}`, 'Werkzeug bringen wir mit', 'Verpackung entsorgen wir' ];
  }
  return [];
}

/* ── Animated counter ───────────────────────────────────────────── */
function useCounter(target, duration = 380) {
  const [val, setVal] = useState(target);
  const ref = useRef(target);
  const rafRef = useRef(0);
  useEffect(() => {
    cancelAnimationFrame(rafRef.current);
    const from = ref.current;
    const start = performance.now();
    const tick = (t) => {
      const k = Math.min(1, (t - start) / duration);
      const e = 1 - Math.pow(1 - k, 3);
      const v = Math.round(from + (target - from) * e);
      setVal(v);
      ref.current = v;
      if (k < 1) rafRef.current = requestAnimationFrame(tick);
    };
    rafRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(rafRef.current);
  }, [target, duration]);
  return val;
}

/* ── Input atoms ────────────────────────────────────────────────── */
function CalcSlider({ value, min, max, step = 1, onChange, label, unit, hint }) {
  const pct = ((value - min) / (max - min)) * 100;
  return (
    <div className="calc-field">
      <div className="calc-flbl">
        <span>{label}</span>
        <span className="calc-flbl-v">{value}{unit ? <em>{unit}</em> : null}</span>
      </div>
      <input type="range" min={min} max={max} step={step} value={value}
             onChange={(e) => onChange(+e.target.value)}
             className="calc-slider" style={{ '--pct': pct + '%' }} />
      {hint && <div className="calc-hint">{hint}</div>}
    </div>
  );
}

function CalcRadio({ value, options, onChange, label }) {
  return (
    <div className="calc-field">
      <div className="calc-flbl"><span>{label}</span></div>
      <div className="calc-radio">
        {options.map((o) => (
          <button key={o.v} type="button"
                  className={`calc-pill${value === o.v ? ' on' : ''}`}
                  onClick={() => onChange(o.v)}>{o.l}</button>
        ))}
      </div>
    </div>
  );
}

function CalcMulti({ value, options, onChange, label }) {
  const has = (v) => value.includes(v);
  const toggle = (v) => onChange(has(v) ? value.filter((x) => x !== v) : [...value, v]);
  return (
    <div className="calc-field">
      <div className="calc-flbl"><span>{label}</span></div>
      <div className="calc-radio">
        {options.map((o) => (
          <button key={o.v} type="button"
                  className={`calc-pill${has(o.v) ? ' on' : ''}`}
                  onClick={() => toggle(o.v)}>{o.l}</button>
        ))}
      </div>
    </div>
  );
}

function CalcToggle({ value, onChange, label, hint }) {
  return (
    <div className="calc-field calc-field-row">
      <div>
        <div className="calc-flbl"><span>{label}</span></div>
        {hint && <div className="calc-hint">{hint}</div>}
      </div>
      <button type="button"
              className={`calc-toggle${value ? ' on' : ''}`}
              onClick={() => onChange(!value)}
              aria-pressed={value}>
        <span className="calc-toggle-knob"></span>
      </button>
    </div>
  );
}

function CalcStepper({ value, min = 1, max = 10, onChange, label, unit }) {
  return (
    <div className="calc-field">
      <div className="calc-flbl"><span>{label}</span></div>
      <div className="calc-stepper">
        <button type="button" onClick={() => onChange(Math.max(min, value - 1))} disabled={value <= min} aria-label="weniger">−</button>
        <span className="calc-stepper-v">{value}{unit ? <em>{unit}</em> : null}</span>
        <button type="button" onClick={() => onChange(Math.min(max, value + 1))} disabled={value >= max} aria-label="mehr">+</button>
      </div>
    </div>
  );
}

/* ── Per-service input panels ───────────────────────────────────── */
function FensterInputs({ v, set }) {
  return (
    <>
      <CalcSlider label="Anzahl Fenster" value={v.count} min={1} max={40} unit=" Stück"
                  onChange={(x) => set('count', x)}
                  hint="Zweiflüglige Fenster zählen als zwei. Wintergärten bitte separat anfragen." />
      <CalcRadio label="Welche Seite reinigen?" value={v.side}
                 options={[{ v:'innen', l:'Nur innen' },{ v:'aussen', l:'Nur außen' },{ v:'beides', l:'Innen & außen' }]}
                 onChange={(x) => set('side', x)} />
      <CalcToggle label="Rahmen mitreinigen" value={v.frames}
                  onChange={(x) => set('frames', x)}
                  hint="Inklusive Fensterbank und Falze." />
      <CalcStepper label="Etagen" value={v.floors} min={1} max={4}
                   onChange={(x) => set('floors', x)} />
    </>
  );
}

function GartenInputs({ v, set }) {
  return (
    <>
      <CalcSlider label="Grundstücksgröße" value={v.size} min={50} max={2000} step={10} unit=" m²"
                  onChange={(x) => set('size', x)} />
      <CalcMulti label="Was soll gemacht werden?" value={v.tasks}
                 options={[{ v:'rasen', l:'Rasen mähen' },{ v:'hecke', l:'Hecke schneiden' },{ v:'beet', l:'Beete pflegen' }]}
                 onChange={(x) => set('tasks', x)} />
      {v.tasks.includes('hecke') && (
        <CalcSlider label="Heckenlänge" value={v.hedge} min={1} max={80} unit=" m"
                    onChange={(x) => set('hedge', x)} />
      )}
      <CalcRadio label="Häufigkeit" value={v.recurring}
                 options={[{ v:'einmalig', l:'Einmalig' },{ v:'monatlich', l:'Regelmäßig' }]}
                 onChange={(x) => set('recurring', x)} />
    </>
  );
}

function EntruempelungInputs({ v, set }) {
  return (
    <>
      <CalcStepper label="Anzahl Räume" value={v.rooms} min={1} max={8}
                   onChange={(x) => set('rooms', x)} />
      <CalcRadio label="Wie voll ist es?" value={v.fill}
                 options={[{ v:'leer', l:'Eher leer' },{ v:'normal', l:'Normal' },{ v:'voll', l:'Sehr voll' }]}
                 onChange={(x) => set('fill', x)} />
      <CalcToggle label="Sperrmüll mit entsorgen" value={v.sperrmuell}
                  onChange={(x) => set('sperrmuell', x)}
                  hint="Möbel, Geräte, größere Teile." />
    </>
  );
}

function ReparaturInputs({ v, set }) {
  return (
    <>
      <CalcRadio label="Geschätzter Aufwand" value={v.hours}
                 options={[{ v:'short', l:'< 2 Std.' },{ v:'half', l:'Halber Tag' },{ v:'full', l:'Ganzer Tag' }]}
                 onChange={(x) => set('hours', x)} />
      <CalcRadio label="Material" value={v.material}
                 options={[{ v:'mit', l:'Habe ich' },{ v:'durch_uns', l:'Bitte besorgen' }]}
                 onChange={(x) => set('material', x)} />
    </>
  );
}

function MontageInputs({ v, set }) {
  return (
    <>
      <CalcRadio label="Was wird montiert?" value={v.type}
                 options={[
                   { v:'schrank', l:'Schrank' },{ v:'bett', l:'Bett' },
                   { v:'kueche', l:'Küche' },{ v:'lampen', l:'Lampen' },
                   { v:'anderes', l:'Anderes' },
                 ]}
                 onChange={(x) => set('type', x)} />
      <CalcStepper label="Anzahl" value={v.count} min={1} max={10}
                   onChange={(x) => set('count', x)} />
    </>
  );
}

const PANELS = {
  fenster: FensterInputs,
  garten: GartenInputs,
  entruempelung: EntruempelungInputs,
  reparatur: ReparaturInputs,
  montage: MontageInputs,
};

/* ── Result card ────────────────────────────────────────────────── */
function PriceCard({ service, params, price, onCta }) {
  const mid = useCounter(price.mid);
  const list = bullets(service, params);
  return (
    <div className="calc-result">
      <div className="calc-result-eyebrow">Richtwert</div>
      <div className="calc-result-price">
        <span className="calc-result-mid">
          <span className="calc-tick">{mid}</span><em>€</em>
        </span>
        <div className="calc-result-range">geschätzt {price.low}–{price.high} €</div>
      </div>
      <ul className="calc-result-list">
        {list.map((b, i) => (
          <li key={i}>
            <svg viewBox="0 0 24 24"><polyline points="4 12 10 18 20 6"/></svg>
            <span>{b}</span>
          </li>
        ))}
      </ul>
      <button type="button" className="calc-cta" onClick={onCta}>
        Verbindliches Angebot anfragen <span>→</span>
      </button>
      <div className="calc-result-foot">Schätzung aus dem Online-Kalkulator. Der finale Preis wird nach kurzer Begutachtung fix vereinbart — ohne Überraschungen.</div>
    </div>
  );
}

/* ── Top-level Calculator ───────────────────────────────────────── */
function Calculator() {
  const [service, setService] = useState('fenster');
  const [params, setParams] = useState(DEFAULTS);
  const v = params[service];
  const set = (k, val) => setParams((prev) => ({ ...prev, [service]: { ...prev[service], [k]: val } }));
  const price = useMemo(() => calcPrice(service, v), [service, v]);

  const Panel = PANELS[service];

  // Horizontal-scroll affordance for tabs
  const tabsRef = useRef(null);
  const [tabScroll, setTabScroll] = useState({ left: false, right: false });
  useEffect(() => {
    const el = tabsRef.current;
    if (!el) return;
    const update = () => {
      const { scrollLeft, scrollWidth, clientWidth } = el;
      setTabScroll({
        left: scrollLeft > 4,
        right: scrollLeft < scrollWidth - clientWidth - 4,
      });
    };
    update();
    el.addEventListener('scroll', update, { passive: true });
    const ro = new ResizeObserver(update);
    ro.observe(el);
    window.addEventListener('resize', update);
    return () => {
      el.removeEventListener('scroll', update);
      ro.disconnect();
      window.removeEventListener('resize', update);
    };
  }, []);
  const scrollTabs = (dir) => {
    const el = tabsRef.current;
    if (!el) return;
    el.scrollBy({ left: dir * 240, behavior: 'smooth' });
  };
  const selectTab = (id) => {
    setService(id);
    const el = tabsRef.current;
    if (!el) return;
    const target = el.querySelector(`[data-tab="${id}"]`);
    if (target) {
      const center = target.offsetLeft + target.offsetWidth / 2 - el.clientWidth / 2;
      el.scrollTo({ left: Math.max(0, center), behavior: 'smooth' });
    }
  };

  const onCta = () => {
    const map = { fenster:'Fensterreinigung', garten:'Gartenpflege', entruempelung:'Entrümpelung', reparatur:'Kleinreparatur', montage:'Montage' };
    const sel = document.getElementById('service');
    if (sel) {
      const want = map[service];
      [...sel.options].forEach((o) => { o.selected = o.text === want; });
    }
    const msg = document.getElementById('msg');
    if (msg) {
      msg.value =
        `Anfrage über den Online-Kalkulator.\n\nLeistung: ${map[service]}\nDetails: ${summary(service, v)}\nRichtwert: ca. ${price.low}–${price.high} €\n\nIch hätte gerne ein verbindliches Angebot. Vielen Dank!`;
      msg.dispatchEvent(new Event('input', { bubbles: true }));
    }
    const target = document.getElementById('kontakt');
    if (target) window.scrollTo({ top: target.offsetTop - 60, behavior: 'smooth' });
    setTimeout(() => {
      const n = document.getElementById('name');
      if (n) n.focus({ preventScroll: true });
    }, 800);
  };

  return (
    <div className="calc">
      <div className="calc-tabs-wrap">
        <div className="calc-tabs" ref={tabsRef} role="tablist">
          {SERVICES.map((s) => (
            <button key={s.id} type="button" role="tab" aria-selected={service === s.id}
                    data-tab={s.id}
                    className={`calc-tab${service === s.id ? ' on' : ''}`}
                    onClick={() => selectTab(s.id)}>
              <span className="calc-tab-icon">{ICONS[s.id]}</span>
              <span className="calc-tab-text">
                <span className="calc-tab-t">{s.title}</span>
                <span className="calc-tab-s">{s.sub}</span>
              </span>
            </button>
          ))}
        </div>
        <div className={`calc-tabs-fade calc-tabs-fade-l${tabScroll.left ? '' : ' hidden'}`} aria-hidden="true"></div>
        <div className={`calc-tabs-fade calc-tabs-fade-r${tabScroll.right ? '' : ' hidden'}`} aria-hidden="true"></div>
        <button type="button" aria-label="Vorherige Leistung"
                className={`calc-tabs-arrow calc-tabs-arrow-l${tabScroll.left ? '' : ' hidden'}`}
                onClick={() => scrollTabs(-1)}>
          <svg viewBox="0 0 24 24"><path d="M15 6l-6 6 6 6"/></svg>
        </button>
        <button type="button" aria-label="Nächste Leistung"
                className={`calc-tabs-arrow calc-tabs-arrow-r${tabScroll.right ? '' : ' hidden'}`}
                onClick={() => scrollTabs(1)}>
          <svg viewBox="0 0 24 24"><path d="M9 6l6 6-6 6"/></svg>
        </button>
      </div>
      <div className="calc-body">
        <div className="calc-inputs" key={service}>
          {Panel && <Panel v={v} set={set} />}
        </div>
        <PriceCard service={service} params={v} price={price} onCta={onCta} />
      </div>
    </div>
  );
}

const calcRoot = document.getElementById('calc-root');
if (calcRoot) ReactDOM.createRoot(calcRoot).render(<Calculator />);
