import React from 'react';
import { Box } from '@wix/design-system';
import { observer } from 'mobx-react-lite';
import type { Field } from '@wix/bex-core';
import { PatternsFieldsProvider, useEntityPageContext } from '../../providers';
import { EntityPageField } from './EntityPageField';

export interface EntityPageFieldsProps {
  dataHook?: string;
  /** Field ids to render, in order. Omitted ⇒ all schema fields in schema order. */
  fieldIds?: string[];
}

function _EntityPageFields({
  dataHook = 'entity-page-fields',
  fieldIds,
}: EntityPageFieldsProps) {
  const state = useEntityPageContext();
  const { schema } = state;

  // The schema loads with the entity in EntityPageState.init(); until it
  // resolves there are no fields to render.
  if (!schema) {
    return null;
  }

  const fields = resolveFields(schema.fields, schema.idField, fieldIds);
  const data = (state.entity ?? {}) as Record<string, unknown>;

  return (
    <Box direction="vertical" gap="SP4" width="100%" dataHook={dataHook}>
      {fields.map((field) => (
        <EntityPageField
          key={field.id}
          field={field}
          formControl={state.form.control}
          data={data}
        />
      ))}
    </Box>
  );
}

function resolveFields(
  fields: Record<string, Field | undefined>,
  idField: string,
  fieldIds?: string[],
): Field[] {
  // An explicit fieldIds list is taken as-is — the consumer chose those fields.
  if (fieldIds) {
    return fieldIds
      .map((id) => fields[id])
      .filter((field): field is Field => Boolean(field));
  }

  // By default, skip the id field and system fields (e.g. `_id`, `_manualSort`,
  // `_createdDate`): they are not user-editable, and rendering a required one
  // would silently block save (react-hook-form marks the form invalid).
  return Object.values(fields).filter(
    (field): field is Field =>
      Boolean(field) && !field!.isSystem && field!.id !== idField,
  );
}

export const EntityPageFieldsWrapped = observer(_EntityPageFields);
export function EntityPageFields(props: EntityPageFieldsProps) {
  return (
    <PatternsFieldsProvider>
      <EntityPageFieldsWrapped {...props} />
    </PatternsFieldsProvider>
  );
}
