import { useMemo } from 'react';

import { styled } from '@mui/system';

import { defaultAttributes } from './constants';
import {
  type HTMLAttributeValue,
  type HTMLBodyProps,
  type HTMLTags,
} from './types';

const Body = styled('div')(({ theme }) => ({
  fontFamily: 'Arial',
  lineHeight: '1.4',
  color: theme.palette.new.text.neutral.default,
  width: '100%',
  maxWidth: '100%',
  '& p': {
    display: 'block',
    width: '100%',
    wordWrap: 'break-word',
    margin: 'revert',
  },
  '& p:empty, & p:has(> br:only-child)': {
    minHeight: '1em',
  },
  '& p:empty::before, & p:has(> br:only-child)::before': {
    content: '"\\00a0"',
  },
  '& ul, li, ol': {
    padding: 'revert',
    overflowX: 'revert !important',
  },
  '& iframe, & video, & img': {
    maxWidth: '100% !important',
  },
  '& video, img': {
    height: 'auto !important',
  },
  '& img[style*="width:auto"], video[style*="width:auto"]': {
    width: 'revert-layer !important',
  },
  '[data-type="resizable-media"]': {
    maxWidth: '100% !important',
  },
  '[data-type="resizable-media"] img': {
    width: '100%',
    borderRadius: 8,
  },
  '[data-type="resizable-media"] iframe, [data-type="resizable-media"] video': {
    aspectRatio: '16 / 9',
    maxWidth: '100%',
    verticalAlign: 'middle',
    width: '100%',
    objectFit: 'contain',
    borderRadius: 8,
  },
  '& .variable-pill, & span[data-variable-token]': {
    display: 'inline-flex',
    alignItems: 'center',
    backgroundColor: theme.palette.new.background.elements.brand,
    color: theme.palette.new.text.neutral.brand,
    border: `1px solid ${theme.palette.new.border.neutral.brand}`,
    borderRadius: theme.shape.borderRadius,
    paddingLeft: 6,
    paddingRight: 6,
    paddingTop: 1,
    paddingBottom: 1,
    fontSize: '0.85em',
    fontFamily: 'inherit',
    lineHeight: 'inherit',
    whiteSpace: 'nowrap' as const,
  },
}));

const applyAttributesToElement = (
  element: Element,
  attributes: Record<string, HTMLAttributeValue>,
) => {
  Object.entries(attributes).forEach(([key, value]) => {
    if (typeof value === 'string' || typeof value === 'number') {
      element.setAttribute(key, String(value));
    } else if (typeof value === 'boolean' && value) {
      element.setAttribute(key, '');
    }
  });
};

export const HTMLBody = ({
  body,
  parserOptions = {},
  canDownloadVideo = false,
}: HTMLBodyProps) => {
  const processedHTML = useMemo(() => {
    const parser = new DOMParser();
    const content = parser.parseFromString(body, 'text/html');
    const allElements = content.querySelectorAll('*');

    allElements.forEach(element => {
      const tagName = element.tagName.toLowerCase();
      // Default anchor attributes
      if (defaultAttributes.a && tagName === 'a') {
        applyAttributesToElement(element, defaultAttributes.a);
      }

      // Block video downloads
      if (defaultAttributes.video && tagName === 'video' && !canDownloadVideo) {
        applyAttributesToElement(element, defaultAttributes.video);
      }

      // Custom parser options
      const customAttrs = parserOptions[tagName as HTMLTags];
      if (customAttrs) {
        applyAttributesToElement(element, customAttrs);
      }
    });

    return content.body.innerHTML;
  }, [body, parserOptions, canDownloadVideo]);

  return <Body dangerouslySetInnerHTML={{ __html: processedHTML }} />;
};

export default HTMLBody;
