'use client';

import * as React from 'react';

import { useTranslations } from 'next-intl';

import { ExternalLink } from 'lucide-react';

import { Link } from '@/i18n/navigation';

/* ============================================================================
   ROUTE LINK — the styleless routing ENGINE every link is built on.
   ----------------------------------------------------------------------------
   It owns exactly one concern: given an href, render the correct element and
   handle external/new-tab semantics. It applies NO typography or affordance.
     • internal  -> next-intl <Link> (locale-aware, prefetch)
     • external  -> <a target="_blank" rel="noopener noreferrer"> + ↗ + sr-only
     • protocol  -> <a> (mailto: / tel:)

   Build flavors ON TOP of this — never re-implement href detection at a call
   site. Consumers: AppLink (text), Button asChild (control), bare card links.
   ========================================================================== */

type IntlLinkProps = React.ComponentProps<typeof Link>;

export function isWebExternalHref(href: string) {
  return href.startsWith('http://') || href.startsWith('https://');
}

export function isProtocolHref(href: string) {
  return href.startsWith('mailto:') || href.startsWith('tel:');
}

export type RouteLinkProps = {
  href: IntlLinkProps['href'] | string;
  children: React.ReactNode;
  className?: string;
  /** Force the external <a> path. Auto-detected for absolute / protocol hrefs. */
  isExternal?: boolean;
  /** Open in a new tab. Defaults to true for web-external hrefs, false otherwise. */
  newTab?: boolean;
  /** Render the ↗ glyph on new-tab links. Default true. */
  showExternalIcon?: boolean;
  /** next-intl <Link> pass-throughs (kept explicit to avoid its generic href type) */
  prefetch?: boolean;
  replace?: boolean;
  scroll?: boolean;
  locale?: string;
} & Omit<
  React.AnchorHTMLAttributes<HTMLAnchorElement>,
  'href' | 'className' | 'children' | 'target' | 'rel'
>;

export function RouteLink({
  href,
  children,
  className,
  isExternal,
  newTab,
  showExternalIcon = true,
  ...props
}: RouteLinkProps) {
  const t = useTranslations('accessibility');

  const isStringHref = typeof href === 'string';
  const external =
    isStringHref && (isExternal === true || isWebExternalHref(href) || isProtocolHref(href));
  const openNewTab = newTab ?? (isStringHref && isWebExternalHref(href));

  if (external) {
    // strip next-intl-only props before they hit a raw <a>
    const anchorProps = Object.fromEntries(
      Object.entries(props).filter(
        ([key]) => !['prefetch', 'replace', 'scroll', 'locale'].includes(key)
      )
    ) as React.ComponentPropsWithoutRef<'a'>;

    return (
      <a
        href={href as string}
        target={openNewTab ? '_blank' : undefined}
        rel={openNewTab ? 'noopener noreferrer' : undefined}
        className={className}
        {...anchorProps}
      >
        {children}
        {openNewTab && showExternalIcon && (
          <ExternalLink aria-hidden="true" className="inline-block size-[0.85em] shrink-0" />
        )}
        {openNewTab && <span className="sr-only">{` (${t('openInNewTab')})`}</span>}
      </a>
    );
  }

  return (
    <Link href={href as IntlLinkProps['href']} className={className} {...props}>
      {children}
    </Link>
  );
}
