"use client";

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

export type AthenaAuthCurrentSessionOverview = {
  city?: string | null;
  region?: string | null;
  country?: string | null;
  timezone?: string | null;
  ipAddress?: string | null;
  mapImageUrl?: string | null;
  mapAlt?: string;
};

export type AthenaAuthSessionOverviewRow = {
  id: string;
  location: string;
  createdOn: string | null;
  expiresOn: string | null;
  isCurrent?: boolean;
};

export type AthenaAuthSessionOverviewProps = {
  heading?: string;
  loading?: boolean;
  error?: string | null;
  currentSession: AthenaAuthCurrentSessionOverview;
  sessions: AthenaAuthSessionOverviewRow[];
  onSignOutAllDevices?: () => void | Promise<void>;
  signOutAllDevicesPending?: boolean;
};

const DEFAULT_MAP_FALLBACK =
  "data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='640' height='280' viewBox='0 0 640 280'%3E%3Cdefs%3E%3ClinearGradient id='a' x1='0' y1='0' x2='1' y2='1'%3E%3Cstop offset='0%25' stop-color='%23dbeafe'/%3E%3Cstop offset='100%25' stop-color='%23bfdbfe'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='640' height='280' rx='18' fill='url(%23a)'/%3E%3Cg stroke='%2393c5fd' stroke-width='1'%3E%3Cpath d='M0 40h640M0 80h640M0 120h640M0 160h640M0 200h640M0 240h640'/%3E%3Cpath d='M80 0v280M160 0v280M240 0v280M320 0v280M400 0v280M480 0v280M560 0v280'/%3E%3C/g%3E%3Cg fill='none' stroke='%231d4ed8' stroke-width='4'%3E%3Ccircle cx='320' cy='140' r='36'/%3E%3Cpath d='M320 86v108M266 140h108'/%3E%3C/g%3E%3Ctext x='320' y='254' font-size='18' text-anchor='middle' fill='%231e3a8a' font-family='ui-sans-serif,system-ui,sans-serif'%3EMap preview%3C/text%3E%3C/svg%3E";

const PAGE_SIZES = [10, 20, 50] as const;

function renderCellValue(value: string | null | undefined): string {
  if (typeof value === "string" && value.trim().length > 0) {
    return value;
  }
  return "-";
}

export function AthenaAuthSessionOverview({
  heading = "Your sessions",
  loading = false,
  error = null,
  currentSession,
  sessions,
  onSignOutAllDevices,
  signOutAllDevicesPending = false,
}: AthenaAuthSessionOverviewProps) {
  const [pageSize, setPageSize] = useState<(typeof PAGE_SIZES)[number]>(10);
  const [page, setPage] = useState(1);

  const pageCount = useMemo(
    () => Math.max(1, Math.ceil(Math.max(sessions.length, 1) / pageSize)),
    [pageSize, sessions.length],
  );

  useEffect(() => {
    setPage((current) => Math.min(current, pageCount));
  }, [pageCount]);

  const pagedRows = useMemo(() => {
    const start = (page - 1) * pageSize;
    return sessions.slice(start, start + pageSize);
  }, [page, pageSize, sessions]);

  return (
    <main className="mx-auto mt-10 w-full max-w-5xl px-4 pb-10 text-slate-900">
      <header className="mb-8">
        <h1 className="text-4xl font-light tracking-tight">{heading}</h1>
      </header>
      <div className="mb-10 h-px w-full bg-slate-200" />

      <section className="space-y-4">
        <h2 className="text-2xl font-medium">Current session</h2>
        <div className="grid gap-6 rounded-2xl border border-slate-200 bg-white p-5 md:grid-cols-[2fr_1.8fr] md:p-6">
          <div className="overflow-hidden rounded-2xl border border-slate-200 bg-slate-50">
            <img
              src={currentSession.mapImageUrl || DEFAULT_MAP_FALLBACK}
              alt={currentSession.mapAlt || "Current session map preview"}
              className="block h-full w-full object-cover"
            />
          </div>

          <dl className="grid grid-cols-[minmax(96px,1fr)_1fr] gap-x-4 gap-y-2 text-sm md:text-base">
            <dt className="text-slate-500">City</dt>
            <dd className="text-right">{renderCellValue(currentSession.city)}</dd>
            <dt className="text-slate-500">Region</dt>
            <dd className="text-right">{renderCellValue(currentSession.region)}</dd>
            <dt className="text-slate-500">Country</dt>
            <dd className="text-right">{renderCellValue(currentSession.country)}</dd>
            <dt className="text-slate-500">Timezone</dt>
            <dd className="text-right">{renderCellValue(currentSession.timezone)}</dd>
            <dt className="text-slate-500">IP Address</dt>
            <dd className="text-right">{renderCellValue(currentSession.ipAddress)}</dd>
          </dl>
        </div>
      </section>

      <div className="my-10 h-px w-full bg-slate-200" />

      <section className="space-y-4">
        <div className="flex flex-wrap items-center justify-between gap-2">
          <h2 className="text-2xl font-medium">Active sessions</h2>
          <span className="rounded-full border border-slate-300 px-3 py-1 text-xs uppercase tracking-wide text-slate-600">
            {loading ? "syncing" : "live"}
          </span>
        </div>

        {error ? (
          <p className="rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
            {error}
          </p>
        ) : null}

        <div className="overflow-hidden rounded-2xl border border-slate-200 bg-white">
          <div className="flex flex-wrap items-center justify-between gap-3 border-b border-slate-200 px-4 py-3 text-sm">
            <div className="flex items-center gap-2">
              <label htmlFor="session-page-size" className="text-slate-600">
                Displaying
              </label>
              <select
                id="session-page-size"
                value={pageSize}
                onChange={(event) => {
                  const nextValue = Number(event.target.value) as (typeof PAGE_SIZES)[number];
                  setPageSize(nextValue);
                  setPage(1);
                }}
                className="rounded-md border border-slate-300 bg-white px-2 py-1 text-sm"
              >
                {PAGE_SIZES.map((size) => (
                  <option key={size} value={size}>
                    {size}
                  </option>
                ))}
              </select>
            </div>

            <div className="flex items-center gap-2">
              <label htmlFor="session-page" className="text-slate-600">
                Page
              </label>
              <select
                id="session-page"
                value={page}
                onChange={(event) => {
                  setPage(Number(event.target.value));
                }}
                className="rounded-md border border-slate-300 bg-white px-2 py-1 text-sm"
              >
                {Array.from({ length: pageCount }).map((_, index) => {
                  const pageValue = index + 1;
                  return (
                    <option key={pageValue} value={pageValue}>
                      {pageValue}
                    </option>
                  );
                })}
              </select>
              <span className="text-slate-500">of {pageCount}</span>
            </div>
          </div>

          <div className="overflow-auto">
            <table className="min-w-full table-fixed text-sm">
              <thead>
                <tr className="border-b border-slate-200 text-left text-slate-600">
                  <th className="px-5 py-3 font-medium">Location</th>
                  <th className="px-5 py-3 font-medium">Created on</th>
                  <th className="px-5 py-3 font-medium">Expires on</th>
                  <th className="w-14 px-5 py-3 text-right font-medium" aria-label="Current session marker">
                    &nbsp;
                  </th>
                </tr>
              </thead>
              <tbody>
                {pagedRows.length > 0 ? (
                  pagedRows.map((session) => (
                    <tr key={session.id} className="border-b border-slate-100 last:border-b-0">
                      <td className="truncate px-5 py-3">{session.location}</td>
                      <td className="px-5 py-3">{renderCellValue(session.createdOn)}</td>
                      <td className="px-5 py-3 text-slate-600">{renderCellValue(session.expiresOn)}</td>
                      <td className="px-5 py-3 text-right text-lg leading-none text-slate-400">
                        {session.isCurrent ? <span title="Current session">•</span> : <span aria-hidden="true">↗</span>}
                      </td>
                    </tr>
                  ))
                ) : (
                  <tr>
                    <td colSpan={4} className="px-5 py-6 text-center text-slate-500">
                      No active sessions found.
                    </td>
                  </tr>
                )}
              </tbody>
            </table>
          </div>
        </div>

        <div className="flex justify-end">
          <button
            type="button"
            onClick={() => {
              void onSignOutAllDevices?.();
            }}
            disabled={!onSignOutAllDevices || signOutAllDevicesPending}
            className="rounded-full border border-slate-300 px-5 py-2 text-base text-slate-900 transition hover:bg-slate-50 disabled:cursor-not-allowed disabled:opacity-50"
          >
            {signOutAllDevicesPending ? "Signing out..." : "Sign out of all devices"}
          </button>
        </div>
      </section>
    </main>
  );
}
