// Optimizer screen — Gridome Hour v2 aesthetic.
// Shows Gridome's autonomous day-ahead plan as a unified 24h timeline.
// Sources: ev_scheduler, battery_orchestrator, sg_ready_controller,
//          feedin_priority, co2_scheduler, charge_plans.
// All read-only — GRIDOME_BATTERY_LIVE unset, OCPP writes fire when charger plugged in.

// ── Stub plan data (mirrors real decision outputs from optimizer_orchestrator.py) ──
function buildOptimizerPlan(scenario) {
  const s = SCENARIOS[scenario];
  const curve = buildPriceCurve(s);

  // 24h slots from now (hour 0 = current hour)
  const nowH = Math.floor(s.hour);

  const slots = Array.from({ length: 24 }, (_, i) => {
    const absH = (nowH + i) % 24;
    const tariff = curve[absH];
    const isCheap = tariff.tier === 'cheap';
    const isPeak = tariff.tier === 'peak' || tariff.tier === 'high';
    const isSolar = absH >= 8 && absH <= 18;
    const solarKw = isSolar ? Math.max(0, 8.4 * Math.sin(((absH - 6) / 12) * Math.PI)) : 0;

    // Battery: charge from grid at cheap windows overnight, discharge at peak
    const battDecision = isCheap && absH < 7
      ? 'grid-charge'    // cheap overnight → charge battery
      : isCheap && isSolar
      ? 'pv-charge'      // cheap + solar → charge from PV
      : isPeak
      ? 'discharge'      // peak → discharge to home
      : 'idle';

    // EV: charge in cheapest overnight window (00–05h range)
    const evCharging = scenario === 'overnight'
      ? (absH >= 1 && absH <= 6)
      : (absH >= 1 && absH <= 5);

    // Heat pump SG-Ready: signal ON when cheap + daytime
    const hpSignal = isCheap && absH >= 8 && absH <= 16;

    // Feed-in priority: when PV > 6kW and battery > 70% (surplus export)
    const feedin = solarKw > 5 && absH >= 10 && absH <= 14;

    return { i, absH, tariff, solarKw, battDecision, evCharging, hpSignal, feedin };
  });

  // Summary stats
  const shiftedKwh = slots.filter(s => s.evCharging).length * 7 * 0.85 +
                     slots.filter(s => s.battDecision === 'grid-charge').length * 3;
  const savedZl = shiftedKwh * 0.62;  // ~0.62 zł/kWh delta cheap vs peak
  const co2Saved = Math.round(shiftedKwh * 0.22); // ~220g CO2/kWh Polish grid average

  const status = 'Optimal';
  const lastRun = `${String(nowH).padStart(2,'0')}:00`;

  return { slots, shiftedKwh: shiftedKwh.toFixed(1), savedZl: savedZl.toFixed(2), co2Saved, status, lastRun, nowH };
}

// ── Row definitions (inside V2Optimizer) ──────────────────────────────────

// ── Main component ─────────────────────────────────────────────────────────
function V2Optimizer({ s }) {
  const { t, locale } = useLocale();
  const TIMELINE_ROWS = [
    { key: 'tariff',  label: t('optimizer.rowPrices'), icon: 'dollar-sign', height: 24 },
    { key: 'pv',      label: t('optimizer.rowPV'),     icon: 'sun', height: 28 },
    { key: 'battery', label: t('optimizer.rowBattery'),icon: 'zap', height: 28 },
    { key: 'ev',      label: t('optimizer.rowEV'),     icon: 'car', height: 28 },
    { key: 'hp',      label: t('optimizer.rowHP'),     icon: 'thermometer', height: 24 },
    { key: 'feedin',  label: t('optimizer.rowExport'), icon: 'upload', height: 24 },
  ];
  const plan = React.useMemo(() => buildOptimizerPlan(s.key), [s.key]);
  const food = foodFor(parseFloat(plan.savedZl));

  return (
    <div>
      {/* Read-only notice */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 10, marginBottom: 20,
        padding: '10px 14px', background: T.raised, borderRadius: 10,
        border: `1px solid ${T.border}`, fontSize: 12, color: T.textMuted,
      }}>
        <span style={{ width: 7, height: 7, borderRadius: '50%', background: T.amber, flexShrink: 0 }}/>
        <span>
          <strong style={{ color: T.textSecondary }}>Read-only — </strong>
          {t('opt.readonlyText')}
          <code style={{ fontFamily: T.fontMono, fontSize: 11, color: T.amber, margin: '0 4px' }}>
            optimizer_orchestrator.py
          </code>
          — {t('optimizer.activeWhen')} <code style={{ fontFamily: T.fontMono, fontSize: 11, color: T.amber }}>GRIDOME_BATTERY_LIVE=1</code>.
        </span>
      </div>

      {/* Hero summary */}
      <div style={{ display: 'grid', gridTemplateColumns: '1.5fr 1fr', gap: 18, marginBottom: 18 }}>
        {/* Croissant moment */}
        <Surface padding={28} style={{
          background: `linear-gradient(135deg, ${T.tintGreen}, ${T.surface})`,
          border: `1px solid ${T.green}33`,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 12 }}>
            <span style={{ width: 8, height: 8, borderRadius: '50%', background: T.green, display: 'inline-block', boxShadow: `0 0 10px ${T.green}` }}/>
            <SurfaceLabel color={T.green}>{t('optimizer.statusOptimal')} · {t('optimizer.lastPlan')} {plan.lastRun}</SurfaceLabel>
          </div>
          <div style={{ fontSize: 14, color: T.textSecondary, lineHeight: 1.7, marginBottom: 16 }}>
            {t('optimizer.heroDesc', { kwh: plan.shiftedKwh, saved: plan.savedZl, emoji: '', food: foodText(parseFloat(plan.savedZl), t, locale) })}
          </div>
          <div style={{ display: 'flex', gap: 16 }}>
            <OptKPI label={t('optimizer.shifted')} value={plan.shiftedKwh} unit="kWh" color={T.green}/>
            <OptKPI label={t('optimizer.savings')} value={plan.savedZl} unit="zł" color={T.green}/>
            <OptKPI label={t('optimizer.co2')} value={plan.co2Saved} unit="g" color={T.blue}/>
          </div>
        </Surface>

        {/* Decision summary cards */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          <DecisionCard icon="car" label={t('opt.card.ev')}
            decision={s.key === 'overnight'
              ? t('opt.card.evDecOvernight')
              : t('opt.card.evDecOther')}
            color={T.blue} locked/>
          <DecisionCard icon="zap" label={t('opt.card.battery')}
            decision={t('opt.card.batteryDec')}
            color={T.green} locked/>
          <DecisionCard icon="thermometer" label={t('opt.card.hp')}
            decision={t('optimizer.decHP')}
            color={T.violet} locked/>
          <DecisionCard icon="upload" label={t('opt.card.feedin')}
            decision={t('optimizer.decExport')}
            color={T.amber} locked/>
        </div>
      </div>

      {/* Unified timeline */}
      <Surface style={{ marginBottom: 18 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 18 }}>
          <SurfaceLabel>{t('optimizer.timeline')}</SurfaceLabel>
          <span style={{ fontSize: 11, color: T.textMuted }}>{t('optimizer.fromNow', { hour: String(plan.nowH).padStart(2,'0') })}</span>
        </div>

        {/* Row labels + bars */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          {TIMELINE_ROWS.map(row => (
            <TimelineRow key={row.key} row={row} slots={plan.slots}/>
          ))}
        </div>

        {/* Time axis */}
        <TimelineAxis nowH={plan.nowH}/>
      </Surface>

      {/* SOC projection */}
      <Surface>
        <SurfaceLabel style={{ marginBottom: 14 }}>{t('optimizer.socTitle')}</SurfaceLabel>
        <SocProjection slots={plan.slots} startSoc={s.batterySOC}/>
        <div style={{ marginTop: 10, fontSize: 11, color: T.textMuted, lineHeight: 1.5 }}>
          {t('optimizer.socNote')}
        </div>
      </Surface>
    </div>
  );
}

// ── Timeline row ──────────────────────────────────────────────────────────
function TimelineRow({ row, slots }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
      {/* Label */}
      <div style={{ width: 120, flexShrink: 0, display: 'flex', alignItems: 'center', gap: 8 }}>
        <LI name={row.icon} size={14} color={T.textMuted}/>
        <span style={{ fontSize: 11, color: T.textMuted, fontWeight: 500 }}>{row.label}</span>
      </div>
      {/* Bar segments */}
      <div style={{ flex: 1, display: 'flex', gap: barDensity(slots.length).gap, height: row.height, alignItems: 'stretch' }}>
        {slots.map((slot, i) => (
          <TimelineSegment key={i} rowKey={row.key} slot={slot} height={row.height}/>
        ))}
      </div>
    </div>
  );
}

function TimelineSegment({ rowKey, slot, height }) {
  let bg = T.raised;
  let opacity = 1;

  switch (rowKey) {
    case 'tariff':
      bg = `${TIER_COLOR[slot.tariff.tier]}55`;
      if (slot.i === 0) bg = TIER_COLOR[slot.tariff.tier];
      break;
    case 'pv':
      const pvH = slot.solarKw / 8.4;
      bg = pvH > 0.05 ? `${T.amber}${Math.round(20 + pvH * 180).toString(16).padStart(2,'0')}` : T.raised;
      break;
    case 'battery':
      bg = slot.battDecision === 'grid-charge' ? `${T.green}55`
         : slot.battDecision === 'pv-charge' ? `${T.green}33`
         : slot.battDecision === 'discharge' ? `${T.blue}55`
         : T.raised;
      break;
    case 'ev':
      bg = slot.evCharging ? `${T.blue}66` : T.raised;
      break;
    case 'hp':
      bg = slot.hpSignal ? `${T.violet}55` : T.raised;
      break;
    case 'feedin':
      bg = slot.feedin ? `${T.amber}66` : T.raised;
      break;
  }

  return (
    <div style={{
      flex: 1, background: bg, borderRadius: 2,
      border: slot.i === 0 ? `1px solid ${T.textSecondary}44` : 'none',
    }}/>
  );
}

// ── Time axis ─────────────────────────────────────────────────────────────
function TimelineAxis({ nowH }) {
  const labels = [0, 6, 12, 18, 23].map(offset => {
    const h = (nowH + offset) % 24;
    return { offset, label: `${String(h).padStart(2,'0')}:00` };
  });
  return (
    <div style={{
      display: 'flex', justifyContent: 'space-between', marginTop: 10,
      paddingLeft: 132, fontFamily: T.fontMono, fontSize: 10, color: T.textMuted,
    }}>
      {labels.map(({ label }, i) => <span key={i}>{label}</span>)}
    </div>
  );
}

// ── SOC projection ─────────────────────────────────────────────────────────
function SocProjection({ slots, startSoc }) {
  const { t } = useLocale();
  // Simulate SOC evolution hour by hour
  let soc = startSoc;
  const socPts = slots.map((slot, i) => {
    if (slot.battDecision === 'grid-charge' || slot.battDecision === 'pv-charge') {
      soc = Math.min(100, soc + 4.5); // ~4.5% SOC per hour charging
    } else if (slot.battDecision === 'discharge') {
      soc = Math.max(20, soc - 3.2); // ~3.2% SOC per hour discharging
    }
    return { i, soc };
  });

  const W = 1000, H = 80, padY = 8;
  const toX = (i) => (i / (slots.length - 1)) * W;
  const toY = (v) => H - padY - ((v - 15) / 85) * (H - padY * 2);

  const pts = socPts.map(({ i, soc }) => ({ x: toX(i), y: toY(soc) }));
  const path = pts.reduce((acc, { x, y }, i) => {
    if (i === 0) return `M${x} ${y}`;
    const prev = pts[i-1];
    const mx = (prev.x + x) / 2, my = (prev.y + y) / 2;
    return acc + ` Q${prev.x} ${prev.y} ${mx} ${my}`;
  }, '') + ` T${pts[pts.length-1].x} ${pts[pts.length-1].y}`;

  // Target SOC lines
  const bufferY = toY(80);
  const reserveY = toY(20);

  return (
    <svg viewBox={`0 0 ${W} ${H}`} width="100%" height={H} preserveAspectRatio="none" style={{ display: 'block' }}>
      <defs>
        <linearGradient id="socProjGrad" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={T.green} stopOpacity="0.3"/>
          <stop offset="100%" stopColor={T.green} stopOpacity="0"/>
        </linearGradient>
      </defs>
      {/* Reference lines */}
      <line x1={0} y1={bufferY} x2={W} y2={bufferY} stroke={T.green} strokeOpacity="0.25" strokeDasharray="3 5"/>
      <line x1={0} y1={reserveY} x2={W} y2={reserveY} stroke={T.amber} strokeOpacity="0.25" strokeDasharray="3 5"/>
      <text x={W - 4} y={bufferY - 4} fontSize="9" fill={T.green} fillOpacity="0.5" textAnchor="end"
            style={{ fontFamily: T.fontMono }}>{t('optimizer.bufferLabel')}</text>
      <text x={W - 4} y={reserveY - 4} fontSize="9" fill={T.amber} fillOpacity="0.5" textAnchor="end"
            style={{ fontFamily: T.fontMono }}>{t('optimizer.reserveLabel')}</text>
      {/* Area + line */}
      <path d={path + ` L${W} ${H} L0 ${H} Z`} fill="url(#socProjGrad)"/>
      <path d={path} fill="none" stroke={T.green} strokeWidth="2" strokeLinecap="round"/>
      {/* Start dot */}
      <circle cx={pts[0].x} cy={pts[0].y} r="4" fill={T.green}/>
    </svg>
  );
}

// ── Small atoms ────────────────────────────────────────────────────────────
function OptKPI({ label, value, unit, color }) {
  return (
    <div>
      <div style={{ fontSize: 9, color: T.textMuted, fontWeight: 600, letterSpacing: 0.8, textTransform: 'uppercase', marginBottom: 5 }}>{label}</div>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 4 }}>
        <span style={{ fontFamily: T.fontMono, fontSize: 22, fontWeight: 700, color, fontVariantNumeric: 'tabular-nums' }}>{value}</span>
        <span style={{ fontSize: 11, color: T.textMuted }}>{unit}</span>
      </div>
    </div>
  );
}

function DecisionCard({ icon, label, decision, color, locked }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'flex-start', gap: 10, padding: '10px 14px',
      background: T.raised, borderRadius: 10, border: `1px solid ${T.border}`,
    }}>
      <LI name={icon} size={15} color={T.textMuted}/>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 3 }}>
          <span style={{ fontSize: 11, fontWeight: 600, color: T.textPrimary }}>{label}</span>
          {locked && <span style={{ fontSize: 9, color: T.textMuted }}>🔒</span>}
        </div>
        <div style={{ fontSize: 11, color: T.textMuted, lineHeight: 1.45, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{decision}</div>
      </div>
      <div style={{ width: 6, height: 6, borderRadius: '50%', background: color, flexShrink: 0, marginTop: 7, boxShadow: `0 0 8px ${color}` }}/>
    </div>
  );
}

Object.assign(window, { V2Optimizer, OptKPI, DecisionCard, TimelineRow, TimelineSegment, TimelineAxis, SocProjection });
