/* global React, WeatherData */

// Denní přehled — one row per day, rows from the TOP of the tile: Dnes / Zítra /
// weekday + date, icon with the day's highest chance of rain (from the hourly
// data, ≥ 20 %), min · range bar · max, precipitation. The bar sits on one
// shared scale for all days (so days compare at a glance) and is coloured by the
// station page's temperature scale from the day's min to its max; today's bar
// has a dot at the temperature measured now. Zero precipitation is dimmed;
// strong gusts (≥ 15 m/s) get a small warning. A short-range model (WRF: 3 days)
// is continued with MASTER's later days under „Další dny · MASTER“ (`more`,
// option showMore). A day with hourly data opens its hours (DayDetail) — like
// „Dnes ◀ ▶“ on the original page; ‹ › and ← → move between days.
const sameDay = (a, b) => a.toDateString() === b.toDateString();
const dayName = (date, long = true) => {
  const t = new Date(); t.setHours(0, 0, 0, 0);
  const diff = Math.round((new Date(date).setHours(0, 0, 0, 0) - t) / 86400e3);
  if (diff === 0) return 'Dnes';
  if (diff === 1) return 'Zítra';
  return (long ? WeatherData.WD_LONG : WeatherData.WD_SHORT)[date.getDay()];
};

function DayDetail({ days, dayKey, hoursOf, onPick, onClose }) {
  const i = days.findIndex(d => d.date.toDateString() === dayKey);
  const day = days[i];
  const prev = days[i - 1], next = days[i + 1];
  React.useEffect(() => {
    const onKey = (e) => {
      if (e.key === 'ArrowLeft' && prev) onPick(prev.date.toDateString());
      if (e.key === 'ArrowRight' && next) onPick(next.date.toDateString());
    };
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, [prev, next]);
  if (!day) return null;
  const hours = hoursOf(day.date);
  const isToday = sameDay(day.date, new Date());
  const name = `${dayName(day.date)} ${day.date.getDate()}. ${day.date.getMonth() + 1}.`;
  const tU = (v) => Math.round(window.Units ? window.Units.temp(v) : v);
  const rain = hours.reduce((s, h) => s + (h.precip > 0 ? h.precip : 0), 0);
  const gust = Math.max(0, ...hours.map(h => h.gust || 0));
  const prob = Math.max(0, ...hours.map(h => h.precipProb || 0));
  const wU = window.Units ? window.Units.windLabel() : 'm/s';
  const title = (
    <span className="dd-nav">
      <button type="button" disabled={!prev} onClick={() => onPick(prev.date.toDateString())} aria-label="Předchozí den"><i className="bi bi-chevron-left" /></button>
      <span>{name}</span>
      <button type="button" disabled={!next} onClick={() => onPick(next.date.toDateString())} aria-label="Následující den"><i className="bi bi-chevron-right" /></button>
    </span>
  );
  return (
    <window.Modal title={title} onClose={onClose} wide kind="day">
      <div className="dd-sum">
        <img src={WeatherData.iconUrl(day.icon)} alt="" width="40" height="40" />
        <div className="dd-cond"><b>{day.cond}</b><span>{isToday ? `zbývá ${hours.length} h` : `${hours.length} h hodinové předpovědi`}</span></div>
        <div><small>teplota</small><b>{tU(day.tmin)}° až {tU(day.tmax)}°</b></div>
        <div><small>srážky</small><b>{rain < 0.1 ? 'žádné' : `${window.czNum(window.Units ? window.Units.rain(rain) : rain, 1)} ${window.Units ? window.Units.rainLabel() : 'mm'}`}</b>{prob >= 15 && <span>až {prob} %</span>}</div>
        <div><small>nárazy</small><b>{window.czNum(window.Units ? window.Units.wind(gust) : gust, 0)} {wU}</b></div>
      </div>
      <div className="dd-chart">
        <window.ChartWidget hourly={hours} onConfigChange={() => {}} widgetConfig={{}}
          config={{ temp: true, precip: true, wind: true, humidity: false, pressure: false, icons: true, hours: hours.length }} />
      </div>
      <div className="dd-hours"><window.HourlyWidget hourly={hours} range={hours.length} nowCol={isToday} /></div>
    </window.Modal>
  );
}

window.DailyWidget = function DailyWidget({ daily, hourly, more, nowTemp, config = {} }) {
  const [openDay, setOpenDay] = React.useState(null);
  if (!daily || !daily.length) return <div className="muted">Načítání…</div>;
  const hoursOf = (date) => (hourly || []).filter(h => sameDay(h.time, date));
  const showRangeBar = config.showRangeBar !== false;
  const showPrecipCol = config.showPrecipCol !== false;
  const showIcon = config.showIcon !== false;
  const showProb = config.showProb !== false;
  // days after the picked model's last one, from MASTER (longest range)
  const last = daily[daily.length - 1].date;
  const extra = config.showMore === false ? []
    : (more || []).filter(d => d.date > last && !sameDay(d.date, last));
  const days = [...daily, ...extra];
  const withHours = daily.filter(d => hoursOf(d.date).length >= 2);
  const tNow = nowTemp != null && nowTemp !== '' && !isNaN(nowTemp) ? Number(nowTemp) : null;
  const tMinAll = Math.min(...days.map(d => d.tmin), tNow ?? Infinity);
  const tMaxAll = Math.max(...days.map(d => d.tmax), tNow ?? -Infinity);
  const range = tMaxAll - tMinAll || 1;
  const pos = (v) => ((v - tMinAll) / range) * 100;
  const dark = window.isDarkTheme ? window.isDarkTheme() : true;
  const tc = (v) => (window.tempColor ? window.tempColor(v, dark) : 'var(--accent)');
  const tU = (v) => Math.round(window.Units ? window.Units.temp(v) : v);
  const cols = ['minmax(0, 1fr)'];
  if (showIcon) cols.push('auto');
  cols.push('minmax(0, 1.7fr)');
  if (showPrecipCol) cols.push('auto');
  const gridStyle = { gridTemplateColumns: cols.join(' ') };
  const row = (d, i) => {
    const isToday = sameDay(d.date, new Date());
    const rain = d.precip || 0;
    const gusty = d.gust != null && d.gust >= 15;
    const hrs = daily.includes(d) ? hoursOf(d.date) : [];
    const prob = Math.max(0, ...hrs.map(h => h.precipProb || 0));
    const canOpen = withHours.includes(d);
    const open = () => setOpenDay(d.date.toDateString());
    const wkend = d.date.getDay() === 0 || d.date.getDay() === 6;
    return (
      <div key={i} className={`daily-row ${isToday ? 'is-today' : ''} ${canOpen ? 'is-clickable' : ''}`} style={gridStyle}
           {...(canOpen ? { role: 'button', tabIndex: 0, title: 'Hodinová předpověď na tento den', onClick: open,
                onKeyDown: (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); open(); } } } : {})}>
        <div className="d-day">
          <strong>{dayName(d.date)}</strong>
          <small className={wkend ? 'is-wkend' : undefined}>{dayName(d.date) === WeatherData.WD_LONG[d.date.getDay()] ? '' : `${WeatherData.WD_SHORT[d.date.getDay()]} `}{d.date.getDate()}. {d.date.getMonth() + 1}.</small>
        </div>
        {showIcon && (
          <div className="d-icon">
            <img src={WeatherData.iconUrl(d.icon)} alt={d.cond} title={d.cond} />
            {showProb && prob >= 20 && <span className="d-prob" title="Nejvyšší pravděpodobnost srážek v tento den">{prob} %</span>}
          </div>
        )}
        <div className="d-temp-bar">
          <span className="d-tmin">{tU(d.tmin)}°</span>
          {showRangeBar && (
            <div className="d-bar">
              <i style={{ left: pos(d.tmin) + '%', right: (100 - pos(d.tmax)) + '%', background: `linear-gradient(90deg, ${tc(d.tmin)}, ${tc(d.tmax)})` }}></i>
              {isToday && tNow != null && (
                <b className="d-now" style={{ left: pos(tNow) + '%', background: tc(tNow) }}
                   title={`Teď na stanici ${window.fmtNum(window.Units ? window.Units.temp(tNow) : tNow, 1)}°`}></b>
              )}
            </div>
          )}
          <span className="d-tmax">{tU(d.tmax)}°</span>
        </div>
        {showPrecipCol && (
          <div className={`d-precip ${rain < 0.1 ? 'is-zero' : ''}`} title={gusty ? `Nárazy větru až ${window.czNum(d.gust, 0)} m/s` : undefined}>
            {gusty && <i className="bi bi-wind d-gust" aria-hidden="true"></i>}
            <i className="bi bi-droplet-fill" aria-hidden="true"></i>
            {rain < 0.1 ? '0' : window.czNum(window.Units ? window.Units.rain(rain) : rain, rain < 10 ? 1 : 0)}
            <small>{window.Units ? window.Units.rainLabel() : 'mm'}</small>
          </div>
        )}
      </div>
    );
  };
  return (
    <div className="daily-list">
      {daily.map(row)}
      {extra.length > 0 && (
        <div className="daily-sep" title="Vybraný model nepředpovídá tak daleko — další dny jsou z modelu MASTER">
          <span>Další dny · MASTER</span>
        </div>
      )}
      {extra.map((d, i) => row(d, daily.length + i))}
      {openDay && <DayDetail days={withHours} dayKey={openDay} hoursOf={hoursOf} onPick={setOpenDay} onClose={() => setOpenDay(null)} />}
    </div>
  );
};
