/* spočítAIto.cz — flow dashboard */

const { useState, useMemo, useRef, useEffect, useCallback, useLayoutEffect } = React;

/* ---------- formatters ---------- */
const fmtCZK = (n) => {
  const sign = n < 0 ? '−' : '';
  const abs = Math.abs(Math.round(n));
  const s = abs.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '\u00A0');
  return `${sign}${s}\u00A0Kč`;
};
const fmtPct = (n) => `${n.toString().replace('.', ',')}\u00A0%`;
const fmtInt = (n) => {
  const sign = n < 0 ? '−' : '';
  const abs = Math.abs(Math.round(n));
  return sign + abs.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '\u00A0');
};

/* ---------- default data ---------- */
const DEFAULT_PROPERTIES = [
  { id: 1, name: 'Byt 2+kk Vinohrady', rent: 22000,
    costs: { mortgage: 12500, fund: 2800, insurance: 350, propertyTax: 200, management: 1500, reserve: 1100, other: 0 } },
  { id: 2, name: 'Byt 1+1 Žižkov', rent: 16000,
    costs: { mortgage: 9200, fund: 2100, insurance: 280, propertyTax: 150, management: 1200, reserve: 800, other: 0 } },
  { id: 3, name: 'Byt 3+1 Smíchov', rent: 28000,
    costs: { mortgage: 18000, fund: 3500, insurance: 450, propertyTax: 280, management: 2000, reserve: 1400, other: 0 } },
  { id: 4, name: 'Garsonka Karlín', rent: 14500,
    costs: { mortgage: 11800, fund: 1900, insurance: 240, propertyTax: 140, management: 1100, reserve: 700, other: 200 } },
];

const COST_LABELS = {
  mortgage: 'Hypotéka',
  fund: 'Fond oprav / SVJ',
  insurance: 'Pojištění',
  propertyTax: 'Daň z nemovitosti',
  management: 'Správa / management',
  reserve: 'Rezerva na opravy',
  other: 'Ostatní',
};
const COST_ORDER = ['mortgage', 'fund', 'insurance', 'propertyTax', 'management', 'reserve', 'other'];

const sumCosts = (costs) => COST_ORDER.reduce((a, k) => a + (costs[k] || 0), 0);

/* ---------- Logo ---------- */
function Logo() {
  return (
    <div className="logo">
      <span className="logo-a">spočít</span>
      <span className="logo-ai">AI</span>
      <span className="logo-a">to</span>
      <span className="logo-cz">.cz</span>
    </div>
  );
}

/* ---------- EditableValue ---------- */
function EditableValue({ value, onChange, suffix = 'Kč', className = '', ariaLabel }) {
  const [editing, setEditing] = useState(false);
  const [draft, setDraft] = useState(String(value));
  const inputRef = useRef(null);

  useEffect(() => {
    if (editing && inputRef.current) {
      inputRef.current.focus();
      inputRef.current.select();
    }
  }, [editing]);

  const commit = () => {
    const cleaned = draft.replace(/[^\d-]/g, '');
    const n = parseInt(cleaned, 10);
    if (!isNaN(n) && n !== value) onChange(n);
    setEditing(false);
  };

  if (editing) {
    return (
      <span className={`editable editing ${className}`}>
        <input
          ref={inputRef}
          className="edit-input"
          value={draft}
          onChange={(e) => setDraft(e.target.value)}
          onBlur={commit}
          onKeyDown={(e) => {
            if (e.key === 'Enter') commit();
            if (e.key === 'Escape') { setDraft(String(value)); setEditing(false); }
          }}
          aria-label={ariaLabel}
        />
        <span className="edit-suffix">{suffix}</span>
      </span>
    );
  }

  return (
    <button
      className={`editable ${className}`}
      onClick={() => { setDraft(String(value)); setEditing(true); }}
      aria-label={ariaLabel}
      type="button"
    >
      <span className="num">{fmtInt(value)}</span>
      <span className="num-suffix">{suffix}</span>
    </button>
  );
}

/* ---------- EditableText (name) ---------- */
function EditableText({ value, onChange, className = '' }) {
  const [editing, setEditing] = useState(false);
  const [draft, setDraft] = useState(value);
  const inputRef = useRef(null);

  useEffect(() => {
    if (editing && inputRef.current) {
      inputRef.current.focus();
      inputRef.current.select();
    }
  }, [editing]);

  const commit = () => {
    const v = draft.trim();
    if (v && v !== value) onChange(v);
    setEditing(false);
  };

  if (editing) {
    return (
      <input
        ref={inputRef}
        className={`name-input ${className}`}
        value={draft}
        onChange={(e) => setDraft(e.target.value)}
        onBlur={commit}
        onKeyDown={(e) => {
          if (e.key === 'Enter') commit();
          if (e.key === 'Escape') { setDraft(value); setEditing(false); }
        }}
      />
    );
  }
  return (
    <button
      className={`name-btn ${className}`}
      onClick={() => { setDraft(value); setEditing(true); }}
      type="button"
    >
      {value}
    </button>
  );
}

/* ---------- PropertyCard ---------- */
function PropertyCard({ property, onUpdate, onRemove, viewMode, cardRef }) {
  const [expanded, setExpanded] = useState(false);

  const monthMul = viewMode === 'year' ? 12 : 1;
  const totalCosts = sumCosts(property.costs);
  const net = property.rent - totalCosts;
  const isPositive = net >= 0;

  const setRent = (v) => onUpdate({ ...property, rent: Math.max(0, v) });
  const setCost = (key, v) => onUpdate({ ...property, costs: { ...property.costs, [key]: Math.max(0, v) } });
  const setName = (v) => onUpdate({ ...property, name: v });

  return (
    <div className="card property-card" ref={cardRef}>
      <div className="card-head">
        <EditableText value={property.name} onChange={setName} />
        <button className="remove-btn" onClick={() => onRemove(property.id)} aria-label="Smazat nemovitost" type="button">
          <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round">
            <path d="M3 3l8 8M11 3l-8 8" />
          </svg>
        </button>
      </div>

      <div className="row rent-row">
        <span className="row-label">Měsíční nájem</span>
        <EditableValue value={property.rent * monthMul} onChange={(v) => setRent(Math.round(v / monthMul))} ariaLabel="Měsíční nájem" />
      </div>

      <div className="divider" />

      <button className="costs-toggle" onClick={() => setExpanded(!expanded)} type="button" aria-expanded={expanded}>
        <span className="row-label">Náklady</span>
        <span className="costs-toggle-right">
          {!expanded && <span className="num costs-collapsed">{fmtCZK(totalCosts * monthMul)}</span>}
          <svg className={`chevron ${expanded ? 'open' : ''}`} width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
            <path d="M3 5l3 3 3-3" />
          </svg>
        </span>
      </button>

      {expanded && (
        <div className="costs-list">
          {COST_ORDER.map((k) => (
            <div className="row cost-row" key={k}>
              <span className="cost-label">{COST_LABELS[k]}</span>
              <EditableValue
                value={property.costs[k] * monthMul}
                onChange={(v) => setCost(k, Math.round(v / monthMul))}
                ariaLabel={COST_LABELS[k]}
                className="muted"
              />
            </div>
          ))}
          <div className="row cost-total">
            <span className="row-label">Náklady celkem</span>
            <span className="num">{fmtCZK(totalCosts * monthMul)}</span>
          </div>
        </div>
      )}

      <div className="card-foot">
        <span className="foot-label">Čistý výnos</span>
        <span className={`net-value ${isPositive ? 'pos' : 'neg'}`}>
          {isPositive ? '+' : ''}{fmtCZK(net * monthMul)}
        </span>
      </div>
    </div>
  );
}

/* ---------- AddCard ---------- */
function AddCard({ onAdd }) {
  return (
    <button className="card add-card" onClick={onAdd} type="button">
      <span className="add-icon" aria-hidden="true">
        <svg width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round">
          <path d="M10 4v12M4 10h12" />
        </svg>
      </span>
      <span className="add-label">Přidat nemovitost</span>
      <span className="add-hint">Nový byt nebo dům</span>
    </button>
  );
}

/* ---------- FlowLines ---------- */
function FlowLines({ anchors, summaryAnchor, properties, viewMode, height }) {
  /* anchors: [{x, y, net}] in container coords; summaryAnchor: {x, y} */
  if (!anchors.length || !summaryAnchor) return null;

  const monthMul = viewMode === 'year' ? 12 : 1;
  const maxAbs = Math.max(...anchors.map(a => Math.abs(a.net)), 1);

  return (
    <svg className="flow-svg" width="100%" height={height} aria-hidden="true">
      <defs>
        <filter id="dot-glow-pos" x="-50%" y="-50%" width="200%" height="200%">
          <feGaussianBlur stdDeviation="2" result="blur"/>
          <feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
        </filter>
      </defs>
      {anchors.map((a, i) => {
        const isPos = a.net >= 0;
        const stroke = isPos ? 'var(--green-500)' : 'var(--red-500)';
        const strokeBg = isPos ? 'var(--green-100)' : 'var(--red-100)';
        const thickness = 2 + (Math.abs(a.net) / maxAbs) * 3;
        const sx = a.x, sy = a.y;
        const ex = summaryAnchor.x, ey = summaryAnchor.y;
        const midY = sy + (ey - sy) * 0.55;
        const d = `M ${sx} ${sy} C ${sx} ${midY}, ${ex} ${midY}, ${ex} ${ey}`;

        // label position roughly 40% along
        const lx = sx + (ex - sx) * 0.5;
        const ly = sy + (ey - sy) * 0.5 - 8;

        const dur = 2.6 + (i % 3) * 0.4;
        const delay = i * 0.35;

        return (
          <g key={a.id}>
            {/* base track */}
            <path d={d} stroke={strokeBg} strokeWidth={thickness} fill="none" strokeLinecap="round" />
            {/* animated dashes */}
            <path
              d={d}
              stroke={stroke}
              strokeWidth={thickness}
              fill="none"
              strokeLinecap="round"
              strokeDasharray="6 10"
              className="flow-dashes"
              style={{ animationDuration: `${dur}s`, animationDelay: `${delay}s` }}
            />
            {/* traveling dot */}
            <circle r={thickness + 1.5} fill={stroke} className="flow-dot" filter="url(#dot-glow-pos)">
              <animateMotion dur={`${dur}s`} repeatCount="indefinite" begin={`${delay}s`} path={d} rotate="auto" />
            </circle>
            {/* label */}
            <g transform={`translate(${lx}, ${ly})`}>
              <rect x="-44" y="-12" width="88" height="22" rx="11" className="flow-label-bg" fill="white" stroke={isPos ? 'var(--green-200)' : 'var(--red-200)'} />
              <text className="flow-label-text" x="0" y="3" textAnchor="middle" fill={isPos ? 'var(--green-700)' : 'var(--red-500)'}>
                {a.net >= 0 ? '+' : ''}{fmtCZK(a.net * monthMul)}
              </text>
            </g>
          </g>
        );
      })}
    </svg>
  );
}

/* ---------- SummaryBlock ---------- */
function SummaryBlock({ properties, viewMode, taxMode, summaryRef }) {
  const monthMul = viewMode === 'year' ? 12 : 1;
  const grossMonth = properties.reduce((a, p) => a + p.rent, 0);
  const costsMonth = properties.reduce((a, p) => a + sumCosts(p.costs), 0);
  const netMonth = grossMonth - costsMonth;
  const netYear = netMonth * 12;
  const netView = netMonth * monthMul;

  let taxRate = 0;
  let taxLabel = 'Bez daně';
  let taxableBase = netMonth;
  if (taxMode === 'tax15') {
    taxRate = 0.15;
    taxLabel = 'Daň z příjmu (15 %)';
    taxableBase = netMonth;
  } else if (taxMode === 'flat30') {
    taxRate = 0.15;
    taxLabel = 'Daň po paušálních výdajích 30 %';
    taxableBase = grossMonth * 0.7; // přiznáno: 70 % příjmu po paušálních výdajích
  }
  const tax = Math.max(0, taxableBase) * taxRate;
  const afterTax = netMonth - tax;

  return (
    <div className="summary" ref={summaryRef}>
      <div className="summary-accent" />
      <div className="summary-inner">
        <div className="summary-head">
          <span className="caption">Vaše kapsa</span>
          <h2 className="summary-title">Souhrn {properties.length} {properties.length === 1 ? 'nemovitosti' : properties.length < 5 ? 'nemovitostí' : 'nemovitostí'}</h2>
        </div>

        <div className="summary-grid">
          <div className="kv">
            <span className="kv-label">Hrubý příjem</span>
            <span className="kv-value num">{fmtCZK(grossMonth * monthMul)}</span>
          </div>
          <div className="kv">
            <span className="kv-label">Celkové náklady</span>
            <span className="kv-value num">{fmtCZK(costsMonth * monthMul)}</span>
          </div>
          <div className="kv">
            <span className="kv-label">Marže</span>
            <span className="kv-value num">{grossMonth > 0 ? fmtPct(((netMonth / grossMonth) * 100).toFixed(1)) : '—'}</span>
          </div>
        </div>

        <div className={`summary-hero ${netMonth >= 0 ? 'pos' : 'neg'}`}>
          <div className="hero-top">
            <span className="caption">Čistý měsíční příjem</span>
            <span className="hero-view-mode">{viewMode === 'year' ? 'roční pohled' : 'měsíční pohled'}</span>
          </div>
          <div className="hero-num">
            <span className={`hero-value num ${netMonth >= 0 ? 'pos' : 'neg'}`}>
              {netMonth >= 0 ? '+' : ''}{fmtCZK(netView)}
            </span>
          </div>
          <div className="hero-sub">
            <span className="num">{fmtCZK(netYear)}</span> ročně
            <span className="dot-sep">·</span>
            <span className="num">{fmtCZK(netMonth)}</span> / měsíc
          </div>
        </div>

        {taxMode !== 'none' && (
          <div className="tax-block">
            <div className="kv tax-row">
              <span className="kv-label">{taxLabel}</span>
              <span className="kv-value num neg">−{fmtCZK(tax * monthMul).replace('−','')}</span>
            </div>
            <div className="kv tax-row">
              <span className="kv-label kv-label-strong">Po zdanění</span>
              <span className="kv-value num strong">{fmtCZK(afterTax * monthMul)}</span>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

/* ---------- Toast ---------- */
function Toast({ message, onUndo, onClose }) {
  useEffect(() => {
    const t = setTimeout(onClose, 5000);
    return () => clearTimeout(t);
  }, [onClose]);
  return (
    <div className="toast" role="status">
      <span>{message}</span>
      <button className="toast-undo" onClick={onUndo} type="button">Vrátit</button>
    </div>
  );
}

/* ---------- Dashboard page (wraps the original flow view) ---------- */
function DashboardPage({ properties, setProperties, viewMode, taxMode, addProperty, removeProperty, updateProperty, totals }) {
  const cardRefs = useRef({});
  const summaryRef = useRef(null);
  const stageRef = useRef(null);
  const [anchors, setAnchors] = useState([]);
  const [summaryAnchor, setSummaryAnchor] = useState(null);
  const [stageHeight, setStageHeight] = useState(420);

  const measure = useCallback(() => {
    if (!stageRef.current) return;
    const stageRect = stageRef.current.getBoundingClientRect();
    const next = [];
    for (const p of properties) {
      const el = cardRefs.current[p.id];
      if (!el) continue;
      const r = el.getBoundingClientRect();
      next.push({
        id: p.id,
        x: r.left - stageRect.left + r.width / 2,
        y: r.bottom - stageRect.top,
        net: p.rent - sumCosts(p.costs),
      });
    }
    setAnchors(prev => {
      if (prev.length !== next.length) return next;
      for (let i = 0; i < prev.length; i++) {
        const a = prev[i], b = next[i];
        if (a.id !== b.id || Math.abs(a.x - b.x) > 0.5 || Math.abs(a.y - b.y) > 0.5 || a.net !== b.net) return next;
      }
      return prev;
    });
    if (summaryRef.current) {
      const r = summaryRef.current.getBoundingClientRect();
      const sx = r.left - stageRect.left + r.width / 2;
      const sy = r.top - stageRect.top;
      const h = r.bottom - stageRect.top + 4;
      setSummaryAnchor(prev => (prev && Math.abs(prev.x - sx) < 0.5 && Math.abs(prev.y - sy) < 0.5) ? prev : { x: sx, y: sy });
      setStageHeight(prev => Math.abs(prev - h) < 0.5 ? prev : h);
    }
  }, [properties]);

  useLayoutEffect(() => { measure(); }, [measure]);
  useEffect(() => {
    let raf = 0;
    const schedule = () => {
      cancelAnimationFrame(raf);
      raf = requestAnimationFrame(() => measure());
    };
    window.addEventListener('resize', schedule);
    if (document.fonts && document.fonts.ready) document.fonts.ready.then(schedule);
    const interval = setInterval(schedule, 500);
    return () => { cancelAnimationFrame(raf); clearInterval(interval); window.removeEventListener('resize', schedule); };
  }, [measure]);

  return (
    <>
      <div className="page-toolbar">
        <div className="toolbar-left">
          <h1 className="page-title">Vaše portfolio</h1>
          <span className="page-sub">{properties.length} {properties.length === 1 ? 'nemovitost' : properties.length < 5 ? 'nemovitosti' : 'nemovitostí'} · čistý {viewMode === 'year' ? 'roční' : 'měsíční'} výnos <span className={`num ${totals.net >= 0 ? 'pos' : 'neg'}`}>{totals.net >= 0 ? '+' : ''}{fmtCZK(totals.net * (viewMode === 'year' ? 12 : 1))}</span></span>
        </div>
        <div className="toolbar-right">
          <button className="btn btn-primary" onClick={addProperty} type="button">
            <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"><path d="M7 2v10M2 7h10"/></svg>
            Přidat nemovitost
          </button>
        </div>
      </div>

      <div className="stage" ref={stageRef} style={{ minHeight: stageHeight }}>
        <FlowLines anchors={anchors} summaryAnchor={summaryAnchor} properties={properties} viewMode={viewMode} height={stageHeight} />
        <div className="cards-row">
          {properties.map((p) => (
            <PropertyCard
              key={p.id}
              property={p}
              onUpdate={updateProperty}
              onRemove={removeProperty}
              viewMode={viewMode}
              cardRef={(el) => { if (el) cardRefs.current[p.id] = el; else delete cardRefs.current[p.id]; }}
            />
          ))}
          <AddCard onAdd={addProperty} />
        </div>
        <SummaryBlock properties={properties} viewMode={viewMode} taxMode={taxMode} summaryRef={summaryRef} />
      </div>
    </>
  );
}

/* ---------- App ---------- */
function App() {
  const [properties, setProperties] = useState(DEFAULT_PROPERTIES);
  const [viewMode, setViewMode] = useState('month');
  const [taxMode, setTaxMode] = useState('tax15');
  const [removed, setRemoved] = useState(null);
  const [nextId, setNextId] = useState(5);
  const [route, setRoute] = useState(() => (window.location.hash.replace('#', '') || 'dashboard'));

  useEffect(() => {
    const handler = () => setRoute(window.location.hash.replace('#', '') || 'dashboard');
    window.addEventListener('hashchange', handler);
    return () => window.removeEventListener('hashchange', handler);
  }, []);
  const go = (r) => { window.location.hash = r; setRoute(r); };

  const updateProperty = (p) => setProperties(props => props.map(x => x.id === p.id ? p : x));
  const removeProperty = (id) => {
    const idx = properties.findIndex(p => p.id === id);
    if (idx < 0) return;
    setRemoved({ property: properties[idx], index: idx });
    setProperties(props => props.filter(p => p.id !== id));
  };
  const undoRemove = () => {
    if (!removed) return;
    setProperties(props => {
      const next = [...props];
      next.splice(removed.index, 0, removed.property);
      return next;
    });
    setRemoved(null);
  };
  const addProperty = () => {
    const id = nextId;
    setNextId(id + 1);
    setProperties(props => [...props, {
      id,
      name: `Nová nemovitost ${props.length + 1}`,
      rent: 18000,
      costs: { mortgage: 10000, fund: 2200, insurance: 300, propertyTax: 180, management: 1200, reserve: 900, other: 0 },
    }]);
  };

  const totals = useMemo(() => {
    const gross = properties.reduce((a, p) => a + p.rent, 0);
    const costs = properties.reduce((a, p) => a + sumCosts(p.costs), 0);
    return { gross, costs, net: gross - costs };
  }, [properties]);

  return (
    <div className="app">
      {/* Header */}
      <header className="header">
        <div className="container header-inner">
          <a href="#dashboard" onClick={(e) => { e.preventDefault(); go('dashboard'); }} className="logo-link"><Logo /></a>
          <nav className="header-nav">
            {[
              { id: 'dashboard', label: 'Přehled' },
              { id: 'history', label: 'Historie' },
              { id: 'scenarios', label: 'Scénáře' },
              { id: 'export', label: 'Export' },
            ].map(n => (
              <a key={n.id} className={`nav-link ${route === n.id ? 'active' : ''}`} href={`#${n.id}`} onClick={(e) => { e.preventDefault(); go(n.id); }}>{n.label}</a>
            ))}
          </nav>
          <div className="header-right">
            <div className="view-toggle" role="tablist" aria-label="Pohled">
              <button className={viewMode === 'month' ? 'active' : ''} onClick={() => setViewMode('month')} type="button">Měsíčně</button>
              <button className={viewMode === 'year' ? 'active' : ''} onClick={() => setViewMode('year')} type="button">Ročně</button>
            </div>
            <div className="plan-badge">
              <span className="plan-dot" />
              PRO
            </div>
            <div className="avatar" aria-label="Účet">JN</div>
          </div>
        </div>
      </header>

      <div className="subheader">
        <div className="container subheader-inner">
          <div className="subhead-route-tag">
            {route === 'dashboard' && 'Flow přehled'}
            {route === 'history' && 'Historický vývoj'}
            {route === 'scenarios' && 'Scénáře a plánování'}
            {route === 'export' && 'Export přehledu'}
          </div>
          <div className="subhead-right">
            <label className="select-wrap">
              <span className="caption">Daňový režim</span>
              <select value={taxMode} onChange={(e) => setTaxMode(e.target.value)}>
                <option value="none">Bez daně</option>
                <option value="tax15">Daň 15 %</option>
                <option value="flat30">Paušální výdaje 30 %</option>
              </select>
            </label>
          </div>
        </div>
      </div>

      <main className="main">
        <div className="container">
          {route === 'dashboard' && (
            <DashboardPage
              properties={properties}
              setProperties={setProperties}
              viewMode={viewMode}
              taxMode={taxMode}
              addProperty={addProperty}
              removeProperty={removeProperty}
              updateProperty={updateProperty}
              totals={totals}
            />
          )}
          {route === 'history' && <HistoryPage properties={properties} viewMode={viewMode} />}
          {route === 'scenarios' && <ScenariosPage properties={properties} />}
          {route === 'export' && <ExportPage properties={properties} taxMode={taxMode} />}
        </div>
      </main>

      <footer className="footer">
        <div className="container footer-inner">
          <Logo />
          <span className="footer-meta">Kolik vám pronájem opravdu nese? · v0.4 demo</span>
        </div>
      </footer>

      {removed && <Toast message={`Smazáno: ${removed.property.name}`} onUndo={undoRemove} onClose={() => setRemoved(null)} />}
    </div>
  );
}

// Expose helpers and shared components for sibling Babel scripts.
Object.assign(window, {
  fmtCZK, fmtPct, fmtInt, sumCosts, COST_LABELS, COST_ORDER,
  App,
});
