import React, { ReactNode, useState } from "react";
import { parse_org } from "../../organic/target/wasm32-unknown-unknown/js/wasm";
import styles from "./OrgAst.module.css";

const OrgAst = (props: {
  setHighlight: Function;
  clearHighlights: Function;
  value: string;
}) => {
  const ast_tree = parse_org(props.value);
  console.log(JSON.stringify(ast_tree));

  const [selectedNode, setSelectedNode] = useState<string>("");

  function selectNode(uid: string, start: number, end: number) {
    props.setHighlight(start, end);
    setSelectedNode(uid);
  }

  if (ast_tree.status !== "success") {
    return <div className={styles.OrgAst}>Error! {ast_tree.content}</div>;
  } else {
    return (
      <div className={styles.OrgAst}>
        <OrgAstNode
          selectNode={selectNode}
          node={ast_tree.content}
          parentUniqueId="^"
          selectedNode={selectedNode}
        />
      </div>
    );
  }
};

const OrgAstNode = (props: {
  selectNode: Function;
  node: any;
  parentUniqueId: string;
  selectedNode: string;
}) => {
  const uid =
    props.parentUniqueId +
    "_" +
    props.node["ast-node"] +
    "/" +
    props.node["standard-properties"]["begin"] +
    "/" +
    props.node["standard-properties"]["end"] +
    "#";

  function selectNode() {
    props.selectNode(
      uid,
      props.node["standard-properties"]["begin"] - 1,
      props.node["standard-properties"]["end"] - 1,
    );
  }

  const nodeClassName =
    props.selectedNode === uid
      ? styles.OrgAstNode + " " + styles.selected
      : styles.OrgAstNode;

  return (
    <div className={nodeClassName}>
      <div className={styles.OrgAstNodeType} onClick={selectNode}>
        {props.node["ast-node"]}
      </div>
      <details>
        <summary>Standard Properties</summary>
        <dl>
          <dt>begin</dt>
          <dd>{props.node["standard-properties"]["begin"]}</dd>
          <dt>contents-begin</dt>
          <dd>{props.node["standard-properties"]["contents-begin"]}</dd>
          <dt>contents-end</dt>
          <dd>{props.node["standard-properties"]["contents-end"]}</dd>
          <dt>end</dt>
          <dd>{props.node["standard-properties"]["end"]}</dd>
          <dt>post-blank</dt>
          <dd>{props.node["standard-properties"]["post-blank"]}</dd>
        </dl>
      </details>
      {Array.isArray(props.node.children) && props.node.children.length > 0 ? (
        <details open={true}>
          <summary>Children</summary>
          <div className={styles.OrgAstChildren}>
            <OrgAstNodeList
              selectNode={props.selectNode}
              parentUniqueId={props.parentUniqueId}
              selectedNode={props.selectedNode}
              node_list={props.node.children}
            />
          </div>
        </details>
      ) : null}
    </div>
  );
};

const OrgAstNodeList = (props: {
  selectNode: Function;
  parentUniqueId: string;
  selectedNode: string;
  node_list: any[];
}): React.JSX.Element[] => {
  return props.node_list.map((node) => {
    return (
      <OrgAstNode
        selectNode={props.selectNode}
        parentUniqueId={props.parentUniqueId}
        selectedNode={props.selectedNode}
        node={node}
      />
    );
  });
};

export default OrgAst;
