/* global React, Widget, WeatherData, RangeTabs */
const { useMemo, useRef, useEffect, useState, useLayoutEffect } = React;

// =========================================================
// HourlyWidget — value-per-row matrix.
//
// Layout: one row per metric (time / icon / temp / precip / wind), columns
// are the hours. Reads top-to-bottom: "what changed for THIS metric across
// the next N hours?".
//
// Never squeezes: a column is at least MIN_COL px wide. When the tile is too
// narrow for every hour, hours are grouped by 2 / 3 / 4 / 6 — the column
// shows the first hour's time, icon and temperature, the SUM of precipitation
// and the highest chance of it, and the strongest wind in the group.
// Day boundaries get a thin vertical accent.
// =========================================================

const MIN_COL = 38;
const STEPS = [1, 2, 3, 4, 6, 8, 12];

window.HourlyWidget = function HourlyWidget({ hourly, range, onRangeChange, config = {}, nowCol = true }) {
  const ref = useRef(null);
  const [width, setWidth] = useState(0);
  useLayoutEffect(() => {
    const el = ref.current;
    if (!el) return undefined;
    const upd = () => setWidth(el.clientWidth);
    upd();
    const ro = new ResizeObserver(upd);
    ro.observe(el);
    return () => ro.disconnect();
  }, [hourly && hourly.length > 0]);

  if (!hourly || !hourly.length) return <div className="muted">Načítání…</div>;
  const showDate   = config.showDateHeader !== false;
  const showIcon   = config.showIcon       !== false;
  const showWind   = config.showWind       !== false;
  const showPrecip = config.showPrecip     !== false;

  const sliced = hourly.slice(0, range);
  const raw = width ? Math.ceil(sliced.length * MIN_COL * window.fontScale() / width) : 1;   // bigger text → wider columns
  const step = STEPS.find(s => s >= raw) || STEPS[STEPS.length - 1];

  // Group hours (step 1 = one column per hour).
  const groups = [];
  for (let i = 0; i < sliced.length; i += step) {
    const g = sliced.slice(i, i + step);
    const rep = g[0];
    const precip = g.reduce((s, h) => s + (h.precip > 0 ? h.precip : 0), 0);
    const prob = Math.max(...g.map(h => h.precipProb || 0));
    const windy = g.reduce((a, h) => ((h.wind || 0) > (a.wind || 0) ? h : a), g[0]);
    groups.push({ rep, precip, prob, wind: windy.wind, windDeg: windy.windDeg, last: g[g.length - 1] });
  }
  let lastDay = null;
  const cols = groups.map((c, i) => {
    const day = c.rep.time.getDate();
    const isDayEdge = lastDay !== null && lastDay !== day;
    lastDay = day;
    return { ...c, i, isDayEdge };
  });

  const N = cols.length;
  const gridStyle = { gridTemplateColumns: `repeat(${N}, minmax(0, 1fr))` };
  const colClass = (i, edge) =>
    `hm-cell ${i === 0 && nowCol ? 'is-now' : ''} ${edge ? 'is-day-edge' : ''} ${i % 2 ? 'is-odd' : ''}`;
  const tempStr = (t) => Math.round(window.Units ? window.Units.temp(t) : t);
  const windStr = (w) => Math.round(window.Units ? window.Units.wind(w) : w);
  const hh = (d) => String(d.getHours()).padStart(2, '0');

  return (
    <div className={`hourly-widget hourly-matrix ${step > 1 ? 'is-grouped' : ''}`} style={gridStyle} ref={ref}
         title={step > 1 ? `Sloučeno po ${step} h (srážky sečtené, vítr nejsilnější)` : undefined}>
      {showDate && cols.map(({ rep, i, isDayEdge }) => (
        <div key={`d${i}`} className={`${colClass(i, isDayEdge)} hm-date`}>
          {(i === 0 || isDayEdge) ? `${WeatherData.WD_SHORT[rep.time.getDay()]} ${rep.time.getDate()}.` : ''}
        </div>
      ))}
      {cols.map(({ rep, i, isDayEdge }) => (
        <div key={`t${i}`} className={`${colClass(i, isDayEdge)} hm-time`}>{hh(rep.time)}</div>
      ))}
      {showIcon && cols.map(({ rep, i, isDayEdge }) => (
        <div key={`i${i}`} className={`${colClass(i, isDayEdge)} hm-icon`}>
          <img src={WeatherData.iconUrl(rep.icon)} alt={rep.cond || ''} />
        </div>
      ))}
      {cols.map(({ rep, i, isDayEdge }) => (
        <div key={`te${i}`} className={`${colClass(i, isDayEdge)} hm-temp`}>{tempStr(rep.temp)}°</div>
      ))}
      {showPrecip && cols.map(({ precip, prob, i, isDayEdge }) => {
        const p = prob >= 15 ? prob : null;
        const amt = precip > 0.1 ? (window.Units ? window.Units.rain(precip) : precip) : null;
        return (
          <div key={`p${i}`} className={`${colClass(i, isDayEdge)} hm-precip ${p == null && amt == null ? 'empty' : ''}`}>
            {p != null && <span className="hm-pop">{p}%</span>}
            {amt != null && <span className="hm-mm">{window.czNum(amt, 1)}</span>}
          </div>
        );
      })}
      {showWind && cols.map(({ wind, windDeg, i, isDayEdge }) => (
        <div key={`w${i}`} className={`${colClass(i, isDayEdge)} hm-wind`}>
          <i className="bi bi-arrow-up" style={{ transform: `rotate(${(windDeg || 0) + 180}deg)` }}></i>
          <span>{windStr(wind)}</span>
        </div>
      ))}
    </div>
  );
};
