'use client';

import { useLocalization } from '@akinon/next/hooks';
import { LocaleUrlStrategy } from '@akinon/next/localization';
import { urlLocaleMatcherRegex, urlSchemes } from '@akinon/next/utils';
import NextLink, { LinkProps as NextLinkProps } from 'next/link';
import { useMemo } from 'react';

type LinkProps = Omit<
  React.AnchorHTMLAttributes<HTMLAnchorElement>,
  keyof NextLinkProps
> &
  NextLinkProps;

export const Link = ({ children, href, ...rest }: LinkProps) => {
  const { locale, defaultLocaleValue, localeUrlStrategy } = useLocalization();
  const formattedHref = useMemo(() => {
    if (!href) {
      return '#';
    }

    if (typeof href === 'string') {
      const trimmedHref = href.trim();
      if (!trimmedHref) {
        return '#';
      }

      if (urlSchemes.some((scheme) => trimmedHref.startsWith(scheme))) {
        if (
          trimmedHref.startsWith('mailto:') ||
          trimmedHref.startsWith('tel:')
        ) {
          return trimmedHref;
        }

        try {
          new URL(trimmedHref);
          return trimmedHref;
        } catch {
          return '#';
        }
      }

      try {
        new URL(trimmedHref, 'http://localhost');
      } catch {
        return '#';
      }

      const pathnameWithoutLocale = trimmedHref.replace(
        urlLocaleMatcherRegex,
        ''
      );
      const hrefWithLocale = `/${locale}${pathnameWithoutLocale}`;

      if (localeUrlStrategy === LocaleUrlStrategy.ShowAllLocales) {
        return hrefWithLocale;
      } else if (
        localeUrlStrategy === LocaleUrlStrategy.HideDefaultLocale &&
        locale !== defaultLocaleValue
      ) {
        return hrefWithLocale;
      }

      return trimmedHref || '#';
    }

    if (typeof href !== 'string') {
      return href;
    }
    return '#';
  }, [href, defaultLocaleValue, locale, localeUrlStrategy]);

  return (
    <NextLink href={formattedHref} {...rest}>
      {children}
    </NextLink>
  );
};
