"use client";

import { useCallback, useEffect, useState } from "react";

import { api, type WavePreview } from "@/lib/api/browser";

import { Button, Card, Empty, ErrorNote, Loading, formatDateTime } from "./ui";

/**
 * Reminder wave preview (task 5.4, spec reminders).
 *
 * Read-mostly by design. The waves themselves are computed by the worker from each event's
 * date; this screen exists so the host can see *exactly when* each one will land and how
 * many people it reaches, before it does — the alternative is finding out on the day.
 */
export default function RemindersView() {
  const [waves, setWaves] = useState<WavePreview[] | null>(null);
  const [error, setError] = useState<unknown>(null);

  const load = useCallback(async () => {
    try {
      setWaves(await api.reminderPreview());
      setError(null);
    } catch (err) {
      setError(err);
    }
  }, []);

  useEffect(() => {
    void load();
  }, [load]);

  if (error) return <ErrorNote error={error} />;
  if (!waves) return <Loading label="Computing waves…" />;

  const byEvent = waves.reduce<Record<string, WavePreview[]>>((acc, wave) => {
    (acc[wave.event_slug] ??= []).push(wave);
    return acc;
  }, {});

  if (waves.length === 0) {
    return (
      <Card>
        <Empty>
          No upcoming waves. Either every event has passed, or reminder schedules have not
          been created yet.
        </Empty>
      </Card>
    );
  }

  return (
    <div className="space-y-4">
      {Object.entries(byEvent).map(([slug, eventWaves]) => (
        <Card key={slug} title={slug}>
          <ul className="divide-y divide-stone-100">
            {eventWaves
              .slice()
              .sort((a, b) => b.offset_days - a.offset_days)
              .map((wave) => (
                <li
                  key={`${slug}-${wave.offset_days}`}
                  className="flex flex-wrap items-baseline gap-x-4 gap-y-1 py-3"
                >
                  <span className="w-16 shrink-0 font-medium">T−{wave.offset_days}</span>
                  <span className="text-sm text-stone-700">{formatDateTime(wave.send_at)}</span>

                  {wave.skipped_past ? (
                    // A "2 days to go" email arriving the morning after is worse than
                    // none, so a past wave is skipped rather than sent late (FR-6.7).
                    <span className="rounded-full bg-stone-200 px-2 py-0.5 text-xs text-stone-600">
                      skipped — already passed
                    </span>
                  ) : (
                    <span className="text-sm text-stone-600">
                      {wave.recipients} recipient{wave.recipients === 1 ? "" : "s"}
                    </span>
                  )}

                  {wave.no_email > 0 && !wave.skipped_past && (
                    <span className="text-sm text-amber-700">
                      {wave.no_email} unreachable (no email)
                    </span>
                  )}
                </li>
              ))}
          </ul>
        </Card>
      ))}

      <p className="text-xs text-stone-500">
        Times are Asia/Dhaka. Nothing is sent between 22:00 and 08:00 — a send that becomes
        due inside that window waits until 08:00.
      </p>

      <Button variant="secondary" onClick={() => void load()}>
        Refresh
      </Button>
    </div>
  );
}
