---
import AposWidget from "./AposWidget.astro";

const {
  area,
  aposAttributes,
  aposStyle,
  aposClassName,
  aposParentOptions,
  widgetComponent,
  ...props
} = Astro.props;

let attributes = {};

// Enough structure to render as an area at all (hardens against malformed
// data — never crash the render).
const renderable = area?.metaType === "area" && Array.isArray(area?.items);

const isOrphan = Boolean(area?._isOrphan);
const isArea = renderable && !isOrphan;

const hasField = Boolean(area?.field);

// Defensive: a corrupt item (null/typeless) must never crash the render.
const widgets: Record<string, any>[] = (area?.items || []).filter(
  (item: any) => item && item.type,
);

const isEdit =
  hasField && area?._edit && Astro.url.searchParams.get("aposEdit");
const forceWrapper = aposAttributes || aposStyle || aposClassName;

const WidgetComponent = widgetComponent ?? AposWidget;

if (isEdit) {
  attributes = {
    "data-apos-area-newly-editable": "",
    "data-doc-id": area?._docId,
    "data-area-id": area?._id,
    "data-field-id": area?.field?._id,
    "data-module": area?.field?.moduleName,
    "data-options": JSON.stringify(area?.options),
    "data-choices": JSON.stringify(area?.choices),
    "data-parent-options": JSON.stringify(aposParentOptions ?? {}),
    style: aposStyle ?? "",
    className: aposClassName ?? "",
    ...(aposAttributes ?? {}),
    data: JSON.stringify(area),
  };
} else if (forceWrapper) {
  attributes = {
    style: aposStyle ?? "",
    className: aposClassName ?? "",
    ...(aposAttributes ?? {}),
  };
}
const Wrapper = isEdit || forceWrapper ? "div" : Fragment;
const widgetOptions = getWidgetOptions(area?.options);

function getWidgetOptions(options: any = {}) {
  let widgets = { ...(options.widgets || {}) };

  if (options.groups) {
    for (const group of Object.keys(options.groups)) {
      widgets = {
        ...widgets,
        ...(options.groups[group]?.widgets || {}),
      };
    }
  }
  return widgets;
}
---

{
  isArea ? (
    <Wrapper {...attributes}>
      {widgets.map((item) => {
        const options = {
          ...item._options,
          ...widgetOptions[item.type],
        };
        return (
          <WidgetComponent
            widget={item}
            options={options}
            area={area}
            canEdit={isEdit}
            {...props}
          />
        );
      })}
    </Wrapper>
  ) : (
    // Genuine orphan only. Dev-only diagnostic: `import.meta.env.DEV` is
    // replaced with `false` in production, so this branch is dead-code
    // eliminated. Un-annotated (e.g. REST-delivered) areas never reach here —
    // they render above.
    (import.meta as any).env.DEV &&
    isOrphan && (
      <div
        data-apos-area-error
        role="alert"
        style="margin:1rem 0;padding:0.75rem 1rem;border:2px solid #dc2626;border-radius:4px;background:#fff1f2;color:#991b1b;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:0.85rem;line-height:1.5;"
      >
        <strong>ApostropheCMS:</strong> an area passed to{" "}
        <code>{"<AposArea />"}</code> is not defined in the schema, so it was
        not rendered. Its field was likely removed from the schema while content
        remains in the document. Restore the field in the schema, or remove the
        matching <code>{"<AposArea />"}</code> from this template.
        <br />
        <small>
          area _id: {area._id} — document: {area._docId}
        </small>
      </div>
    )
  )
}
