import { useEffect, useRef, useState } from 'react';
import { EmbedVideoIslandProps, EmbedVideoParams } from '../types.js';
import styles from './index.module.scss';

const CustomThumbnailPlayIcon = ({ fill }: { fill?: string }) => (
  <svg viewBox="0 0 135.39 149.4" fill={fill}>
    <path
      d="M371.2,398.69l-127.79,71c-1.47.83-2.74.93-3.8.28a3.69,3.69,0,0,1-1.59-3.46V324.88a3.73,3.73,0,0,1,1.59-3.47,3.66,3.66,0,0,1,3.8.29l127.79,71c1.47.84,2.21,1.82,2.21,3S372.67,397.85,371.2,398.69Z"
      transform="translate(-238.02 -321)"
    ></path>
  </svg>
);

const OEmbedContainer = ({
  embedVideoParams,
  oEmbedThumbnail,
  oEmbedPlayButtonColor,
}: {
  embedVideoParams: EmbedVideoParams;
  oEmbedThumbnail?: { src: string; alt?: string };
  oEmbedPlayButtonColor?: { color?: string };
}) => {
  const {
    oembed_url: oembedUrl,
    oembed_response: oembedResponse,
    supported_oembed_types: supportedOembedTypes,
  } = embedVideoParams;

  const [oembedData, setOembedData] =
    useState<EmbedVideoParams['oembed_response']>(oembedResponse);
  const [hasPlayed, setHasPlayed] = useState(false);
  const iframeWrapperRef = useRef<HTMLDivElement>(null);
  const iframeRef = useRef<HTMLIFrameElement | null>(null);

  const isSupportedOEmbedType = supportedOembedTypes.includes(
    oembedData?.type || ''
  );

  const playButtonFill = oEmbedPlayButtonColor?.color ?? '#ffffff';

  useEffect(() => {
    if (oembedData || !oembedUrl) {
      return;
    }

    const fetchOEmbed = async () => {
      try {
        const query = new URLSearchParams({
          url: oembedUrl,
          autoplay: '0',
        });
        const response = await fetch(`/_hcms/oembed?${query}`);
        if (!response.ok) {
          console.error('Server reached, error retrieving oEmbed response.');
          return;
        }
        setOembedData(await response.json());
      } catch {
        console.error(
          'Could not reach the server. Failed to retrieve oEmbed response.'
        );
      }
    };
    fetchOEmbed();
  }, [oembedUrl]);

  useEffect(() => {
    if (!oembedData) {
      return;
    }

    const el = document.createElement('div');
    el.innerHTML = oembedData.html;
    const iframe = el.firstChild as HTMLIFrameElement;
    iframe.setAttribute('class', styles['oembed_container_iframe']);
    iframe.setAttribute('title', oembedData.title || '');
    iframeRef.current = iframe;
    if (!oEmbedThumbnail?.src) {
      // if there is a custom thumbnail, iframe will be appended on click
      iframeWrapperRef.current?.appendChild(iframe);
    }
  }, [oembedData, oEmbedThumbnail?.src]);

  return (
    <div className={styles['oembed_container']}>
      {oEmbedThumbnail?.src && (
        <button
          className={styles['oembed_custom-thumbnail']}
          style={{
            backgroundImage: `url(${oEmbedThumbnail.src})`,
            display: hasPlayed ? 'none' : undefined,
          }}
          onClick={() => {
            const iframe = iframeRef.current;
            if (iframe) {
              const iframeSrc = new URL(iframe.src);
              iframeSrc.searchParams.append('autoplay', '1');
              iframe.src = iframeSrc.toString();
              iframeWrapperRef.current?.appendChild(iframe);
              setHasPlayed(true);
            }
          }}
        >
          <span className={styles['oembed-info']}>
            {[
              'Video player',
              oEmbedThumbnail.alt ?? '',
              'Click to play video',
            ].join(' - ')}
          </span>
          <div className={styles['oembed_custom-thumbnail_icon']}>
            <CustomThumbnailPlayIcon fill={playButtonFill} />
          </div>
        </button>
      )}
      {isSupportedOEmbedType && oembedData && (
        <div ref={iframeWrapperRef} className={styles.iframe_wrapper} />
      )}
    </div>
  );
};

const EmbedHTMLContainer = ({ embedHtml }: { embedHtml: string }) => {
  return (
    <div className={styles.embed_container}>
      <div
        className={styles.iframe_wrapper}
        dangerouslySetInnerHTML={{ __html: embedHtml }}
      />
    </div>
  );
};

const EmbedVideoIsland = ({
  embedVideoParams,
  oembedThumbnail,
  playButtonColor,
}: EmbedVideoIslandProps) => {
  if (
    embedVideoParams.source_type === 'oembed' &&
    embedVideoParams.oembed_url
  ) {
    return (
      <OEmbedContainer
        embedVideoParams={embedVideoParams}
        oEmbedThumbnail={oembedThumbnail}
        oEmbedPlayButtonColor={playButtonColor}
      />
    );
  }

  if (embedVideoParams.source_type === 'html' && embedVideoParams.embed_html) {
    return <EmbedHTMLContainer embedHtml={embedVideoParams.embed_html} />;
  }

  return null;
};

export default EmbedVideoIsland;
