---
import type { HTMLAttributes } from 'astro/types';
import { cn } from '@/lib/cn';
import { isExternalUrl } from '@/lib/utils';
import { buttonVariants } from './button.variants';
import Icon from '@/components/ui/primitives/Icon/Icon.astro';

interface Props extends HTMLAttributes<'button'> {
  variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'link' | 'destructive';
  size?: 'sm' | 'md' | 'lg';
  loading?: boolean;
  fullWidth?: boolean;
  href?: string;
  target?: string;
  rel?: string;
  icon?: boolean;
}

const {
  variant = 'primary',
  size = 'md',
  loading = false,
  fullWidth = false,
  href,
  target,
  icon = false,
  class: className,
  disabled,
  ...attrs
} = Astro.props;

// Auto-detect external URLs and apply appropriate attributes
const isExternal = href ? isExternalUrl(href) : false;
const linkTarget = target ?? (isExternal ? '_blank' : undefined);
const linkRel = isExternal ? 'noopener noreferrer' : undefined;

const Element = href ? 'a' : 'button';
const isDisabled = disabled || loading;
const isDisabledLink = href && isDisabled;

const classes = cn(
  buttonVariants({ variant, size, fullWidth, icon }),
  isDisabledLink && 'pointer-events-none',
  className
);
---

<Element
  class={classes}
  disabled={!href ? isDisabled : undefined}
  href={isDisabledLink ? undefined : href}
  target={isDisabledLink ? undefined : linkTarget}
  rel={isDisabledLink ? undefined : linkRel}
  aria-disabled={isDisabledLink ? 'true' : undefined}
  tabindex={isDisabledLink ? '-1' : undefined}
  {...attrs}
>
  {
    loading ? <Icon name="loader" size="sm" class="animate-spin" /> : null
  }
  <slot />
</Element>

<style is:global>
  /*
   * Dark mode: soften the flat near-white primary button background with a
   * subtle top-to-bottom gradient — same principle as the hero H1 gradient.
   * color-mix blends 55% foreground + 45% foreground-secondary so the bottom
   * of the button is slightly dimmer and brand-tinted without looking grey.
   * Hover clears the gradient image so the Tailwind bg-foreground/90 takes over.
   */
  .dark .btn-primary {
    border: 1px solid var(--color-foreground-secondary);
    background-image: linear-gradient(
      180deg,
      var(--color-foreground) 0%,
      color-mix(in oklch, var(--color-foreground) 55%, var(--color-foreground-secondary)) 100%
    );
  }

  .dark .btn-primary:hover {
    background-image: none;
  }
</style>
