import { forwardRef, type ReactNode } from 'react';
import { Platform, Text, View, type TextProps } from 'react-native';
import {
  LinkRoot as LinkRootPrimitive,
  Slot,
  dataAttributes,
  mergeDataAttributes,
  useLinkInteractionContext,
  type ILinkProps,
} from '@cdx-ui/primitives';
import { cn } from '@cdx-ui/utils';
import { Icon, type IconProps } from '../Icon';
import {
  linkIconVariants,
  linkLabelVariants,
  linkNativeUnderlineVariants,
  linkRootVariants,
} from './styles';

export { LinkProvider, type LinkConfig, type LinkAction } from '@cdx-ui/primitives';

// =============================================================================
// STYLED ROOT COMPONENT
// =============================================================================

export interface LinkProps extends ILinkProps {
  asChild?: boolean;
  className?: string;
  children?: ReactNode;
}

const LinkRoot = forwardRef<View, LinkProps>(({ className, children, style, ...props }, ref) => {
  const rootClassName = cn(linkRootVariants(), className);

  return (
    <LinkRootPrimitive
      ref={ref}
      className={rootClassName}
      style={style}
      {...props}
      {...mergeDataAttributes(props, dataAttributes({ slot: 'link' }))}
    >
      {children}
    </LinkRootPrimitive>
  );
});

LinkRoot.displayName = 'Link';

// =============================================================================
// STYLED LABEL COMPONENT
// =============================================================================

export interface LinkLabelProps extends TextProps {
  asChild?: boolean;
  className?: string;
  children?: ReactNode;
}

const LinkLabel = forwardRef<Text, LinkLabelProps>(
  ({ asChild, className, children, style, ...props }, ref) => {
    const { visited } = useLinkInteractionContext();
    const computedClassName = cn(linkLabelVariants({ visited }), className);
    const Comp = asChild ? Slot : Text;

    const textElement = (
      <Comp
        ref={ref}
        className={computedClassName}
        style={style}
        {...props}
        {...mergeDataAttributes(props, dataAttributes({ slot: 'link-label' }))}
      >
        {children}
      </Comp>
    );

    if (Platform.OS === 'web') {
      return textElement;
    }

    return <View className={cn(linkNativeUnderlineVariants({ visited }))}>{textElement}</View>;
  },
);

LinkLabel.displayName = 'Link.Label';

// =============================================================================
// STYLED ICON COMPONENT
// =============================================================================

export interface LinkIconProps extends Omit<IconProps, 'children'> {}

const LinkIcon = ({ className, style, as, ...props }: LinkIconProps) => {
  const { visited } = useLinkInteractionContext();
  const computedClassName = cn(linkIconVariants({ visited }), className);

  return (
    <Icon
      as={as}
      className={computedClassName}
      style={style}
      {...props}
      {...mergeDataAttributes(props, dataAttributes({ slot: 'link-icon' }))}
    />
  );
};

LinkIcon.displayName = 'Link.Icon';

// =============================================================================
// COMPOUND COMPONENT EXPORT
// =============================================================================

type LinkCompoundComponent = typeof LinkRoot & {
  Label: typeof LinkLabel;
  Icon: typeof LinkIcon;
};

export const Link = Object.assign(LinkRoot, {
  Label: LinkLabel,
  Icon: LinkIcon,
}) as LinkCompoundComponent;
