const RatingsContext = React.createContext(null);

function padDaysRange(rows, from, to) {
  const byDate = {};
  for (const r of rows) byDate[r.date] = r;
  const out = [];
  let cur = from;
  while (cur <= to) {
    if (byDate[cur]) {
      out.push(byDate[cur]);
    } else {
      out.push({
        date: cur,
        rating: 5,
        comment: null,
        authorId: null,
        authorName: null,
        authorAvatar: null,
        authorColor: null,
        isDefault: true,
      });
    }
    cur = shiftISO(cur, 1);
  }
  return out;
}

function RatingsProvider({ childId, children: reactChildren }) {
  const [rows, setRows] = React.useState([]);
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState(null);
  const [range, setRange] = React.useState(() => {
    const today = todayISO();
    const from = shiftISO(today, -200);
    const fromDate = new Date(from);
    const wd = (fromDate.getDay() + 6) % 7;
    const aligned = shiftISO(from, -wd);
    return { from: aligned, to: today };
  });

  const refresh = React.useCallback(async () => {
    if (childId == null) { setRows([]); return; }
    setLoading(true); setError(null);
    try {
      const { days } = await api.getRatings(childId, range.from, range.to);
      setRows(days || []);
    } catch (e) {
      setError(e);
      setRows([]);
    } finally {
      setLoading(false);
    }
  }, [childId, range.from, range.to]);

  React.useEffect(() => { refresh(); }, [refresh]);

  const saveRating = React.useCallback(async ({ date, rating, comment }) => {
    if (childId == null) return;
    await api.putRating(date, childId, rating, comment || null);
    await refresh();
  }, [childId, refresh]);

  const days = React.useMemo(
    () => padDaysRange(rows, range.from, range.to),
    [rows, range.from, range.to]
  );

  const value = {
    childId,
    days,
    rawDays: rows,
    loading,
    error,
    refresh,
    saveRating,
    range,
  };

  return <RatingsContext.Provider value={value}>{reactChildren}</RatingsContext.Provider>;
}

const useRatings = () => React.useContext(RatingsContext);

Object.assign(window, { RatingsContext, RatingsProvider, useRatings });
