import * as React from "react"
import {
  useNavigate,
  useLocation,
  useSearchParams as useRouterSearchParams,
  Link as RouterLink,
  type LinkProps as RouterLinkProps,
} from "react-router-dom"

/**
 * `next/*` → `react-router-dom` shim
 * ----------------------------------
 *
 * The template-vite stack uses react-router-dom for navigation, but the
 * porteable DS components keep Next-style import shapes so the codebase
 * stays one source of truth for components shared with `apps/web`
 * (which today still runs Next).
 *
 * Replace `import Link from "next/link"` with
 * `import { Link } from "@/lib/next-compat"`, and
 * `import { useRouter, ... } from "next/navigation"` with
 * `import { useRouter, ... } from "@/lib/next-compat"`.
 *
 * When `apps/web` finishes migrating to Vite (PR-3 → PR-6) and the Next
 * stack is removed entirely (PR-7), this shim is deleted and call sites
 * import directly from `react-router-dom`.
 */

// ---------------------------------------------------------------------------
// next/link
// ---------------------------------------------------------------------------

export type LinkProps = Omit<RouterLinkProps, "to"> & {
  href: string
  /** next/link prefetch — RR doesn't prefetch routes; no-op. */
  prefetch?: boolean
  /** next/link scroll — RR scrolls by default; no-op flag. */
  scroll?: boolean
}

export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
  function Link({ href, prefetch: _prefetch, scroll: _scroll, ...rest }, ref) {
    return <RouterLink ref={ref} to={href} {...rest} />
  },
)

// ---------------------------------------------------------------------------
// next/navigation
// ---------------------------------------------------------------------------

/**
 * Next-shape `useRouter`. The template only uses `push`, `replace`, `back`,
 * `forward`, `refresh`, and `prefetch` from the Next router — we map each
 * to the matching `useNavigate` / window primitives. `prefetch` is a no-op
 * because RR doesn't ship a route-prefetch primitive.
 */
export function useRouter() {
  const navigate = useNavigate()
  return React.useMemo(
    () => ({
      push: (href: string) => navigate(href),
      replace: (href: string) => navigate(href, { replace: true }),
      back: () => navigate(-1),
      forward: () => navigate(1),
      refresh: () => window.location.reload(),
      prefetch: (_href: string) => undefined,
    }),
    [navigate],
  )
}

export function usePathname(): string {
  return useLocation().pathname
}

/**
 * Next's `useSearchParams` returns `ReadonlyURLSearchParams`. RR's tuple
 * returns `[URLSearchParams, setSearchParams]`. We expose just the
 * params object — call sites that need to write delegate to `useRouter().push`.
 */
export function useSearchParams(): URLSearchParams {
  const [params] = useRouterSearchParams()
  return params
}

/**
 * Next's `redirect()` works in server components / actions — there's no
 * SPA equivalent. Where Next code did `redirect("/x")`, the Vite port
 * uses `<Navigate to="/x" replace />` JSX. This helper exists only so
 * any straggler imports compile; it throws so call sites are surfaced.
 */
export function redirect(href: string): never {
  throw new Error(
    `redirect("${href}") is server-only and unavailable in the Vite shim. ` +
      `Use <Navigate to="${href}" replace /> from react-router-dom in JSX, ` +
      `or useNavigate() inside a useEffect.`,
  )
}
