// Phase 3: one view of a saved report. Register keys here so shared data.jsx
// can page both tables past 1,000 rows without modifying another job's file.
Object.assign(TABLE_KEYS, { pacing_weeks: "week_date", market_daily: "date" });

function PacingPage() {
  const weeksState = useTables(["pacing_weeks"]);
  const marketState = useTables(["market_daily"]);
  const [selected, setSelected] = React.useState(null);
  const math = window.AretePacingWeeks;
  const weeks = math.orderedWeeks(weeksState.data.pacing_weeks);
  const selectedIndex = weeks.findIndex(w => w.week_date === selected);
  const index = selectedIndex < 0 ? weeks.length - 1 : selectedIndex;
  const week = weeks[index];
  const dateLabel = value => new Date(value + "T12:00:00Z")
    .toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric", timeZone: "UTC" });
  const missing = <span aria-label="Not recorded" title="Not recorded">—</span>;
  const amount = (value, digits = 0) => math.number(value) === null ? missing :
    math.number(value).toLocaleString("en-US", { minimumFractionDigits: digits, maximumFractionDigits: Math.max(1, digits) });
  const percent = value => math.percent(value) === null ? missing : <>{amount(value)}%</>;
  const gap = value => value === null ? missing : <span className={"pacing-gap " + value.className}
    aria-label={`${value.amount} percentage points ${value.word}`}>
    <span aria-hidden="true">{value.symbol} </span>{value.amount} {value.word}
  </span>;
  const card = (label, children) => <div className="tcard scrollx pacing-table" role="region" aria-label={label} tabIndex={0}>{children}</div>;

  if (weeksState.status === "loading") return <Loading />;
  if (weeksState.status === "error") return <LoadError error={weeksState.error} onRetry={weeksState.reload} />;
  if (!week) return <NoData>No Sunday pacing reports yet. The next report will appear here after it is pushed.</NoData>;

  const comps = Array.isArray(week.comps) ? week.comps : [];
  const average = math.compAverages(comps);
  const market = math.marketForWeek(week, marketState.data.market_daily, { isLatest: index === weeks.length - 1 });
  const move = delta => {
    const next = index + delta;
    if (next >= 0 && next < weeks.length) setSelected(next === weeks.length - 1 ? null : weeks[next].week_date);
  };
  return <div className="pacing-page">
    <div className="weekbar">
      <button className="arrow" onClick={() => move(-1)} disabled={index === 0} aria-label="Earlier week"><Icon name="left" size={18} /></button>
      <div aria-live="polite" aria-atomic="true"><div className="label">Week of {dateLabel(week.week_date)}</div>
        <div className="ago">{index === weeks.length - 1 ? "Latest Sunday report" : "Older report"}</div></div>
      <button className="arrow" onClick={() => move(1)} disabled={index === weeks.length - 1} aria-label="Later week"><Icon name="right" size={18} /></button>
    </div>
    <section>
      <div className="secthead"><h2>Us vs comps</h2></div>
      <p className="sub">Share of nights booked in the next 30 / 60 / 90 days</p>
      {!comps.length && <NoData>No comp calendar was saved for this report.</NoData>}
      {card("Us vs comps", <table className="tbl"><thead><tr><th scope="col">Home</th>{[30, 60, 90].map(h => <th key={h} scope="col" className="r">{h} days</th>)}</tr></thead>
        <tbody>{comps.map(c => <tr key={c.id}><td>{c.name}</td>{[30, 60, 90].map(h => <td key={h} className="r num">{percent(c["occ_" + h])}</td>)}</tr>)}
          <tr className="avg"><td>Comp average</td>{[30, 60, 90].map(h => <td key={h} className="r num">{percent(average["occ_" + h])}</td>)}</tr>
          <tr className="us"><td>Us</td>{[30, 60, 90].map(h => <td key={h} className="r num">{percent(week["us_occ_" + h])}</td>)}</tr>
          <tr><td className="pacing-muted">Us vs average</td>{[30, 60, 90].map(h => <td key={h} className="r num">{gap(math.gap(week["us_occ_" + h], average["occ_" + h]))}</td>)}</tr>
        </tbody></table>)}
    </section>
    <section>
      <div className="secthead"><h2>Us vs market</h2></div>
      <p className="sub">Share of nights booked · market from PriceLabs, refreshed daily</p>
      {marketState.status === "loading" ? <Loading height={220} /> : marketState.status === "error" ?
        <LoadError error={marketState.error} onRetry={marketState.reload} /> : <>
          {market.rows.every(r => r.us === null && r.market === null) ? <NoData>No market figures are available for this view.</NoData> : <>
            {card("Us vs market", <table className="tbl"><thead><tr><th scope="col">Next</th><th scope="col" className="r">Us</th><th scope="col" className="r">Market</th><th scope="col" className="r">Gap</th></tr></thead>
              <tbody>{market.rows.map(r => <tr key={r.days}><td>{r.days} days</td><td className="r num">{percent(r.us)}</td><td className="r num">{percent(r.market)}</td><td className="r num">{gap(r.gap)}</td></tr>)}</tbody></table>)}
            <p className="pacing-note">{market.source === "daily" ? "Daily PriceLabs snapshot" : "Saved report figures"} · {dateLabel(market.date)}. Gaps are percentage points.</p>
          </>}
        </>}
    </section>
    <section>
      <div className="secthead"><h2>Booked in the last 7 days</h2></div>
      <p className="sub">New stays and nights added since the week before</p>
      {!comps.some(c => c.new_stays != null || c.new_nights != null) && <NoData>No full seven-day comp comparison was saved for this report.</NoData>}
      {card("Booked in the last 7 days", <table className="tbl"><thead><tr><th scope="col">Home</th><th scope="col" className="r">New stays</th><th scope="col" className="r">Nights</th></tr></thead>
        <tbody>{comps.map(c => <tr key={c.id}><td>{c.name}</td><td className="r num">{amount(c.new_stays)}</td><td className="r num">{amount(c.new_nights)}</td></tr>)}
          <tr className="avg"><td>Comp average</td><td className="r num">{amount(average.new_stays, 1)}</td><td className="r num">{amount(average.new_nights, 1)}</td></tr>
          <tr className="us"><td>Us</td><td className="r num">{amount(week.us_new_stays)}</td><td className="r num">{amount(week.us_new_nights)}</td></tr>
        </tbody></table>)}
      <p className="pacing-note">Comp pickup covers the next {week.pickup_window_days || 60} nights. Consecutive nights newly closed count as an estimated stay; owner blocks count too.
        {week.comp_baseline_date && <> Compared with {dateLabel(week.comp_baseline_date)}.</>} Our stays use the report’s booking-date count. A dash means not recorded; averages use known values only.</p>
    </section>
  </div>;
}

window.ARETE_PAGES = Object.assign(window.ARETE_PAGES || {}, { "dashboard/pacing": PacingPage });
