import type { OrganizationModel } from '..'
import { assertSystemExists, makeOntologyId, ontologyMapName, titleize } from './helpers'
import type { OmScaffoldPlan, OntologyRecordScaffoldSpec } from './types'

function kindSpecificFields(spec: OntologyRecordScaffoldSpec): Record<string, unknown> {
  if (spec.kind === 'link') {
    return {
      from: makeOntologyId(spec.systemPath, 'object', 'source-object'),
      to: makeOntologyId(spec.systemPath, 'object', 'target-object')
    }
  }

  if (spec.kind === 'action') {
    return { actsOn: [] }
  }

  if (spec.kind === 'group') {
    return { members: [] }
  }

  return {}
}

export function scaffoldOntologyRecord(model: OrganizationModel, spec: OntologyRecordScaffoldSpec): OmScaffoldPlan {
  assertSystemExists(model, spec.systemPath)
  const localId = spec.localId ?? spec.id
  const ontologyId = makeOntologyId(spec.systemPath, spec.kind, localId)
  const label = spec.label ?? titleize(localId)
  const mapName = ontologyMapName(spec.kind)
  const snippetRecord = {
    id: ontologyId,
    label,
    ownerSystemId: spec.systemPath,
    ...(spec.description === undefined ? {} : { description: spec.description }),
    ...kindSpecificFields(spec)
  }
  // Non-System scaffolds only create linked projects when explicitly requested.

  return {
    intent: 'ontology',
    id: ontologyId,
    summary: `Scaffold ${spec.kind} ontology record "${ontologyId}".`,
    writes: [],
    edits: [
      {
        path: 'packages/elevasis-core/src/organization-model/systems.ts',
        description: `Add this record under ${spec.systemPath}.ontology.${mapName}.`,
        snippet: `${JSON.stringify(ontologyId)}: ${JSON.stringify(snippetRecord, null, 2)}`
      }
    ],
    warnings: [],
    nextSteps: [
      'Wire any cross-references using canonical ontology IDs.',
      `Run pnpm exec elevasis om:verify --scope ${spec.systemPath}.`
    ],
    projectCommand: spec.withProject
      ? `pnpm exec elevasis project:create --link-om ${spec.systemPath} --title "Add ${label} ontology" --kind om-change`
      : undefined
  }
}
