"use client";

import { useQuery } from "@tanstack/react-query";
import type { CheckinStatusData } from "@alqove/api-client";
import { checkinApi } from "@/lib/checkin/api";

/** Slow-poll cadence for live mode (D7 — 30–60s, no websockets). */
export const POLL_INTERVAL_MS = 45_000;

/**
 * Terminal buy states — once here, nothing else moves and polling stops. The
 * status read doesn't expose an `is_terminal` flag, so we derive it from the
 * status enum (matching the API's BuyStatus terminal set).
 */
const TERMINAL_STATUSES = new Set([
  "voided",
  "no_buy",
  "accepted",
  "declined",
]);

export function isTerminalStatus(data: CheckinStatusData | undefined): boolean {
  return !!data && TERMINAL_STATUSES.has(data.status);
}

/**
 * The status read omits the store's visibility mode; queue position + ETA are
 * present ONLY in `live` mode. So their presence is our signal to keep polling
 * (confirmation_only stays static, relying on the completion SMS).
 */
export function isLiveStatus(data: CheckinStatusData | undefined): boolean {
  return (
    !!data &&
    (data.queue_position != null || data.estimated_wait_minutes != null)
  );
}

/**
 * Poll only while it's worth polling: live mode AND not yet terminal.
 * Returning `false` stops the interval entirely.
 */
export function statusRefetchInterval(
  data: CheckinStatusData | undefined,
): number | false {
  if (!data || isTerminalStatus(data)) return false;
  if (!isLiveStatus(data)) return false;
  return POLL_INTERVAL_MS;
}

function ContainerSummary({ status }: { status: CheckinStatusData }) {
  if (status.container_count == null) return null;
  return (
    <p className="mt-2 text-xs text-slate-400">
      {status.container_count} container
      {status.container_count === 1 ? "" : "s"}
    </p>
  );
}

function TerminalView({ status }: { status: CheckinStatusData }) {
  return (
    <div className="text-center">
      <div className="mb-2 text-4xl" aria-hidden="true">
        🎉
      </div>
      <h1 className="text-xl font-semibold text-slate-900">All done</h1>
      <p className="mt-2 text-sm text-slate-600">
        Your buy is complete. See staff for details — {status.status_label}.
      </p>
      <ContainerSummary status={status} />
    </div>
  );
}

function LiveView({ status }: { status: CheckinStatusData }) {
  return (
    <div className="text-center">
      <div className="mb-2 text-4xl" aria-hidden="true">
        ⏳
      </div>
      <h1 className="text-xl font-semibold text-slate-900">You&apos;re in line</h1>
      {status.queue_position != null ? (
        <p className="mt-2 text-sm text-slate-600">
          You&apos;re{" "}
          <span className="font-semibold text-slate-900">
            #{status.queue_position}
          </span>{" "}
          in line.
        </p>
      ) : (
        <p className="mt-2 text-sm text-slate-600">
          We&apos;ll update this page as the line moves.
        </p>
      )}
      {status.estimated_wait_minutes != null ? (
        <p className="mt-1 text-sm text-slate-500">
          Estimated wait: ~{status.estimated_wait_minutes} min
        </p>
      ) : null}
      <ContainerSummary status={status} />
    </div>
  );
}

function ConfirmationOnlyView({ status }: { status: CheckinStatusData }) {
  return (
    <div className="text-center">
      <div className="mb-2 text-4xl" aria-hidden="true">
        ✅
      </div>
      <h1 className="text-xl font-semibold text-slate-900">You&apos;re checked in</h1>
      <p className="mt-2 text-sm text-slate-600">
        Bring your containers to the counter — staff will take it from here.
      </p>
      <ContainerSummary status={status} />
    </div>
  );
}

export function StatusView({ status }: { status: CheckinStatusData }) {
  let body;
  if (isTerminalStatus(status)) {
    body = <TerminalView status={status} />;
  } else if (isLiveStatus(status)) {
    body = <LiveView status={status} />;
  } else {
    body = <ConfirmationOnlyView status={status} />;
  }

  return (
    <div className="mx-auto flex w-full max-w-md flex-col gap-6">
      {/* Announce status/position changes to assistive tech as the page polls. */}
      <div role="status" aria-live="polite">
        {body}
      </div>
    </div>
  );
}

/**
 * Live status of a check-in. Server-rendered initial data makes the page
 * reachable cold from the SMS deep link; the client query slow-polls only in
 * live mode and stops at a terminal state.
 */
export function StatusPoller({
  statusToken,
  initialStatus,
}: {
  statusToken: string;
  initialStatus: CheckinStatusData;
}) {
  const { data } = useQuery({
    queryKey: ["checkin-status", statusToken],
    queryFn: () => checkinApi.getStatus(statusToken).then((r) => r.data),
    initialData: initialStatus,
    refetchInterval: (query) => statusRefetchInterval(query.state.data),
  });

  return <StatusView status={data ?? initialStatus} />;
}
