'use client';

import React from 'react';
import { twMerge } from 'tailwind-merge';

import {
  TYPOGRAPHY_DISCOVER_CARD_SUBTITLE_CLASSNAME,
  TYPOGRAPHY_DISCOVER_CARD_TITLE_CLASSNAME,
} from '@/utils/constants';
import { PolymorphicComponent } from '@/utils/polymorphic';

export type Props = {
  metadataClassName?: string;
  titleClassName?: string;
  subtitleClassName?: string;
  contentClassName?: string;
  actionClassName?: string;
  /**
   * Metadata content displayed above title.
   *
   * Can be provided as literal JSX or a component that will receive
   * `metadataClassName` as the `className` prop.
   */
  metadata?: React.ReactNode | React.ComponentType<{ className?: string }>;
  /**
   * Title content
   *
   * If given as a string, will be wrapped in `<h2>`. Otherwise, can be
   * provided as literal JSX or a component that will receive `titleClassName`
   * as the `className` prop.
   */
  title?: React.ReactNode | React.ComponentType<{ className?: string }>;
  /**
   * Subtitle content
   *
   * If given as a string, will be wrapped in `<h3>`. Otherwise, can be
   * provided as literal JSX or a component that will receive
   * `subtitleClassName` as the `className` prop.
   */
  subtitle?: React.ReactNode | React.ComponentType<{ className?: string }>;
  /**
   * Additional content displayed under subtitle
   *
   * If given as a string, will be wrapped in `<div>`. Otherwise, can be
   * provided as literal JSX or a component that will receive
   * `contentClassName` as the `className` prop.
   */
  content?: React.ReactNode | React.ComponentType<{ className?: string }>;
  /**
   * Action content that can be rendered inline with the main content area
   */
  action?: React.ReactNode | React.ComponentType<{ className?: string }>;
  /**
   * Content rating tags
   */
  contentRatingTags?:
    | React.ReactNode
    | React.ComponentType<{ className?: string }>;
};

const DiscoverCardMeta: PolymorphicComponent<Props> = (props) => {
  const {
    as: Component = 'div',
    className,
    metadataClassName: explicitMetadataClassName,
    titleClassName: explicitTitleClassName,
    subtitleClassName: explicitSubtitleClassName,
    contentClassName: explicitContentClassName,
    actionClassName: explicitActionClassName,
    metadata,
    title,
    subtitle,
    content,
    action,
    contentRatingTags,
    children,
    ...restProps
  } = props;

  const metadataClassName = twMerge(
    TYPOGRAPHY_DISCOVER_CARD_SUBTITLE_CLASSNAME,
    'text-foreground-tertiary-glass max-w-max',
    explicitMetadataClassName
  );
  const titleClassName = twMerge(
    TYPOGRAPHY_DISCOVER_CARD_TITLE_CLASSNAME,
    'text-foreground-primary-glass max-w-max',
    explicitTitleClassName
  );
  const subtitleClassName = twMerge(
    TYPOGRAPHY_DISCOVER_CARD_SUBTITLE_CLASSNAME,
    'text-foreground-secondary-glass max-w-max',
    explicitSubtitleClassName
  );
  const contentClassName = twMerge('max-w-max', explicitContentClassName);
  const actionClassName = twMerge('shrink-0', explicitActionClassName);

  // When there's an action and no children, render MetadataContent & play button in a row layout
  const useRowLayout = action && !children;

  const MetadataContent = () => {
    return (
      <>
        {typeof metadata === 'function'
          ? React.createElement(metadata, { className: metadataClassName })
          : metadata}
        {typeof contentRatingTags === 'function'
          ? React.createElement(contentRatingTags, { className: 'max-w-max' })
          : contentRatingTags}
        {typeof title === 'string' ? (
          <h2 className={titleClassName}>{title}</h2>
        ) : typeof title === 'function' ? (
          React.createElement(title, { className: titleClassName })
        ) : (
          title
        )}
        {typeof subtitle === 'string' ? (
          <p className={subtitleClassName}>{subtitle}</p>
        ) : typeof subtitle === 'function' ? (
          React.createElement(subtitle, { className: subtitleClassName })
        ) : (
          subtitle
        )}
        {typeof content === 'string' ? (
          <div className={contentClassName}>{content}</div>
        ) : typeof content === 'function' ? (
          React.createElement(content, { className: contentClassName })
        ) : (
          content
        )}
      </>
    );
  };

  if (useRowLayout) {
    return (
      <Component
        className={twMerge(
          'relative flex flex-row items-end justify-between',
          className
        )}
        {...restProps}
      >
        <div className='flex flex-col gap-1'>
          <MetadataContent />
        </div>
        <div className={actionClassName}>
          {typeof action === 'function'
            ? React.createElement(action, { className: actionClassName })
            : action}
        </div>
      </Component>
    );
  }

  return (
    <Component
      className={twMerge('relative flex flex-col gap-1', className)}
      {...restProps}
    >
      <MetadataContent />
      {children}
    </Component>
  );
};

export default DiscoverCardMeta;
