import type { OrganizationModel } from '..'
import {
  addProjectNextStep,
  assertSystemPathAvailable,
  localIdOf,
  nextSystemOrder,
  parentPathOf,
  slugify,
  titleize
} from './helpers'
import type { OmScaffoldPlan, SystemScaffoldSpec } from './types'

export function scaffoldSystem(model: OrganizationModel, spec: SystemScaffoldSpec): OmScaffoldPlan {
  const systemPath = spec.parent !== undefined && !spec.id.includes('.') ? `${spec.parent}.${spec.id}` : spec.id
  assertSystemPathAvailable(model, systemPath)

  const parentPath = parentPathOf(systemPath)
  const localId = localIdOf(systemPath)
  const label = spec.label ?? titleize(localId)
  const roleId = spec.role ?? 'role.ops-lead'
  const uiPath = spec.uiPath ?? `/${localId}`
  const featureSlug = slugify(systemPath.replaceAll('.', '-'))
  const knowledgeId = `knowledge.${featureSlug}-system-overview`
  const order = nextSystemOrder(model, parentPath)
  // Systems default to opening a linked project because they usually start a multi-file build chain.
  const withProject = spec.withProject ?? !spec.noProject

  const systemEntry = `  ${JSON.stringify(localId)}: {
    id: ${JSON.stringify(systemPath)},
    order: ${order},
    label: ${JSON.stringify(label)},
    description: ${JSON.stringify(spec.description ?? `${label} bounded context.`)},
    kind: ${JSON.stringify(spec.kind ?? 'operational')},
    ${parentPath === undefined ? '' : `parentSystemId: ${JSON.stringify(parentPath)},\n    `}responsibleRoleId: ${JSON.stringify(roleId)},
    governedByKnowledge: [${JSON.stringify(knowledgeId)}],
    drivesGoals: [],
    lifecycle: 'draft',
    ui: {
      path: ${JSON.stringify(uiPath)},
      surfaces: [],
      ${spec.icon === undefined ? '' : `icon: ${JSON.stringify(spec.icon)},`}
    }${spec.withOntology ? `,
    ontology: {
      objectTypes: {}
    }` : ''}
  }`

  const plan: OmScaffoldPlan = {
    intent: 'system',
    id: systemPath,
    summary: `Scaffold System "${systemPath}" with nav, role wiring, governing knowledge, and a UI manifest stub.`,
    writes: [
      {
        path: `packages/ui/src/features/${featureSlug}/manifest.stub.ts`,
        mode: 'create',
        description: 'SystemModule manifest stub. Route files are intentionally not generated.',
        content: `import type { SystemModule } from '@repo/ui'\n\nexport const ${featureSlug.replaceAll('-', '_')}Manifest: SystemModule = {\n  key: ${JSON.stringify(featureSlug)},\n  systemId: ${JSON.stringify(systemPath)}\n}\n`
      },
      {
        path: `packages/elevasis-core/src/knowledge/nodes/${featureSlug}-system-overview.mdx.stub`,
        mode: 'create',
        description: 'Governing knowledge skeleton for the new System.',
        content: `---\nid: ${knowledgeId}\nkind: reference\ntitle: ${JSON.stringify(`${label} System Overview`)}\nsummary: ${JSON.stringify(`Governing context for the ${label} System.`)}\nlinks:\n  - system:${systemPath}\nownerIds:\n  - ${roleId}\nupdatedAt: 2026-05-15\n---\n\n## Purpose\n\nDocument the operating boundaries, decisions, and ownership for ${label}.\n`
      }
    ],
    edits: [
      {
        path: 'packages/elevasis-core/src/organization-model/systems.ts',
        description:
          parentPath === undefined
            ? 'Add this entry to platformSystems.'
            : `Add this entry under platformSystems ${parentPath}.systems.`,
        snippet: systemEntry
      },
      {
        path: 'packages/elevasis-core/src/organization-model/navigation.ts',
        description: 'Confirm sidebar placement derives from ui.path or add explicit surface targeting if needed.',
        snippet: `// System "${systemPath}" declares ui.path ${JSON.stringify(uiPath)}. Do not add route files in /om create.`
      },
      {
        path: 'packages/elevasis-core/src/organization-model/roles.ts',
        description: `Confirm ${roleId} exists or add the owning role before merging.`,
        snippet: `// responsibleRoleId: ${JSON.stringify(roleId)}`
      },
      {
        path: 'packages/elevasis-core/src/organization-model/assembly.ts',
        description: 'Confirm roleFor()/owner routing covers the new System.',
        snippet: `case ${JSON.stringify(systemPath)}:\n  return ${JSON.stringify(roleId)}`
      },
      {
        path: 'packages/elevasis-core/src/organization-model/knowledge.ts',
        description: 'Register the generated governing knowledge node after replacing the .stub suffix.',
        snippet: `${JSON.stringify(knowledgeId)}`
      }
    ],
    warnings: spec.withOntology
      ? ['Ontology was requested; the default objectTypes block is intentionally empty until the domain language is known.']
      : ['Ontology is opt-in. Re-run with --with-ontology when the object/action/catalog language is known.'],
    nextSteps: [
      'Review the planned OM edits and apply them in the listed source files.',
      'Replace .stub suffixes only after the System entry is merged.',
      `Run pnpm exec elevasis om:verify --scope ${systemPath}.`
    ]
  }

  return addProjectNextStep(
    plan,
    withProject,
    `pnpm exec elevasis project:create --link-om ${systemPath} --title "Build ${label} System" --kind system-build`
  )
}
