import React, { forwardRef } from 'react';
import {
  Box,
  MarketingLayout,
  SkeletonLine,
  Card,
  Button,
  BadgeSkin,
  ButtonSkin,
  Image,
  Text,
  TextButton,
  Badge,
  SkeletonRectangle,
  ButtonPriority,
} from '@wix/design-system';
import { Offer } from '@wix/bex-utils/@wix/ambassador-dealer-v1-serving-offer/types';
import { BaseCardComponentProps, SuggestionsCardProps } from './types';
import { SuggestionCtaWrapper } from './SuggestionCtaWrapper';

/**
 * Schema for marketing card content.
 * This defines the structure expected in offer.asset.creative for MarketingCard rendering.
 */
export interface MarketingCardSchema {
  title: string;
  description: {
    text: string;
    learnMore?: {
      link: string;
      text?: string; // defaults to 'Learn more'
    };
  };
  imageUrl: string;
  ctaButton?: {
    text: string;
    link: string;
    skin?: Extract<ButtonSkin, 'standard' | 'premium' | 'ai'>; // defaults to 'standard'
    priority?: Extract<ButtonPriority, 'primary' | 'secondary'>; // defaults to 'secondary'
  };
  badge?: {
    text: string;
    skin?: Extract<BadgeSkin, 'general' | 'success' | 'premium'>; // defaults to 'general'
  };
}

const getCardWidth = (totalOffers: number) => {
  if (totalOffers === 1) {
    return '100%';
  }
  if (totalOffers === 2) {
    return '50%';
  }
  return '550px';
};

interface MarketingCardInternalProps {
  schema: MarketingCardSchema;
  totalOffers: number;
  offerId: string;
}

const MarketingCardInternal = forwardRef<
  HTMLDivElement,
  MarketingCardInternalProps
>(({ schema, totalOffers, offerId }, ref) => {
  const {
    title,
    description: descriptionData,
    imageUrl,
    ctaButton: ctaButtonData,
    badge: badgeData,
  } = schema;

  const handleCtaClick = () => {
    if (ctaButtonData?.link) {
      window.open(ctaButtonData.link, '_blank');
    }
  };

  const handleLearnMoreClick = () => {
    if (descriptionData?.learnMore?.link) {
      window.open(descriptionData.learnMore.link, '_blank');
    }
  };

  const description = (
    <>
      <Text size="small" secondary dataHook="suggestions-card-subtitle">
        {descriptionData.text}{' '}
      </Text>
      {descriptionData.learnMore && (
        <TextButton
          size="small"
          secondary
          dataHook="suggestions-card-learn-more"
          onClick={handleLearnMoreClick}
        >
          {descriptionData.learnMore.text ?? 'Learn more'}
        </TextButton>
      )}
    </>
  );

  const ctaButton = ctaButtonData ? (
    <SuggestionCtaWrapper offerId={offerId} referredUrl={ctaButtonData.link}>
      <Button
        size="small"
        skin={ctaButtonData.skin || 'standard'}
        priority={ctaButtonData.priority || 'secondary'}
        dataHook="suggestions-card-button"
        onClick={handleCtaClick}
      >
        {ctaButtonData.text}
      </Button>
    </SuggestionCtaWrapper>
  ) : null;

  const badge = badgeData ? (
    <Badge
      skin={badgeData.skin || 'general'}
      size="small"
      dataHook="suggestion-card-badge"
      uppercase={false}
    >
      {badgeData.text}
    </Badge>
  ) : null;

  const image = (
    <Image
      src={imageUrl}
      width={96}
      height={96}
      borderRadius="8px"
      dataHook="suggestions-card-image"
    />
  );

  return (
    <Box
      dataHook="suggestions-card"
      width={getCardWidth(totalOffers)}
      ref={ref}
    >
      <Card stretchVertically>
        <MarketingLayout
          title={title}
          description={description}
          image={image}
          actions={[ctaButton]}
          badge={badge}
          hiddenBadge={!badge}
        />
      </Card>
    </Box>
  );
});

/**
 * Creates a render function for marketing cards.
 * @param transformOffer - Optional function to transform offer data into MarketingCardSchema.
 *                         If not provided, uses offer.asset.creative directly.
 * @returns A render function compatible with Suggestions.renderCard prop.
 */
export const renderMarketingCard =
  (transformOffer?: (offer: Offer) => MarketingCardSchema | null) =>
  (props: SuggestionsCardProps): React.ReactElement | null => {
    const schema = transformOffer
      ? transformOffer(props.offer)
      : (props.offer?.asset?.creative as MarketingCardSchema | null);

    const requiredFieldsExist =
      schema?.title && schema?.imageUrl && schema?.description?.text;

    if (!requiredFieldsExist) {
      console.error(
        `Can't render MarketingCard for offer ${props.offer.offerGuid} - missing required fields (title, imageUrl, description.text) in schema:`,
        schema,
      );
      return null;
    }

    return (
      <MarketingCardInternal
        schema={schema}
        totalOffers={props.totalOffers}
        offerId={props.offer.offerGuid ?? ''}
      />
    );
  };

/**
 * Skeleton component for MarketingCard during loading state.
 */
export const MarketingCardSkeleton: React.FC<BaseCardComponentProps> = ({
  totalOffers,
}) => {
  return (
    <Box dataHook="suggestions-card" width={getCardWidth(totalOffers)}>
      <Card stretchVertically>
        <MarketingLayout
          title={<SkeletonLine width="120px" />}
          description={<SkeletonLine width="168px" />}
          actions={[<SkeletonRectangle width="72px" height="30px" />]}
          image={<SkeletonRectangle width="96px" height="96px" />}
          badge={<Badge />}
          hiddenBadge={true}
        />
      </Card>
    </Box>
  );
};
