---
import { z } from 'astro/zod'
import { Icon } from 'astro-icon/components'

import { networksBySlug } from '../constants/networks'
import { cn } from '../lib/cn'

import type { HTMLAttributes } from 'astro/types'

type Props = Omit<HTMLAttributes<'a'>, 'href' | 'rel' | 'target'> & {
  url: string
  referral: string | null
  enableMinWidth?: boolean
}

const { url: baseUrl, referral, class: className, enableMinWidth = false, ...htmlProps } = Astro.props

function makeLink(url: string, referral: string | null) {
  const hostname = new URL(url).hostname
  const urlWithReferral = url + (referral ?? '')

  const onionMatch = /^(?:https?:\/\/)?(.{0,10}).*?(.{0,10})(\.onion)$/.exec(hostname)
  if (onionMatch) {
    return {
      type: 'onion' as const,
      url: urlWithReferral,
      textBits: onionMatch.length
        ? [
            {
              style: 'normal' as const,
              text: onionMatch[1] ?? '',
            },
            {
              style: 'irrelevant' as const,
              text: '...',
            },
            {
              style: 'normal' as const,
              text: onionMatch[2] ?? '',
            },
            {
              style: 'irrelevant' as const,
              text: onionMatch[3] ?? '',
            },
          ]
        : [
            {
              style: 'normal' as const,
              text: hostname,
            },
          ],
      icon: networksBySlug.onion.icon,
    }
  }

  const i2pMatch = /^(?:https?:\/\/)?(.{0,10}).*?(.{0,8})((?:\.b32)?\.i2p)$/.exec(hostname)
  if (i2pMatch) {
    return {
      type: 'i2p' as const,
      url: urlWithReferral,
      textBits: i2pMatch.length
        ? [
            {
              style: 'normal' as const,
              text: i2pMatch[1] ?? '',
            },
            {
              style: 'irrelevant' as const,
              text: '...',
            },
            {
              style: 'normal' as const,
              text: i2pMatch[2] ?? '',
            },
            {
              style: 'irrelevant' as const,
              text: i2pMatch[3] ?? '',
            },
          ]
        : [
            {
              style: 'normal' as const,
              text: hostname,
            },
          ],
      icon: networksBySlug.i2p.icon,
    }
  }

  const bitcointalkMatch = /^(?:https?:\/\/)?(?:www\.)?bitcointalk\.org$/.exec(hostname)
  if (bitcointalkMatch) {
    return {
      type: 'clearnet' as const,
      url: urlWithReferral,
      textBits: [
        {
          style: 'normal',
          text: 'BitcoinTalk ',
        },
        {
          style: 'irrelevant',
          text: 'thread',
        },
      ],
      icon: networksBySlug.clearnet.icon,
    }
  }

  return {
    type: 'clearnet' as const,
    url: urlWithReferral,
    textBits: [
      {
        style: 'normal' as const,
        text: hostname.replace(/^www\./, ''),
      },
    ],
    icon: networksBySlug.clearnet.icon,
  }
}

const link = makeLink(baseUrl, referral)

if (!z.string().url().safeParse(link.url).success) {
  console.error(`Invalid service URL with referral: ${link.url}`)
}
---

<a
  href={link.url}
  target="_blank"
  rel="noopener noreferrer"
  class={cn(
    '2xs:text-sm 2xs:h-8 2xs:gap-2 focus-visible:ring-offset-night-700 inline-flex h-6 items-center gap-1 rounded-full bg-white text-xs whitespace-nowrap text-black focus-visible:ring-4 focus-visible:ring-orange-500 focus-visible:ring-offset-2 focus-visible:outline-none',
    className
  )}
  {...htmlProps}
>
  <Icon name={link.icon} class="2xs:ml-2 2xs:size-5 2xs:-mr-0.5 -mr-0.25 ml-1 size-4" />
  <span class={cn('font-title font-bold', { 'min-w-[29ch]': enableMinWidth })}>
    {
      link.textBits.map((textBit) => (
        <span class={cn(textBit.style === 'irrelevant' && 'text-zinc-500')}>{textBit.text}</span>
      ))
    }
  </span>
  <Icon
    name="ri:arrow-right-line"
    class="2xs:size-6 mr-1 size-4 rounded-full bg-orange-500 p-0.5 text-white"
  />
</a>
