---
import { getEntry } from 'astro:content';
import ContentWidth from '@/components/frames/ContentWidth.astro';
import H2 from '@/components/typography/H2Markdown.astro';
import H3 from '@/components/typography/H3Markdown.astro';
import H4 from '@/components/typography/H4Markdown.astro';
import MarkdownCode from '@/components/typography/MarkdownCode.astro';
import P from '@/components/typography/P.astro';
import type { ComponentReference } from '@/types/component-reference';
import { isValidFramework } from '@/types/docs';
import { resolveReferenceSlug } from '@/utils/api-reference-overrides';
import { createComponentReferenceModel } from '@/utils/componentReferenceModel';
import FrameworkCase from '../FrameworkCase.astro';
import ApiCSSVarsTable from './ApiCSSVarsTable.astro';
import ApiDataAttrsTable from './ApiDataAttrsTable.astro';
import ApiPropsTable from './ApiPropsTable.astro';
import ApiStateTable from './ApiStateTable.astro';
import InlineMarkdown from './InlineMarkdown.astro';

interface Props {
  component: string;
  partOrder?: string[];
}

const { component, partOrder } = Astro.props;
const { framework } = Astro.params;
if (!framework || !isValidFramework(framework)) {
  throw new Error(`Invalid or missing framework param.`);
}

const entry = await getEntry('componentReference', resolveReferenceSlug(component));
const apiRef: ComponentReference | null = entry?.data ?? null;
if (!apiRef) return;

const apiReferenceModel = createComponentReferenceModel(component, apiRef, partOrder);
if (!apiReferenceModel) return;
const showAttributeName = framework === 'html';

const singlePropsSection = !apiReferenceModel.hasParts
  ? apiReferenceModel.sections.find((section) => section.key === 'props')
  : null;
const singleStateSection = !apiReferenceModel.hasParts
  ? apiReferenceModel.sections.find((section) => section.key === 'state')
  : null;
const singleDataAttributesSection = !apiReferenceModel.hasParts
  ? apiReferenceModel.sections.find((section) => section.key === 'dataAttributes')
  : null;
const singleCssCustomPropertiesSection = !apiReferenceModel.hasParts
  ? apiReferenceModel.sections.find((section) => section.key === 'cssCustomProperties')
  : null;
---

<ContentWidth>
  <H2 id={apiReferenceModel.heading.id}>{apiReferenceModel.heading.text}</H2>

  {
    apiReferenceModel.hasParts ? (
      apiReferenceModel.parts.map((part) => {
        const partPropsSection = part.sections.find(
          (section) => section.key === "props",
        );
        const partStateSection = part.sections.find(
          (section) => section.key === "state",
        );
        const partDataAttributesSection = part.sections.find(
          (section) => section.key === "dataAttributes",
        );
        const partCssCustomPropertiesSection = part.sections.find(
          (section) => section.key === "cssCustomProperties",
        );

        return (
          <FrameworkCase frameworks={part.frameworks}>
            <H3 id={part.id}>
              <FrameworkCase frameworks={["react"]}>
                {part.labelByFramework.react}
              </FrameworkCase>
              <FrameworkCase frameworks={["html"]}>
                {part.labelByFramework.html}
              </FrameworkCase>
            </H3>

            {part.description && (
              <P>
                <InlineMarkdown content={part.description} />
              </P>
            )}

            {partPropsSection && (
              <>
                <H4 id={partPropsSection.id}>{partPropsSection.title}</H4>
                <ApiPropsTable
                  props={part.data.props}
                  componentName={part.componentName}
                  showAttributeName={showAttributeName}
                />
              </>
            )}

            {partStateSection && (
              <>
                <H4 id={partStateSection.id}>{partStateSection.title}</H4>
                <P>
                  <FrameworkCase frameworks={["react"]}>
                    State is accessible via the{" "}
                    <MarkdownCode>render</MarkdownCode>,{" "}
                    <MarkdownCode>className</MarkdownCode>, and{" "}
                    <MarkdownCode>style</MarkdownCode> props.
                  </FrameworkCase>
                  <FrameworkCase frameworks={["html"]}>
                    State is reflected as data attributes for CSS styling.
                  </FrameworkCase>
                </P>
                <ApiStateTable
                  state={part.data.state}
                  componentName={part.componentName}
                />
              </>
            )}

            {partDataAttributesSection && (
              <>
                <H4 id={partDataAttributesSection.id}>
                  {partDataAttributesSection.title}
                </H4>
                <ApiDataAttrsTable
                  dataAttributes={part.data.dataAttributes}
                  componentName={part.componentName}
                />
              </>
            )}

            {partCssCustomPropertiesSection && (
              <>
                <H4 id={partCssCustomPropertiesSection.id}>
                  {partCssCustomPropertiesSection.title}
                </H4>
                <ApiCSSVarsTable
                  cssCustomProperties={part.data.cssCustomProperties}
                  componentName={part.componentName}
                />
              </>
            )}
          </FrameworkCase>
        );
      })
    ) : (
      <>
        {singlePropsSection && (
          <>
            <H3 id={singlePropsSection.id}>{singlePropsSection.title}</H3>
            <ApiPropsTable
              props={apiReferenceModel.data.props}
              componentName={component}
              showAttributeName={showAttributeName}
            />
          </>
        )}

        {singleStateSection && (
          <>
            <H3 id={singleStateSection.id}>{singleStateSection.title}</H3>
            <P>
              <FrameworkCase frameworks={["react"]}>
                State is accessible via the <MarkdownCode>render</MarkdownCode>,{" "}
                <MarkdownCode>className</MarkdownCode>, and{" "}
                <MarkdownCode>style</MarkdownCode> props.
              </FrameworkCase>
              <FrameworkCase frameworks={["html"]}>
                State is reflected as data attributes for CSS styling.
              </FrameworkCase>
            </P>
            <ApiStateTable
              state={apiReferenceModel.data.state}
              componentName={component}
            />
          </>
        )}

        {singleDataAttributesSection && (
          <>
            <H3 id={singleDataAttributesSection.id}>
              {singleDataAttributesSection.title}
            </H3>
            <ApiDataAttrsTable
              dataAttributes={apiReferenceModel.data.dataAttributes}
              componentName={component}
            />
          </>
        )}

        {singleCssCustomPropertiesSection && (
          <>
            <H3 id={singleCssCustomPropertiesSection.id}>
              {singleCssCustomPropertiesSection.title}
            </H3>
            <ApiCSSVarsTable
              cssCustomProperties={apiReferenceModel.data.cssCustomProperties}
              componentName={component}
            />
          </>
        )}
      </>
    )
  }
</ContentWidth>
