"use client";

import { useMemo, useState } from "react";
import { api, Trip, TripDetail, TripRow } from "@/lib/api";
import { useApi } from "@/hooks/useApi";
import { useLocale } from "@/i18n/LocaleProvider";
import { TripMap } from "@/components/TripMap";
import {
  Button,
  Card,
  EmptyState,
  ErrorState,
  Field,
  Numeric,
  PageHeader,
  Sheet,
  SkeletonTable,
  StatusBadge,
  Tone,
} from "@/components/ui";

const statusTone: Record<string, Tone> = {
  COMPLETED: "success",
  ACTIVE: "info",
  ENDING: "warning",
  PENDING_UNLOCK: "warning",
  EXPIRED: "neutral",
  CANCELLED: "neutral",
};

/** Seconds as an operator reads a ride length: "8m 53s", not 533. */
function duration(seconds: number): string {
  const m = Math.floor(seconds / 60);
  const s = seconds % 60;
  return m > 0 ? `${m}m ${s}s` : `${s}s`;
}

/** Metres below a kilometre, kilometres above it, one decimal. */
function distance(metres: number | null): string {
  if (metres == null) return "-";
  return metres < 1000 ? `${metres} m` : `${(metres / 1000).toFixed(1)} km`;
}

export default function Page() {
  const { t } = useLocale();
  const trips = useApi<TripRow[]>(() => api.listTrips({ limit: 200 }), []);
  const [query, setQuery] = useState("");
  const [selected, setSelected] = useState<Trip | null>(null);

  const rows = trips.data ?? [];
  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return rows;
    return rows.filter((r) =>
      `${r.qrCode ?? ""} ${r.trip.id} ${r.trip.userId}`.toLowerCase().includes(q),
    );
  }, [rows, query]);

  const completed = rows.filter((r) => r.trip.status === "COMPLETED");
  const revenue = completed.reduce((sum, r) => sum + (r.trip.fare.total ?? 0), 0);

  return (
    <div>
      <PageHeader
        titleKey="nav.trips"
        subtitle={
          trips.data ? (
            <>
              <Numeric>{completed.length}</Numeric> {t("trips.completed")}
              {" · "}
              <Numeric>{revenue.toFixed(2)}</Numeric> {t("common.sar")}
            </>
          ) : undefined
        }
        actions={<Button onClick={trips.reload}>{t("common.refresh")}</Button>}
      />

      <Card className="mb-4">
        <Field
          label={t("trips.search")}
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          placeholder="BEEB-0102"
        />
      </Card>

      {trips.loading && !trips.data && <SkeletonTable rows={6} />}
      {trips.error ? <ErrorState onRetry={trips.reload} /> : null}

      {trips.data &&
        (filtered.length === 0 ? (
          <EmptyState
            icon={<span className="text-xl">🧾</span>}
            title={t("trips.emptyTitle")}
            description={t("trips.emptyBody")}
          />
        ) : (
          <div className="card overflow-x-auto">
            <table className="w-full min-w-[900px] text-sm">
              <thead>
                <tr className="border-b border-line bg-surface-raised/60">
                  <Th>{t("trips.colVehicle")}</Th>
                  <Th>{t("trips.colWhen")}</Th>
                  <Th>{t("trips.colDuration")}</Th>
                  <Th>{t("trips.colDistance")}</Th>
                  <Th>{t("trips.colFare")}</Th>
                  <Th>{t("trips.colStatus")}</Th>
                </tr>
              </thead>
              <tbody>
                {filtered.map(({ trip, qrCode }) => (
                  <tr
                    key={trip.id}
                    onClick={() => setSelected(trip)}
                    className="cursor-pointer border-b border-line transition last:border-b-0 hover:bg-surface-raised"
                  >
                    <td className="px-4 py-3.5">
                      <div className="font-medium">
                        {/* A trip outlives its vehicle, so a deleted one still shows an id. */}
                        <Numeric>{qrCode ?? trip.scooterId.slice(0, 8)}</Numeric>
                      </div>
                      <div className="text-xs text-muted">
                        <Numeric>{trip.trackPoints}</Numeric> {t("trips.points")}
                      </div>
                    </td>
                    <td className="px-4 py-3.5 text-xs text-muted">
                      {trip.endedAt ? new Date(trip.endedAt).toLocaleString() : "-"}
                    </td>
                    <td className="px-4 py-3.5">
                      <Numeric>{duration(trip.durationSeconds)}</Numeric>
                    </td>
                    <td className="px-4 py-3.5">
                      <Numeric>{distance(trip.distanceMeters)}</Numeric>
                    </td>
                    <td className="px-4 py-3.5 font-medium">
                      <Numeric>{(trip.fare.total ?? 0).toFixed(2)}</Numeric>{" "}
                      <span className="text-xs font-normal text-muted">{trip.currency}</span>
                    </td>
                    <td className="px-4 py-3.5">
                      <StatusBadge tone={statusTone[trip.status] ?? "neutral"}>
                        {trip.status}
                      </StatusBadge>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        ))}

      <TripSheet trip={selected} onClose={() => setSelected(null)} />
    </div>
  );
}

function Th({ children }: { children: React.ReactNode }) {
  return (
    <th className="px-4 py-3 text-start text-xs font-semibold uppercase tracking-wide text-muted">
      {children}
    </th>
  );
}

/* --------------------------------------------------------------------- detail */

/**
 * One trip in full: where it went, how long it took, and exactly how the fare was built.
 *
 * <p>The fare is itemised because the total alone is what starts a support call. Unlock fee,
 * billed minutes at their rate, and any parking fee add up on screen to the number the rider was
 * charged.
 */
function TripSheet({ trip, onClose }: { trip: Trip | null; onClose: () => void }) {
  const { t } = useLocale();
  const detail = useApi<TripDetail | null>(
    () => (trip ? api.trip(trip.id) : Promise.resolve(null)),
    [trip?.id],
  );

  if (!trip) return null;
  const d = detail.data?.detail;
  const fare = d?.trip.fare ?? trip.fare;

  return (
    <Sheet open onClose={onClose} title={detail.data?.qrCode ?? t("nav.trips")}>
      <div className="space-y-4">
        <TripMap
          track={d?.track ?? []}
          start={
            trip.startLat != null && trip.startLng != null
              ? { lat: trip.startLat, lng: trip.startLng }
              : null
          }
          end={
            trip.endLat != null && trip.endLng != null
              ? { lat: trip.endLat, lng: trip.endLng }
              : null
          }
        />

        <div className="card divide-y divide-line">
          <Row label={t("trips.colStatus")} value={trip.status} />
          <Row
            label={t("trips.started")}
            value={trip.startedAt ? new Date(trip.startedAt).toLocaleString() : "-"}
          />
          <Row
            label={t("trips.ended")}
            value={trip.endedAt ? new Date(trip.endedAt).toLocaleString() : "-"}
          />
          <Row label={t("trips.colDuration")} value={duration(trip.durationSeconds)} />
          <Row label={t("trips.colDistance")} value={distance(trip.distanceMeters)} />
          <Row label={t("trips.points")} value={String(d?.track.length ?? trip.trackPoints)} />
          <Row label={t("trips.rider")} value={trip.userId.slice(0, 8)} mono />
        </div>

        {/* The receipt. Each line is a real component of the total, not a restatement of it. */}
        <div className="card divide-y divide-line">
          <div className="px-4 py-3 text-sm font-semibold">{t("trips.fareTitle")}</div>
          <Row label={t("trips.unlockFee")} value={(fare.unlockFee ?? 0).toFixed(2)} mono />
          <Row
            label={`${t("trips.timeCharge")} (${fare.minutes} × ${(fare.perMinuteRate ?? 0).toFixed(2)})`}
            value={(fare.timeAmount ?? 0).toFixed(2)}
            mono
          />
          <Row label={t("trips.parkingFee")} value={(fare.parkingFee ?? 0).toFixed(2)} mono />
          <div className="flex items-center justify-between px-4 py-3">
            <span className="text-sm font-semibold">{t("trips.total")}</span>
            <span className="text-base font-semibold">
              <Numeric>{(fare.total ?? 0).toFixed(2)}</Numeric>{" "}
              <span className="text-xs font-normal text-muted">{trip.currency}</span>
            </span>
          </div>
        </div>

        {d?.invoice && (
          <p className="text-xs text-muted">
            {t("trips.invoice")}: <Numeric>{d.invoice.id.slice(0, 8)}</Numeric>
            {" · "}
            <Numeric>{new Date(d.invoice.createdAt).toLocaleString()}</Numeric>
          </p>
        )}
        {detail.error ? <ErrorState onRetry={detail.reload} /> : null}
      </div>
    </Sheet>
  );
}

function Row({ label, value, mono }: { label: string; value: string; mono?: boolean }) {
  return (
    <div className="flex items-center justify-between gap-3 px-4 py-3">
      <span className="text-sm text-muted">{label}</span>
      <span className="text-sm font-medium">{mono ? <Numeric>{value}</Numeric> : value}</span>
    </div>
  );
}
