"use client";

import type { AnchorHTMLAttributes, ButtonHTMLAttributes, DetailedHTMLProps, FC, ReactNode } from "react";
import React, { isValidElement } from "react";
import type { ButtonProps as AriaButtonProps } from "react-aria-components";
import { Button as AriaButton, Link as AriaLink } from "react-aria-components";
import { cx, sortCx } from '../../../utils/cx';
import { isReactComponent } from '../../../utils/is-react-component';

// Barelux theme: Rounded full buttons with elegant styling
export const styles = sortCx({
    common: {
        root: [
            "group relative inline-flex h-max cursor-pointer items-center justify-center whitespace-nowrap outline-none transition duration-100 ease-linear focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring",
            "disabled:cursor-not-allowed disabled:opacity-50",
            "*:data-icon:pointer-events-none *:data-icon:size-5 *:data-icon:shrink-0 *:data-icon:transition-inherit-all",
        ].join(" "),
        icon: "pointer-events-none size-5 shrink-0 transition-inherit-all",
    },
    sizes: {
        sm: {
            root: "gap-2 rounded-full px-6 py-2.5 text-sm font-medium uppercase tracking-wide",
        },
        md: {
            root: "gap-2 rounded-full px-8 py-3 text-base font-medium uppercase tracking-wide",
        },
        lg: {
            root: "gap-2 rounded-full px-10 py-3.5 text-lg font-medium uppercase tracking-wide",
        },
        xl: {
            root: "gap-2.5 rounded-full px-12 py-4 text-xl font-medium uppercase tracking-wide",
        },
    },

    colors: {
        primary: {
            root: "bg-brand-solid text-white hover:bg-brand-solid_hover transition-colors",
        },
        secondary: {
            root: "bg-secondary text-fg-primary hover:opacity-90 transition-all",
        },
        tertiary: {
            root: "text-fg-primary hover:underline",
        },
        "link-gray": {
            root: [
                "p-0! text-fg-primary",
                "*:data-text:underline *:data-text:underline-offset-4 hover:*:data-text:no-underline",
            ].join(" "),
        },
        "link-color": {
            root: [
                "p-0! text-fg-primary",
                "*:data-text:underline *:data-text:underline-offset-4 hover:*:data-text:no-underline",
            ].join(" "),
        },
    },
});

export interface CommonProps {
    isDisabled?: boolean;
    isLoading?: boolean;
    size?: keyof typeof styles.sizes;
    color?: keyof typeof styles.colors;
    iconLeading?: FC<{ className?: string }> | ReactNode;
    iconTrailing?: FC<{ className?: string }> | ReactNode;
    noTextPadding?: boolean;
    showTextWhileLoading?: boolean;
}

export interface ButtonProps extends CommonProps, DetailedHTMLProps<Omit<ButtonHTMLAttributes<HTMLButtonElement>, "color" | "slot">, HTMLButtonElement> {
    slot?: AriaButtonProps["slot"];
}

interface LinkProps extends CommonProps, DetailedHTMLProps<Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "color">, HTMLAnchorElement> {}

export type Props = ButtonProps | LinkProps;

export const Button = ({
    size = "sm",
    color = "primary",
    children,
    className,
    noTextPadding,
    iconLeading: IconLeading,
    iconTrailing: IconTrailing,
    isDisabled: disabled,
    isLoading: loading,
    showTextWhileLoading,
    ...otherProps
}: Props) => {
    const href = "href" in otherProps ? otherProps.href : undefined;
    const Component = href ? AriaLink : AriaButton;

    const isIcon = (IconLeading || IconTrailing) && !children;
    const isLinkType = ["link-gray", "link-color"].includes(color);

    noTextPadding = isLinkType || noTextPadding;

    let props = {};

    if (href) {
        props = {
            ...otherProps,
            href: disabled ? undefined : href,
            ...(disabled ? { "data-rac": true, "data-disabled": true } : {}),
        };
    } else {
        props = {
            ...otherProps,
            type: otherProps.type || "button",
            isPending: loading,
            isDisabled: disabled,
        };
    }

    return (
        <Component
            data-loading={loading ? true : undefined}
            data-icon-only={isIcon ? true : undefined}
            {...props}
            className={cx(
                styles.common.root,
                styles.sizes[size].root,
                styles.colors[color].root,
                (loading || (href && (disabled || loading))) && "pointer-events-none",
                loading && (showTextWhileLoading ? "[&>*:not([data-icon=loading]):not([data-text])]:hidden" : "[&>*:not([data-icon=loading])]:invisible"),
                className,
            )}
        >
            {/* Leading icon */}
            {isValidElement(IconLeading) && IconLeading}
            {isReactComponent(IconLeading) && React.createElement(IconLeading, { 'data-icon': 'leading', className: styles.common.icon } as Record<string, unknown>)}

            {loading && (
                <svg
                    fill="none"
                    data-icon="loading"
                    viewBox="0 0 20 20"
                    className={cx(styles.common.icon, !showTextWhileLoading && "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2")}
                >
                    {/* Background circle */}
                    <circle className="stroke-current opacity-30" cx="10" cy="10" r="8" fill="none" strokeWidth="2" />
                    {/* Spinning circle */}
                    <circle
                        className="origin-center animate-spin stroke-current"
                        cx="10"
                        cy="10"
                        r="8"
                        fill="none"
                        strokeWidth="2"
                        strokeDasharray="12.5 50"
                        strokeLinecap="round"
                    />
                </svg>
            )}

            {children && (
                <span data-text className={cx("transition-inherit-all", !noTextPadding && "px-0.5")}>
                    {children}
                </span>
            )}

            {/* Trailing icon */}
            {isValidElement(IconTrailing) && IconTrailing}
            {isReactComponent(IconTrailing) && React.createElement(IconTrailing, { 'data-icon': 'trailing', className: styles.common.icon } as Record<string, unknown>)}
        </Component>
    );
};

import { registerThemeVariant } from '../../../lib/component-registry';
registerThemeVariant('button', 'barelux', Button);
