"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateModelAdminPage = generateModelAdminPage;
const Generator = __importStar(require("@postxl/generator"));
/**
 * Generator function that generates the Admin page for a model
 */
function generateModelAdminPage({ model, context, }) {
    const adminUiPolicy = resolveAdminUiPolicy(model, context);
    const writePolicy = resolveWritePolicy(model, context);
    const imports = Generator.ImportGenerator
        //
        .from(model.admin.page.pageComponent.location)
        .add(model.table.component)
        .add(context.admin.components.sidebar)
        .add(context.admin.components.auditLogSidebar)
        .add(model.itemsHook)
        .addImport({
        from: Generator.toPackageName('react'),
        items: [
            Generator.toFunctionName('useState'),
            Generator.toFunctionName('useCallback'),
            Generator.toFunctionName('useMemo'),
            Generator.toFunctionName('useEffect'),
        ],
    })
        .addImport({
        from: model.types.filter.field.location,
        items: [
            model.types.filter.field.name,
            model.types.filter.fieldType.name,
            model.types.filter.config.name,
            model.types.filter.type.name,
        ],
    })
        .addImport({
        from: Generator.toPackageName('@types'),
        items: [Generator.toTypeName('SortState')],
    })
        .addImport({
        from: Generator.toPackageName('@tanstack/react-router'),
        items: [Generator.toFunctionName('useNavigate'), Generator.toFunctionName('useSearch')],
    })
        .addImport({
        from: Generator.toBackendModuleLocation('@app-actions/command-palette-action'),
        items: [
            Generator.toFunctionName('command'),
            Generator.toFunctionName('input'),
            Generator.toFunctionName('waitForNextFrame'),
        ],
    })
        .addImport({
        from: Generator.toBackendModuleLocation('@app-actions/command-palette-store'),
        items: [Generator.toFunctionName('useCommandPaletteActions')],
    })
        .addImport({
        from: Generator.toBackendModuleLocation('@app-actions/ai-sidebar-content'),
        items: [Generator.toFunctionName('AiSidebarContent')],
    })
        .addImport({
        from: Generator.toBackendModuleLocation('@lib/command-palette-filter.utils'),
        items: [
            Generator.toConstantName('stringFilterInputSchema'),
            Generator.toConstantName('numberFilterInputSchema'),
            Generator.toConstantName('dateFilterInputSchema'),
            Generator.toConstantName('booleanFilterInputSchema'),
            Generator.toFunctionName('parseBooleanQuery'),
            Generator.toFunctionName('toFilterActionLabel'),
        ],
    });
    const showComments = model.name !== 'Comment' && !!context.admin.components.commentSidebar;
    configureSidebarImports({ imports, context, showComments });
    const relatedModels = collectRelatedModels({ model, context, imports });
    const createModalContent = resolveCreateModalContent(model, imports);
    const canAccessAdminExpression = toRoleExpression(adminUiPolicy, 'userRoles');
    const canWriteModelExpression = toRoleExpression(writePolicy, 'userRoles');
    const commentCountState = buildCommentCountState(showComments);
    const modelHookMutationFields = buildModelHookMutationFields(model);
    const commentSidebarLogic = buildCommentSidebarLogic({ showComments, model });
    const commentSelectedEntityId = buildCommentSelectedEntityId(showComments);
    const cellUpdateHandler = buildCellUpdateHandler(model);
    const removeRowsHandler = buildRemoveRowsHandler(model);
    const commentSidebarTab = buildCommentSidebarTab({ showComments, model });
    const relatedTableProps = buildRelatedTableProps(relatedModels);
    const addRowProp = buildAddRowProp(model);
    const cellUpdateProp = buildCellUpdateProp(model);
    const removeRowsProp = buildRemoveRowsProp(model);
    return `
import { SidebarTab, useDebouncedCallback } from '@postxl/ui-components'
import { APP_CONFIG } from '@lib/config'
import { useAuth } from '@context-providers/auth-context-provider'
import { hasAnyRole } from '@lib/authorization'
${imports.generate()}

export default function ${model.admin.page.pageComponent.name}() {
  const navigate = useNavigate()
  const { viewerData } = useAuth()
  const currentUserId = viewerData?.user?.id
  const userRoles = viewerData?.userRoles ?? []
  const canAccessAdminPage = ${canAccessAdminExpression}
  const canWriteModel = ${canWriteModelExpression}
  ${commentCountState}

  const { selectedKey, focusedCell } = useSearch({
    from: '/_auth-routes${model.admin.page.route}',
    select: (search) => ({ selectedKey: search.selectedKey, focusedCell: search.focusedCell }),
  })
  
  ${createModalContent.hook}
  ${createModalContent.intentHook}
  // Track selected row IDs from checkbox selection
  const [selectedRowIds, setSelectedRowIds] = useState<string[]>([])

  const [filters, setFilters] = useState<${model.types.filter.type.name}>({})

  // Server-side sorting state (backend applies default sort by ID if empty)
  const [sortState, setSortState] = useState<SortState<${model.types.filter.fieldType.name}>>([])

  // Global search input state (debounced filter update happens via handleSearchInputChange)
  const [searchInput, setSearchInput] = useState('')
  const { registerComponentActions, deregisterComponentActions } = useCommandPaletteActions()

   const {
    ${model.itemsHook.filteredList.name}: filteredDataList,
    hasNextPage,
    fetchNextPage,
    total,
    ${modelHookMutationFields}
  } = ${model.itemsHook.name}({ filters, sort: sortState })

  // Queries for related models' maps used by the table (passed as separate props)
  ${relatedModels.map((rm) => rm.mapDefinition).join('\n  ')}


  // The selected entity ID comes from the URL selectedKey (which is the entity's id)
  const selectedEntityId = selectedKey ?? null

  // Get the selected field name based on focused cell (columnId from search params)
  const selectedField = useMemo(() => {
    if (!focusedCell || focusedCell === 'select' || focusedCell === 'actions') {
      return null
    }
    return focusedCell
  }, [focusedCell])

  ${commentSidebarLogic}
  // Callback when row selection changes (checkbox)
  const handleRowSelectionChange = useCallback((rowIds: string[]) => {
    setSelectedRowIds(rowIds)
    // Clear cell selection when using checkbox selection
    if (rowIds.length > 0) {
      void navigate({ to: '${model.admin.page.route}', search: { selectedKey: undefined, focusedCell: undefined } })
    }
  }, [navigate])

  // Clear field filter (go up to entity level)
  const handleClearField = useCallback(() => {
    void navigate({ to: '${model.admin.page.route}', search: { selectedKey, focusedCell: undefined } })
  }, [navigate, selectedKey])

  // Clear entity filter (go back to model overview)
  const handleClearEntity = useCallback(() => {
    void navigate({ to: '${model.admin.page.route}', search: { selectedKey: undefined, focusedCell: undefined } })
    setSelectedRowIds([])
  }, [navigate])

  const handleFilterChange = useCallback((key: ${model.types.filter.fieldType.name} | 'globalSearch', val: any) => {
    setFilters((prev) => {
      if (!val || (Array.isArray(val) && val.length === 0)) {
        const { [key]: _removed, ...rest } = prev
        return rest
      }
      return { ...prev, [key]: val }
    })
  }, [])

  // Debounced filter change for global search
  const debouncedFilterChange = useDebouncedCallback(handleFilterChange, 300)

  // Handler for search input that updates state immediately and triggers debounced filter
  const handleSearchInputChange = useCallback((value: string) => {
    setSearchInput(value)
    debouncedFilterChange('globalSearch', value)
  }, [debouncedFilterChange])

  // Callback when cell focus changes in the table — also sets selectedKey from the focused row
  const handleCellChange = useCallback((args: { rowIndex: number; columnId: string }) => {
    const row = filteredDataList?.[args.rowIndex]
    const key = row?.${model.keyField.name} == null ? undefined : String(row.${model.keyField.name})
    void navigate({ to: '${model.admin.page.route}', search: { selectedKey: key, focusedCell: args.columnId || undefined } })
    // Clear checkbox selection when focusing a cell
    setSelectedRowIds([])
  }, [navigate, filteredDataList])
    
  useEffect(() => {
    const prefix = 'admin-${model._conjugated.kebabCase}-filter'
    const getFilterInputSchema = (valueType: string) => {
      if (valueType === 'number') {
        return numberFilterInputSchema
      }
      if (valueType === 'date') {
        return dateFilterInputSchema
      }
      if (valueType === 'boolean') {
        return booleanFilterInputSchema
      }
      return stringFilterInputSchema
    }

    const filterActions = Object.entries(${model.types.filter.config.name}).map(([field, fieldConfig]) =>
      input({
        key: prefix + '-' + field,
        visibility: 'visible',
        group: 'Filter records by...',
        label: toFilterActionLabel(field),
        inputSchema: getFilterInputSchema(fieldConfig.valueType),
        run: async (query, inputValue) => {
          if (fieldConfig.valueType === 'number') {
            const parsed = numberFilterInputSchema.safeParse(inputValue)
            if (parsed.success && Object.values(parsed.data).some((value) => value !== undefined)) {
              handleFilterChange(fieldConfig.filterKey as ${model.types.filter.fieldType.name}, parsed.data)
            } else {
              const numericValue = Number(query.trim())
              if (!Number.isNaN(numericValue)) {
                handleFilterChange(fieldConfig.filterKey as ${model.types.filter.fieldType.name}, { values: [numericValue] })
              }
            }
          } else if (fieldConfig.valueType === 'date') {
            const parsed = dateFilterInputSchema.safeParse(inputValue)
            if (parsed.success && Object.values(parsed.data).some((value) => value !== undefined)) {
              handleFilterChange(fieldConfig.filterKey as ${model.types.filter.fieldType.name}, parsed.data)
            } else if (query.trim()) {
              handleFilterChange(fieldConfig.filterKey as ${model.types.filter.fieldType.name}, { values: [query.trim()] })
            }
          } else if (fieldConfig.valueType === 'boolean') {
            const parsed = booleanFilterInputSchema.safeParse(inputValue)
            if (parsed.success && parsed.data.values && parsed.data.values.length > 0) {
              handleFilterChange(fieldConfig.filterKey as ${model.types.filter.fieldType.name}, parsed.data.values)
            } else {
              const parsedFromQuery = parseBooleanQuery(query)
              if (parsedFromQuery) {
                handleFilterChange(fieldConfig.filterKey as ${model.types.filter.fieldType.name}, parsedFromQuery)
              }
            }
          } else {
            const parsed = stringFilterInputSchema.safeParse(inputValue)
            if (parsed.success && Object.values(parsed.data).some((value) => value !== undefined && value !== '')) {
              handleFilterChange(fieldConfig.filterKey as ${model.types.filter.fieldType.name}, parsed.data)
            } else if (query.trim()) {
              handleFilterChange(fieldConfig.filterKey as ${model.types.filter.fieldType.name}, { contains: query.trim() })
            }
          }

          await waitForNextFrame()
          return { kind: 'close' }
        },
      }),
    )

    const actions = [
      command({
        key: 'admin-${model._conjugated.kebabCase}-clear-all-filters',
        visibility: 'visible',
        group: 'Filter records by...',
        label: 'Clear all filters',
        run: async () => {
          setFilters({})
          setSearchInput('')
          await waitForNextFrame()
          return { kind: 'close' }
        },
      }),
      command({
        key: 'admin-${model._conjugated.kebabCase}-query-filters',
        visibility: 'llm',
        group: 'Filter records by...',
        label: 'Query active filters',
        run: () => Promise.resolve({ kind: 'output', output: { filters, searchInput } }),
      }),
      input({
        key: 'admin-${model._conjugated.kebabCase}-search',
        visibility: 'visible',
        group: 'Filter records by...',
        label: 'Global search',
        run: async (query) => {
          handleSearchInputChange(query)
          await waitForNextFrame()
          return { kind: 'close' }
        },
      }),
      ...filterActions,
    ]

    registerComponentActions(actions)

    return () => {
      deregisterComponentActions(actions)
    }
  }, [
    deregisterComponentActions,
    filters,
    handleFilterChange,
    handleSearchInputChange,
    registerComponentActions,
    searchInput,
    setFilters,
    setSearchInput,
  ])

  ${commentSelectedEntityId}

  ${cellUpdateHandler}

  ${removeRowsHandler}
  
  if (!canAccessAdminPage) {
    return null
  }

  return (
    <>
    <SidebarTab
        side="left"
        id="admin-navigation"
        icon={ListTree}
        label="Navigation"
      >
        <AdminSidebarNavContent />
      </SidebarTab>
      ${commentSidebarTab}
      <SidebarTab
        side="right"
        id="audit-log-content"
        icon={ScrollText}
        label="Audit Log"
        order={1}
      >
        <AuditLogSidebar
            model="${model.name}"
            entityId={selectedEntityId}
            entityIds={selectedRowIds}
            field={selectedField}
            labelField="${model.labelField.name}"
            onClearField={handleClearField}
            onClearEntity={handleClearEntity}
          />
      </SidebarTab>

      {APP_CONFIG.enableAI && (
        <SidebarTab
          side="right"
          id="ai-assistant-content"
          icon={Sparkles}
          label="AI Assistant"
          order={2}
        >
            <AiSidebarContent />
        </SidebarTab>
      )}
      <div className="p-4 overflow-hidden gap-4">
        <h3 className="font-bold text-[1.75rem]">${model.userFriendlyName}</h3>
        <${model.table.component.name}
          data={filteredDataList ?? []}
          filters={filters}
          onFilterChange={(filterKey, val) => {
          const config = ${model.types.filter.config.name}[filterKey]
            if (config.valueType === 'boolean') {
              handleFilterChange(
                config.filterKey,
                (val as string[]).map((v) => v === 'true'),
              )
            } else {
              handleFilterChange(config.filterKey, val)
            }
          }}
          searchInput={searchInput}
          onSearchInputChange={handleSearchInputChange}
          sort={sortState}
          onSortChange={setSortState}
          ${cellUpdateProp}
          ${addRowProp}
          ${removeRowsProp}
          onCellChange={handleCellChange}
          onRowSelectionChange={handleRowSelectionChange}
          selectedKey={selectedKey}
          keyField="${model.keyField.name}"
          hasNextPage={hasNextPage}
          fetchNextPage={fetchNextPage}
          total={total}
          model="${model._conjugated.camelCase}"
          currentUserId={currentUserId}
          isAdmin={canWriteModel}
          onFiltersReplace={setFilters}
          onSortReplace={setSortState}
          ${relatedTableProps}
        />
      </div>

      ${createModalContent.modal}
    </>
  )
}
`;
}
function configureSidebarImports({ imports, context, showComments, }) {
    if (showComments) {
        imports.add(context.admin.components.commentSidebar);
        imports.addImport({
            from: Generator.toPackageName('lucide-react'),
            items: [
                Generator.toFunctionName('ListTree'),
                Generator.toFunctionName('MessageSquareText'),
                Generator.toFunctionName('ScrollText'),
                Generator.toFunctionName('Sparkles'),
            ],
        });
        return;
    }
    imports.addImport({
        from: Generator.toPackageName('lucide-react'),
        items: [
            Generator.toFunctionName('ListTree'),
            Generator.toFunctionName('ScrollText'),
            Generator.toFunctionName('Sparkles'),
        ],
    });
}
function collectRelatedModels({ model, context, imports, }) {
    const relatedModels = [];
    for (const relatedModelName of model.relatedModelNames) {
        const relatedModel = context.models.get(relatedModelName);
        imports.add(relatedModel.itemsHook);
        relatedModels.push({
            model: relatedModel,
            mapName: relatedModel.internalPluralName,
            mapDefinition: `const {${relatedModel.itemsHook.map.name}: ${relatedModel.internalPluralName}} = ${relatedModel.itemsHook.name}()`,
        });
    }
    return relatedModels;
}
function toRoleExpression(policy, userRolesVariableName) {
    if (policy.allowAll) {
        return 'true';
    }
    return `hasAnyRole(${userRolesVariableName}, ${JSON.stringify(policy.roles)})`;
}
function buildCommentCountState(showComments) {
    if (!showComments) {
        return '';
    }
    return 'const [commentCount, setCommentCount] = useState(0)';
}
function buildModelHookMutationFields(model) {
    const fields = [];
    if (model.itemsHook.updateField) {
        fields.push(`${model.itemsHook.updateField.name}: updateFieldMutation,`);
    }
    if (model.itemsHook.updateFieldMany) {
        fields.push(`${model.itemsHook.updateFieldMany.name}: updateFieldManyMutation,`);
    }
    if (model.itemsHook.deleteMany) {
        fields.push(`${model.itemsHook.deleteMany.name}: deleteManyMutation,`);
    }
    return fields.join('\n    ');
}
function buildCommentSidebarLogic({ showComments, model, }) {
    if (!showComments) {
        return '';
    }
    return `// Comment sidebar: compute filtered entity IDs and label map from table data
  const commentFilteredIds = useMemo(() =>
    filteredDataList?.map(item => String(item.id)) ?? [],
    [filteredDataList]
  )
  const commentLabelMap = useMemo(() =>
    Object.fromEntries((filteredDataList ?? []).map(item => [String(item.id), String(item.${model.labelField.name})])),
    [filteredDataList]
  )`;
}
function buildCommentSelectedEntityId(showComments) {
    if (!showComments) {
        return '';
    }
    return `
  let commentSelectedEntityId: string | undefined
  if (selectedEntityId) {
    commentSelectedEntityId = String(selectedEntityId)
  } else if (selectedRowIds.length === 1) {
    commentSelectedEntityId = selectedRowIds[0]
  }`;
}
function buildCellUpdateHandler(model) {
    if (!model.itemsHook.updateField) {
        return '';
    }
    const flushMutations = model.itemsHook.updateFieldMany
        ? `if (entry.ids.length === 1) {
            void updateFieldMutation({ id: entry.ids[0], field: entry.field, value: entry.value } as Parameters<typeof updateFieldMutation>[0])
          } else {
            void updateFieldManyMutation({ ids: entry.ids, field: entry.field, value: entry.value } as Parameters<typeof updateFieldManyMutation>[0])
          }`
        : `for (const id of entry.ids) {
            void updateFieldMutation({ id, field: entry.field, value: entry.value } as Parameters<typeof updateFieldMutation>[0])
          }`;
    const dependencies = model.itemsHook.updateFieldMany
        ? '[filteredDataList, updateFieldMutation, updateFieldManyMutation]'
        : '[filteredDataList, updateFieldMutation]';
    return `// Batch cell updates: collect updates within the same microtask and send as one updateFieldMany
  const pendingUpdatesRef = useRef<Map<string, { field: string; value: unknown; ids: ${model.types.id.name}[] }> | null>(null)

  const handleCellUpdate = useCallback((args: { rowIndex: number; columnId: string; value: unknown }) => {
    const row = filteredDataList?.[args.rowIndex]
    if (!row) return

    // Initialize batch map and schedule flush on first call in this microtask
    if (!pendingUpdatesRef.current) {
      pendingUpdatesRef.current = new Map()
      queueMicrotask(() => {
        const pending = pendingUpdatesRef.current
        pendingUpdatesRef.current = null
        if (!pending) return

        for (const entry of pending.values()) {
          ${flushMutations}
        }
      })
    }

    // Group by field+value so identical field updates across rows get batched
    const key = \`\${args.columnId}::\${JSON.stringify(args.value)}\`
    const existing = pendingUpdatesRef.current.get(key)
    if (existing) {
      existing.ids.push(row.id)
    } else {
      pendingUpdatesRef.current.set(key, { field: args.columnId, value: args.value, ids: [row.id] })
    }
  }, ${dependencies})`;
}
function buildRemoveRowsHandler(model) {
    if (!model.itemsHook.deleteMany) {
        return '';
    }
    return `function handleRemoveRows(rows: ${model.types.id.name}[]) {
    void deleteManyMutation(rows)
  }`;
}
function buildCommentSidebarTab({ showComments, model }) {
    if (!showComments) {
        return '';
    }
    return `<SidebarTab
        side="right"
        id="comment-content"
        icon={MessageSquareText}
        label="Comment"
        order={0}
        badge={{ label: String(commentCount) }}
      >
        <ModelCommentContent
            model="${model.name}"
            filteredIds={commentFilteredIds}
            labelMap={commentLabelMap}
            selectedEntityId={commentSelectedEntityId}
            onCommentCountChange={setCommentCount}
        />
      </SidebarTab>`;
}
function buildRelatedTableProps(relatedModels) {
    return relatedModels.map((rm) => `${rm.model.table.propName}={${rm.mapName}}`).join('\n              ');
}
function buildAddRowProp(model) {
    if (model.isReadonly) {
        return '';
    }
    return 'handleAddRow={() => setIsCreateModalOpen(true)}';
}
function buildCellUpdateProp(model) {
    if (!model.itemsHook.updateField) {
        return '';
    }
    return 'onCellUpdate={handleCellUpdate}';
}
function buildRemoveRowsProp(model) {
    if (!model.itemsHook.deleteMany) {
        return '';
    }
    return 'handleRemoveRows={handleRemoveRows}';
}
function resolveCreateModalContent(model, imports) {
    if (!model.isReadonly) {
        imports
            .addType(model.types.id)
            .addImport({ from: Generator.toPackageName('sonner'), items: [Generator.toFunctionName('toast')] })
            .addImport({ from: model.forms.createModal.location, items: [model.forms.createModal.name] });
        if (model.itemsHook.updateField) {
            imports.addImport({ from: Generator.toPackageName('react'), items: [Generator.toFunctionName('useRef')] });
        }
        // In case the model does not provide any explicit label field, we generally use the id field as fallback.
        // However, in case of creating a new item, we do not have an Id yet and hence cannot show it in success and error messages.
        const hasLabelField = model.labelField.name !== model.idField.name;
        const variableName = hasLabelField ? `created${model.name}` : '_';
        const label = hasLabelField ? ` "\${${variableName}.${model.labelField.name}}"` : '';
        return {
            hook: ` const [isCreateModalOpen, setIsCreateModalOpen] = useState(false)`,
            intentHook: `
  useEffect(() => {
    if (typeof globalThis === 'undefined') {
      return
    }

    const storageKey = 'pxl:create-intent-model'
    const targetModel = '${model.name}'
    const openFromIntent = (intentModel: unknown) => {
      if (intentModel === targetModel) {
        setIsCreateModalOpen(true)
        globalThis.sessionStorage.removeItem(storageKey)
      }
    }

    openFromIntent(globalThis.sessionStorage.getItem(storageKey))

    const onIntent = (event: Event) => {
      const detail = (event as CustomEvent<{ model?: string }>).detail
      openFromIntent(detail?.model)
    }

    globalThis.addEventListener('pxl:create-intent', onIntent)
    return () => {
      globalThis.removeEventListener('pxl:create-intent', onIntent)
    }
  }, [])`,
            modal: `
    <${model.forms.createModal.name}
        open={isCreateModalOpen}
        onClose={() => setIsCreateModalOpen(false)}
        onSuccess={(${variableName}) => {
          toast.success(\`${model.userFriendlyName}${label} created successfully!\`)
          setIsCreateModalOpen(false)
        }}
        onError={(${variableName}, error) => {
          toast.error(\`Error creating ${model.userFriendlyName}${label}: \${String(error)}\`)
        }}
      />`,
        };
    }
    return { hook: '', intentHook: '', modal: '' };
}
function resolveSchemaRuleSet(model, context) {
    for (const [schemaName, schemaRules] of context.schema.schemaAuth.entries()) {
        if (schemaName === model.databaseSchema) {
            return (schemaRules ?? {});
        }
    }
    return {};
}
function resolveEffectiveRuleSet(model, context) {
    const schemaRuleSet = resolveSchemaRuleSet(model, context);
    const modelRuleSet = (model.auth ?? {});
    return { ...schemaRuleSet, ...modelRuleSet };
}
function resolveWritePolicy(model, context) {
    const effectiveRules = resolveEffectiveRuleSet(model, context);
    const roles = effectiveRules.write?.anyRole;
    if (roles) {
        return { allowAll: false, roles };
    }
    // If create/update/delete are configured independently, use a conservative write gate:
    // users must satisfy all configured operation role sets to see generic write UI controls.
    const operationRoleSets = [
        effectiveRules.create?.anyRole,
        effectiveRules.update?.anyRole,
        effectiveRules.delete?.anyRole,
    ]
        .filter((entry) => !!entry && entry.length > 0)
        .map((entry) => Array.from(new Set(entry)));
    if (operationRoleSets.length > 0) {
        const [firstRoleSet, ...remainingRoleSets] = operationRoleSets;
        if (!firstRoleSet) {
            return { allowAll: !(context.schema.auth?.defaultDeny ?? true), roles: [] };
        }
        const intersection = remainingRoleSets.reduce((shared, current) => shared.filter((role) => current.includes(role)), firstRoleSet);
        return { allowAll: false, roles: intersection };
    }
    return { allowAll: !(context.schema.auth?.defaultDeny ?? true), roles: [] };
}
function resolveAdminUiPolicy(model, context) {
    const effectiveRules = resolveEffectiveRuleSet(model, context);
    const roles = effectiveRules.adminUi?.visibleFor;
    if (roles) {
        return { allowAll: false, roles };
    }
    return { allowAll: !(context.schema.auth?.defaultDeny ?? true), roles: [] };
}
//# sourceMappingURL=model-admin-page.generator.js.map