'use client';

import { useMemo } from 'react';
import { WidgetContentProps } from '../types/widget';
import clsx from 'clsx';
import { getResponsiveStyle, ResponsiveSize } from '../utils/styles';
import { ActionTooltip } from '@theme/components';

export function WidgetContent({
  widgetData,
  skipParentWrapper = false,
  onWidgetClick,
  selectedWidget,
  designMode,
  responsive,
  draggable,
  onDragStart,
  onDragOver,
  onDragLeave,
  onDrop
}: WidgetContentProps) {
  const componentId = Object.keys(widgetData.attributes)[0];
  const componentData = widgetData.attributes[componentId];
  const parentData = widgetData.parent;

  const combinedStyles = useMemo(
    () =>
      getResponsiveStyle(
        componentData?.style || {},
        responsive as ResponsiveSize
      ),
    [componentData?.style, responsive]
  );

  if (!componentData) return null;

  const parentStyles = parentData?.style
    ? Object.keys(parentData.style).reduce(
        (acc, breakpoint) => ({
          ...acc,
          ...parentData.style[breakpoint]
        }),
        {}
      )
    : {};

  const getClickableStyles = (isSelected: boolean) => {
    const baseComponentId = componentId.split('-')[0];
    const baseSelectedId = selectedWidget?.id?.split('-')[0];

    return clsx(
      designMode && [
        'cursor-pointer',
        (isSelected || baseComponentId === baseSelectedId) &&
          'outline outline-2 outline-[#3B82F6] outline-offset-2'
      ]
    );
  };

  const renderActionTooltip = () => {
    if (!designMode || !selectedWidget || selectedWidget.id !== componentId) {
      return null;
    }

    return (
      <ActionTooltip
        widgetData={widgetData}
        selectedWidget={selectedWidget}
        designMode={designMode}
        onDelete={() => {
          window.parent.postMessage(
            {
              type: 'WIDGET_DELETE',
              data: { id: componentId }
            },
            '*'
          );
        }}
        onMoveUp={() => {
          window.parent.postMessage(
            {
              type: 'WIDGET_MOVE',
              data: { id: componentId, direction: 'up' }
            },
            '*'
          );
        }}
        onMoveDown={() => {
          window.parent.postMessage(
            {
              type: 'WIDGET_MOVE',
              data: { id: componentId, direction: 'down' }
            },
            '*'
          );
        }}
        onCopy={() => {
          window.parent.postMessage(
            {
              type: 'WIDGET_COPY',
              data: { id: componentId }
            },
            '*'
          );
        }}
      />
    );
  };

  const wrapWithTooltip = (component: React.ReactNode) => {
    return (
      <div className="relative">
        {renderActionTooltip()}
        {component}
      </div>
    );
  };

  const renderComponent = () => {
    let iconSvg;
    let Tag;
    let CustomTag;

    const dragProps =
      designMode && draggable
        ? {
            draggable: true,
            onDragStart,
            onDragOver,
            onDragLeave,
            onDrop
          }
        : {};

    switch (componentData.type) {
      case 'text':
        Tag = (
          componentData.tag || 'div'
        ).toLowerCase() as keyof React.JSX.IntrinsicElements;
        return wrapWithTooltip(
          <Tag
            id={componentId}
            style={combinedStyles}
            onClick={onWidgetClick}
            className={getClickableStyles(selectedWidget?.id === componentId)}
            {...dragProps}
          >
            {componentData.value?.text}
          </Tag>
        );

      case 'image': {
        const {
          src,
          mobileSrc,
          tabletSrc,
          desktopSrc,
          alt = '',
          sizes,
          mediaQueries = {
            mobile: '(max-width: 767px)',
            tablet: '(min-width: 768px) and (max-width: 1023px)',
            desktop: '(min-width: 1024px)'
          }
        } = componentData.value || {};

        return wrapWithTooltip(
          <picture
            id={componentId}
            onClick={onWidgetClick}
            className={clsx(
              designMode && [
                'cursor-pointer relative',
                selectedWidget?.id === componentId
                  ? 'outline outline-2 outline-[#3B82F6] outline-offset-2'
                  : ''
              ]
            )}
            {...dragProps}
          >
            {mobileSrc && (
              <source
                media={mediaQueries.mobile}
                srcSet={mobileSrc}
                sizes={sizes?.mobile}
              />
            )}
            {tabletSrc && (
              <source
                media={mediaQueries.tablet}
                srcSet={tabletSrc}
                sizes={sizes?.tablet}
              />
            )}
            {desktopSrc && (
              <source
                media={mediaQueries.desktop}
                srcSet={desktopSrc}
                sizes={sizes?.desktop}
              />
            )}
            <img
              className={clsx(
                designMode && [
                  'cursor-pointer',
                  selectedWidget?.id === componentId
                    ? 'outline outline-2 outline-[#3B82F6] outline-offset-2'
                    : ''
                ]
              )}
              src={src || desktopSrc || tabletSrc || mobileSrc || ''}
              alt={alt}
              style={combinedStyles}
              loading="lazy"
            />
          </picture>
        );
      }

      case 'icon':
        iconSvg =
          componentData.value?.sizes?.[
            Object.keys(componentData.value.sizes || {})[0]
          ];
        if (!iconSvg) return null;
        return wrapWithTooltip(
          <div
            id={componentId}
            style={combinedStyles}
            onClick={onWidgetClick}
            className={clsx(
              'relative',
              designMode && [
                'cursor-pointer',
                selectedWidget?.id === componentId
                  ? 'outline outline-2 outline-[#3B82F6] outline-offset-2'
                  : ''
              ]
            )}
            dangerouslySetInnerHTML={{ __html: iconSvg }}
            {...dragProps}
          />
        );

      case 'link':
        return wrapWithTooltip(
          <a
            id={componentId}
            href={componentData.value?.href || '#'}
            target={componentData.value?.target}
            style={combinedStyles}
            onClick={onWidgetClick}
            className={clsx(
              'relative data-container',
              designMode && [
                'cursor-pointer',
                selectedWidget?.id === componentId
                  ? 'outline outline-2 outline-[#3B82F6] outline-offset-2'
                  : ''
              ]
            )}
            {...dragProps}
          >
            {componentData.value?.text || componentData.value?.title || 'Link'}
          </a>
        );

      case 'divider':
        return wrapWithTooltip(
          <hr
            id={componentId}
            style={combinedStyles}
            onClick={onWidgetClick}
            {...dragProps}
          />
        );

      default:
        if (componentData.tag) {
          CustomTag =
            componentData.tag.toLowerCase() as keyof React.JSX.IntrinsicElements;
          return wrapWithTooltip(
            <CustomTag
              id={componentId}
              style={combinedStyles}
              onClick={onWidgetClick}
              className={getClickableStyles(selectedWidget?.id === componentId)}
              {...dragProps}
            >
              {componentData.value?.text}
            </CustomTag>
          );
        }
        return wrapWithTooltip(
          <div
            id={componentId}
            style={combinedStyles}
            onClick={onWidgetClick}
            {...dragProps}
          >
            {componentData.value?.text}
          </div>
        );
    }
  };

  if (parentData && !skipParentWrapper) {
    const ParentTag = (
      parentData.tag || 'div'
    ).toLowerCase() as keyof React.JSX.IntrinsicElements;
    return (
      <ParentTag
        id={parentData.id}
        style={parentStyles}
        onClick={onWidgetClick}
      >
        {renderComponent()}
      </ParentTag>
    );
  }

  return renderComponent();
}
