import React from "react";

import getImageUrl, { Image as ImageType } from "../../utils/getImageUrl";
import { Image } from "../Image";
import { Link } from "../Link";
import { Text } from "../Text";
import { VideoEmbed } from "../VideoEmbed";
import { View } from "../View";
import DescriptionListNode from "./DescriptionListNode";
import ListNode from "./ListNode";
import TextNode, { withText } from "./TextNode";
import { BlockSpec } from "./index";
import mapTree from "./mapTree";

/* eslint-disable camelcase */
const typeMap = {
  blockquote: ({ children }) => <Text as="blockquote">{children}</Text>,
  heading: ({ node }) => (
    <Text
      h1={!node.attrs || node.attrs?.level === 1}
      h2={node.attrs?.level === 2}
      h3={node.attrs?.level === 3}
    >
      {node.text}
    </Text>
  ),
  paragraph: ({ children }) => <Text as="p">{children}</Text>,
  image: ({ node }) => {
    const imageSource = node.image
      ? getImageUrl({ file: node.image } as ImageType)
      : getImageUrl(node);
    const imageMeta = node.image
      ? node.image?.attributes?.meta
      : node.file?.attributes?.meta;

    return (
      <Image
        source={imageSource}
        style={{
          width: imageMeta?.width,
          height: imageMeta?.height,
        }}
      />
    );
  },
  hard_break: View,
  bullet_list: (props) => <ListNode type="bullet" {...props} />,
  ordered_list: (props) => <ListNode type="ordered" {...props} />,
  description_list: (props) => <DescriptionListNode {...props} />,
  description_item: ({ children }) => children,
  list_item: ({ children }) => children,
  // code_block: "code",
  text: TextNode,
  video: ({ node }) => (
    <VideoEmbed aspectRatio={node.aspectRatio} src={node.url} />
  ),
};
/* eslint-enable camelcase */

const markMap = {
  em: withText({ italic: true }),
  strong: withText({ bold: true }),
  code: withText({ as: "code" }),
  link: Link,
};

type Props = {
  content: BlockSpec[];
  typeMap?: {};
  markMap?: {};
};

const StructuredContent = (props: Props) => {
  const options = {
    typeMap: { ...typeMap, ...(props.typeMap || {}) },
    markMap: { ...markMap, ...(props.markMap || {}) },
  };

  return (
    <>{props.content.map((child, index) => mapTree(child, index, options))}</>
  );
};

export default StructuredContent;
