import * as React from 'react';
import { useLocation } from 'react-router-dom';

import type { UiAccessibleConfig } from '../../config';
import type { FeedbackProps } from '../types/feedback';
import type { MdHeading } from '../types/markdown';

import { DocumentationLayout } from '@redocly/theme/layouts/DocumentationLayout';
import { Markdown } from '@redocly/theme/components/Markdown/Markdown';
import { TableOfContent } from '@redocly/theme/components/TableOfContent/TableOfContent';
import { Feedback } from '@redocly/theme/components/Feedback/Feedback';
import { CodeWalkthroughLayout } from '@redocly/theme/layouts/CodeWalkthroughLayout';

import { IS_BROWSER, onDocumentReady } from '../utils/dom';
import { extendDetailsBehaviour } from '../utils/details';
import { useThemeHooks } from '../hooks/use-theme-hooks';
import { useThemeConfig } from '../hooks/use-theme-config';

export type MarkdownTemplateProps = {
  pageProps: {
    frontmatter?: UiAccessibleConfig;
    headings?: (MdHeading | null)[];
    editPage?: { to: string };
    lastModified?: string | null;
    metadata: {
      markdoc: { tagList: string[]; [key: string]: unknown };
      [key: string]: unknown;
    };
  };
};

export default function ({ pageProps, children }: React.PropsWithChildren<MarkdownTemplateProps>) {
  const [wrapperElement, setWrapperElement] = React.useState<HTMLDivElement | null>(null);
  const { useSidebarSiblingsData } = useThemeHooks();
  const { markdown } = useThemeConfig();
  const { nextPage, prevPage } = useSidebarSiblingsData() || {};
  const { pathname } = useLocation();

  const wrapperRefCb = React.useCallback(
    (node: HTMLDivElement) => {
      if (!node) {
        return;
      }
      setWrapperElement(node);
    },
    // eslint-disable-next-line no-warning-comments
    // TODO: is this correct?
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [pageProps.headings],
  );

  const tableOfContent = (
    <TableOfContent headings={pageProps.headings} contentWrapper={wrapperElement} />
  );

  const { type, settings, hide } = (pageProps.frontmatter?.feedback as FeedbackProps) || {};
  const feedback = <Feedback type={type} hide={hide} settings={settings} path={pathname} />;

  const documentationLayoutProps = {
    tableOfContent,
    feedback,
    config: markdown,
    editPage: pageProps.editPage,
    lastModified: pageProps.lastModified,
    nextPage,
    prevPage,
  };

  if (IS_BROWSER) {
    onDocumentReady(extendDetailsBehaviour);
  }

  const document = <Markdown ref={wrapperRefCb}>{children}</Markdown>;
  const tagList = pageProps.metadata.markdoc.tagList;
  const withCodeWalkthrough = Boolean(
    Array.isArray(tagList) && tagList.includes('code-walkthrough'),
  );

  return withCodeWalkthrough ? (
    <CodeWalkthroughLayout>{document}</CodeWalkthroughLayout>
  ) : (
    <DocumentationLayout {...documentationLayoutProps}>{document}</DocumentationLayout>
  );
}
