import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"

import { cn } from "@/lib/utils"

type SocialPlatform =
  | "apple"
  | "facebook"
  | "google"
  | "linkedin"
  | "twitter"
  | "whatsapp"

type SocialButtonVariant = "solid" | "outline"
type SocialButtonSize = "default" | "icon"

type SocialPlatformConfig = {
  label: string
  labelAr: string
  solidBg: string
  solidHover: string
  solidBorder: string
  solidIconBorder?: string
  solidFg: string
  solidIcon: string
  outlineIcon: string
  width: {
    ltr: string
    rtl: string
  }
}

const socialPlatformConfig: Record<SocialPlatform, SocialPlatformConfig> = {
  apple: {
    label: "Sign in with Apple",
    labelAr: "تسجيل الدخول باستخدام آبل",
    solidBg: "var(--bh-social-apple-bg)",
    solidHover: "var(--bh-social-apple-hover)",
    solidBorder: "var(--bh-social-apple-border)",
    solidIconBorder: "var(--bh-social-apple-icon-border)",
    solidFg: "var(--bh-social-apple-fg)",
    solidIcon: "var(--bh-social-apple-icon)",
    outlineIcon: "var(--bh-social-apple-outline-icon)",
    width: { ltr: "var(--bh-social-apple-width)", rtl: "var(--bh-social-apple-width-rtl)" },
  },
  facebook: {
    label: "Sign in with Facebook",
    labelAr: "تسجيل الدخول باستخدام فيسبوك",
    solidBg: "var(--bh-social-facebook-bg)",
    solidHover: "var(--bh-social-facebook-hover)",
    solidBorder: "transparent",
    solidFg: "var(--bh-social-facebook-fg)",
    solidIcon: "var(--bh-social-facebook-icon)",
    outlineIcon: "var(--bh-social-facebook-outline-icon)",
    width: { ltr: "var(--bh-social-facebook-width)", rtl: "var(--bh-social-facebook-width-rtl)" },
  },
  google: {
    label: "Sign in with Google",
    labelAr: "تسجيل الدخول باستخدام جوجل",
    solidBg: "var(--bh-social-google-bg)",
    solidHover: "var(--bh-social-google-hover)",
    solidBorder: "var(--bh-social-google-border)",
    solidFg: "var(--bh-social-google-fg)",
    solidIcon: "currentColor",
    outlineIcon: "currentColor",
    width: { ltr: "var(--bh-social-google-width)", rtl: "var(--bh-social-google-width-rtl)" },
  },
  linkedin: {
    label: "Sign in with LinkedIn",
    labelAr: "تسجيل الدخول باستخدام لينكد إن",
    solidBg: "var(--bh-social-linkedin-bg)",
    solidHover: "var(--bh-social-linkedin-hover)",
    solidBorder: "transparent",
    solidFg: "var(--bh-social-linkedin-fg)",
    solidIcon: "var(--bh-social-linkedin-icon)",
    outlineIcon: "var(--bh-social-linkedin-outline-icon)",
    width: { ltr: "var(--bh-social-linkedin-width)", rtl: "var(--bh-social-linkedin-width-rtl)" },
  },
  twitter: {
    label: "Sign in with Twitter",
    labelAr: "تسجيل الدخول باستخدام تويتر",
    solidBg: "var(--bh-social-twitter-bg)",
    solidHover: "var(--bh-social-twitter-hover)",
    solidBorder: "var(--bh-social-twitter-border)",
    solidIconBorder: "var(--bh-social-twitter-icon-border)",
    solidFg: "var(--bh-social-twitter-fg)",
    solidIcon: "var(--bh-social-twitter-icon)",
    outlineIcon: "var(--bh-social-twitter-outline-icon)",
    width: { ltr: "var(--bh-social-twitter-width)", rtl: "var(--bh-social-twitter-width-rtl)" },
  },
  whatsapp: {
    label: "Sign in with WhatsApp",
    labelAr: "تسجيل الدخول باستخدام واتساب",
    solidBg: "var(--bh-social-whatsapp-bg)",
    solidHover: "var(--bh-social-whatsapp-hover)",
    solidBorder: "transparent",
    solidFg: "var(--bh-social-whatsapp-fg)",
    solidIcon: "var(--bh-social-whatsapp-icon)",
    outlineIcon: "var(--bh-social-whatsapp-outline-icon)",
    width: { ltr: "var(--bh-social-whatsapp-width)", rtl: "var(--bh-social-whatsapp-width-rtl)" },
  },
}

const socialButtonVariants = cva(
  "group/social-button relative inline-flex items-center justify-center whitespace-nowrap rounded-[var(--bh-social-button-radius)] bg-[var(--bh-social-button-bg)] text-[var(--bh-social-button-fg)] shadow-[var(--shadow-social-button)] outline-none transition-[background-color,box-shadow,color] [--bh-social-button-current-border:var(--bh-social-button-border)] [--shadow-social-button:inset_0px_0px_0px_var(--bh-border-width-default)_var(--bh-social-button-current-border,var(--bh-social-button-border,transparent)),var(--shadow-component-default)] rtl:[--bh-social-button-width:var(--bh-social-button-width-rtl)] hover:bg-[var(--bh-social-button-bg-hover)] focus-visible:[--bh-social-button-current-border:var(--bh-social-button-focus-border)] focus-visible:shadow-[var(--shadow-social-button-focus)] disabled:pointer-events-none disabled:opacity-[var(--bh-opacity-50)] [&_svg]:pointer-events-none [&_svg]:shrink-0",
  {
    variants: {
      variant: {
        solid: "",
        outline: "",
      },
      size: {
        default:
          "h-[var(--bh-social-button-height)] w-[var(--bh-social-button-width)] gap-[var(--bh-social-button-gap)] px-[var(--bh-social-button-padding-x)] py-[var(--bh-social-button-padding-y)] text-[length:var(--bh-text-button-font-size)] font-[var(--bh-text-button-font-weight)] leading-[var(--bh-text-button-line-height)] tracking-[var(--bh-text-button-letter-spacing)]",
        icon: "size-[var(--bh-social-button-height)] p-0",
      },
    },
    defaultVariants: {
      variant: "solid",
      size: "default",
    },
  }
)

type SocialButtonProps = Omit<React.ComponentProps<"button">, "children"> &
  VariantProps<typeof socialButtonVariants> & {
    platform: SocialPlatform
    asChild?: boolean
    children?: React.ReactNode
    label?: string
  }

const SocialButton = React.forwardRef<HTMLButtonElement, SocialButtonProps>(function SocialButton({
  className,
  platform,
  variant = "solid",
  size = "default",
  label,
  asChild = false,
  children,
  dir,
  style,
  type,
  "aria-label": ariaLabel,
  ...props
}, ref) {
  const config = socialPlatformConfig[platform]
  const selectedVariant = variant || "solid"
  const selectedSize = size || "default"
  const isIcon = selectedSize === "icon"
  const defaultLabel = getDefaultLabel(config, dir)
  const visibleLabel = label || (isSimpleLabel(children) ? children : defaultLabel)
  const accessibleLabel =
    typeof visibleLabel === "string" || typeof visibleLabel === "number"
      ? String(visibleLabel)
      : defaultLabel
  const Comp = asChild ? Slot : "button"
  const cssVars = getSocialButtonVars(config, selectedVariant, isIcon)
  const content = (
    <>
      <SocialButtonIcon platform={platform} variant={selectedVariant} />
      {!isIcon && (
        <span
          data-slot="social-button-label"
          dir="auto"
          className="min-w-0 pe-[var(--bh-social-button-label-padding-inline-end)]"
        >
          {visibleLabel}
        </span>
      )}
    </>
  )
  const slottedChildren =
    asChild && React.isValidElement(children)
      ? React.cloneElement(children, undefined, content)
      : content

  return (
    <Comp
      aria-label={isIcon ? ariaLabel || accessibleLabel : ariaLabel}
      data-platform={platform}
      data-size={selectedSize}
      data-slot="social-button"
      data-variant={selectedVariant}
      dir={dir}
      ref={ref}
      className={cn(
        socialButtonVariants({
          variant: selectedVariant,
          size: selectedSize,
          className,
        })
      )}
      style={{ ...cssVars, ...style }}
      {...(!asChild ? { type: type || "button" } : {})}
      {...props}
    >
      {slottedChildren}
    </Comp>
  )
})

function isSimpleLabel(
  value: React.ReactNode
): value is string | number {
  return typeof value === "string" || typeof value === "number"
}

function getDefaultLabel(
  config: SocialPlatformConfig,
  dir: React.HTMLAttributes<HTMLElement>["dir"]
) {
  return dir === "rtl" ? config.labelAr : config.label
}

function getSocialButtonVars(
  config: SocialPlatformConfig,
  variant: SocialButtonVariant,
  isIcon: boolean
) {
  const isSolid = variant === "solid"
  const border = isSolid
    ? isIcon
      ? config.solidIconBorder || config.solidBorder
      : config.solidBorder
    : "var(--bh-border-default)"

  return {
    "--bh-social-button-bg": isSolid ? config.solidBg : "var(--bh-bg-raised)",
    "--bh-social-button-bg-hover": isSolid
      ? config.solidHover
      : "var(--bh-bg-raised-hover)",
    "--bh-social-button-border": border,
    "--bh-social-button-focus-border": isSolid
      ? border
      : "var(--bh-border-focus)",
    "--bh-social-button-fg": isSolid
      ? config.solidFg
      : "var(--bh-content-default)",
    "--bh-social-button-icon": isSolid ? config.solidIcon : config.outlineIcon,
    "--bh-social-button-width": isIcon
      ? "var(--bh-social-button-height)"
      : config.width.ltr,
    "--bh-social-button-width-rtl": isIcon
      ? "var(--bh-social-button-height)"
      : config.width.rtl,
  } as React.CSSProperties
}

function SocialButtonIcon({
  platform,
  variant,
}: {
  platform: SocialPlatform
  variant: SocialButtonVariant
}) {
  const color =
    platform === "google" ? undefined : "var(--bh-social-button-icon)"

  return (
    <svg
      aria-hidden="true"
      className="size-[var(--bh-social-button-icon-size)]"
      data-slot="social-button-icon"
      fill="none"
      focusable="false"
      viewBox="0 0 18 18"
    >
      {platform === "apple" && <AppleIcon color={color} />}
      {platform === "facebook" && <FacebookIcon color={color} />}
      {platform === "google" && <GoogleIcon />}
      {platform === "linkedin" && <LinkedInIcon color={color} />}
      {platform === "twitter" && <TwitterIcon color={color} />}
      {platform === "whatsapp" && <WhatsAppIcon color={color} />}
    </svg>
  )
}

function AppleIcon({ color }: { color?: string }) {
  return (
    <path
      d="M13.54 9.55c-.02-1.86 1.52-2.75 1.59-2.79-.87-1.27-2.22-1.44-2.7-1.46-1.15-.12-2.24.68-2.82.68-.59 0-1.49-.66-2.45-.64-1.26.02-2.42.73-3.07 1.86-1.31 2.27-.34 5.63.94 7.47.62.9 1.37 1.91 2.35 1.87.94-.04 1.3-.61 2.44-.61 1.13 0 1.46.61 2.45.59 1.01-.02 1.66-.92 2.28-1.82.72-1.05 1.02-2.07 1.03-2.12-.02-.01-1.99-.76-2.03-3.03ZM11.68 4.1c.52-.63.87-1.5.77-2.37-.74.03-1.64.49-2.17 1.12-.48.55-.9 1.44-.79 2.29.83.06 1.67-.42 2.19-1.04Z"
      fill={color}
    />
  )
}

function FacebookIcon({ color }: { color?: string }) {
  return (
    <path
      d="M18 9A9 9 0 1 0 7.59 17.9v-6.3H5.3V9h2.29V6.98c0-2.27 1.35-3.52 3.42-3.52.99 0 2.02.18 2.02.18v2.22h-1.14c-1.12 0-1.47.7-1.47 1.41V9h2.51l-.4 2.6h-2.11v6.3A9 9 0 0 0 18 9Z"
      fill={color}
    />
  )
}

function GoogleIcon() {
  return (
    <>
      <path
        d="M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.88 2.68-6.62Z"
        fill="var(--bh-social-google-blue)"
      />
      <path
        d="M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.8.54-1.84.86-3.04.86-2.35 0-4.34-1.59-5.05-3.72H.93v2.33A9 9 0 0 0 9 18Z"
        fill="var(--bh-social-google-green)"
      />
      <path
        d="M3.95 10.7A5.41 5.41 0 0 1 3.66 9c0-.59.1-1.16.29-1.7V4.97H.93A9 9 0 0 0 0 9c0 1.45.34 2.82.93 4.03l3.02-2.33Z"
        fill="var(--bh-social-google-yellow)"
      />
      <path
        d="M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.58C13.47.9 11.43 0 9 0A9 9 0 0 0 .93 4.97L3.95 7.3C4.66 5.17 6.65 3.58 9 3.58Z"
        fill="var(--bh-social-google-red)"
      />
    </>
  )
}

function LinkedInIcon({ color }: { color?: string }) {
  return (
    <>
      <path
        d="M3.23 7.2h2.43V15H3.23V7.2Zm1.22-3.88a1.41 1.41 0 1 1 0 2.82 1.41 1.41 0 0 1 0-2.82Z"
        fill={color}
      />
      <path
        d="M7.18 7.2h2.33v1.07h.03c.32-.61 1.12-1.26 2.3-1.26 2.47 0 2.93 1.63 2.93 3.74V15h-2.43v-3.77c0-.9-.02-2.06-1.26-2.06-1.26 0-1.45.98-1.45 1.99V15H7.18V7.2Z"
        fill={color}
      />
    </>
  )
}

function TwitterIcon({ color }: { color?: string }) {
  return (
    <path
      d="M10.65 7.72 16.16 1.5h-1.31l-4.78 5.4-3.82-5.4H1.83l5.78 8.17-5.78 6.83h1.31l5.05-5.97 4.04 5.97h4.42l-6-8.78Zm-1.79 2.08-.58-.82-4.66-6.4h1.72l3.76 5.17.58.82 4.89 6.72h-1.72L8.86 9.8Z"
      fill={color}
    />
  )
}

function WhatsAppIcon({ color }: { color?: string }) {
  return (
    <path
      d="M9.03 1.5A7.42 7.42 0 0 0 2.6 12.62L1.5 16.5l3.98-1.05A7.43 7.43 0 1 0 9.03 1.5Zm0 13.56c-1.22 0-2.35-.36-3.3-.98l-.24-.15-2.36.62.63-2.3-.16-.24a6.1 6.1 0 1 1 5.43 3.05Zm3.34-4.57c-.18-.09-1.08-.53-1.25-.59-.17-.06-.29-.09-.42.09-.12.18-.48.59-.59.71-.11.12-.22.13-.4.04-.18-.09-.77-.28-1.47-.9-.54-.48-.91-1.08-1.02-1.26-.11-.18-.01-.28.08-.37.08-.08.18-.22.27-.33.09-.11.12-.18.18-.3.06-.12.03-.23-.01-.33-.05-.09-.42-1-.57-1.37-.15-.36-.3-.31-.42-.32h-.36c-.12 0-.33.05-.5.23-.17.18-.65.64-.65 1.56 0 .92.67 1.81.76 1.94.09.12 1.32 2.02 3.2 2.83.45.19.8.31 1.07.4.45.14.86.12 1.18.07.36-.05 1.08-.44 1.23-.86.15-.42.15-.79.11-.86-.05-.08-.17-.13-.35-.22Z"
      fill={color}
    />
  )
}

export { SocialButton, socialButtonVariants, socialPlatformConfig }
export type {
  SocialButtonProps,
  SocialButtonSize,
  SocialButtonVariant,
  SocialPlatform,
}
