import { describe, it, expect } from 'vitest'
import { z } from 'zod'
import { ResourceRegistry } from '../resource-registry'
import type { RemoteOrgConfig } from '../resource-registry'
import type { WorkflowDefinition } from '../../../execution/engine/workflow/types'
import type { AgentDefinition } from '../../../execution/engine/agent/core/types'
import type { ModelConfig } from '../../../execution/engine/llm/model-info'
import type { ResourceEntry } from '../../../organization-model/domains/resources'
import type { SystemEntry } from '../../../organization-model/domains/systems'

describe('ResourceRegistry', () => {
  // Mock data helpers
  const createMockWorkflow = (resourceId: string, status: 'dev' | 'prod' = 'dev'): WorkflowDefinition => ({
    config: {
      resourceId,
      name: `Workflow ${resourceId}`,
      description: `Test workflow ${resourceId}`,
      version: '1.0.0',
      type: 'workflow',
      status
    },
    contract: {
      inputSchema: z.object({ data: z.string() }),
      outputSchema: z.object({ result: z.boolean() })
    },
    steps: {
      step1: {
        id: 'step1',
        name: 'First Step',
        description: 'First step',
        handler: async () => ({ result: true }),
        inputSchema: z.object({ data: z.string() }),
        outputSchema: z.object({ result: z.boolean() }),
        next: null
      }
    },
    entryPoint: 'step1'
  })

  const createMockAgent = (resourceId: string, status: 'dev' | 'prod' = 'dev'): AgentDefinition => ({
    config: {
      resourceId,
      name: `Agent ${resourceId}`,
      description: `Test agent ${resourceId}`,
      version: '1.0.0',
      type: 'agent',
      status,
      systemPrompt: 'You are a test agent'
    },
    contract: {
      inputSchema: z.object({ query: z.string() }),
      outputSchema: z.object({ response: z.string() })
    },
    tools: [],
    modelConfig: {
      provider: 'mock',
      apiKey: 'test-key',
      model: 'mock'
    } as ModelConfig
  })

  describe('getResourceDefinition', () => {
    it('returns workflow definition by resourceId', () => {
      const workflow = createMockWorkflow('test-workflow')
      const registry = new ResourceRegistry({
        'test-org': { workflows: [workflow] }
      })

      const result = registry.getResourceDefinition('test-org', 'test-workflow')

      expect(result).toBe(workflow)
      expect(result?.config.type).toBe('workflow')
    })

    it('returns agent definition by resourceId', () => {
      const agent = createMockAgent('test-agent')
      const registry = new ResourceRegistry({
        'test-org': { agents: [agent] }
      })

      const result = registry.getResourceDefinition('test-org', 'test-agent')

      expect(result).toBe(agent)
      expect(result?.config.type).toBe('agent')
    })

    it('returns null for non-existent organization', () => {
      const registry = new ResourceRegistry({})

      const result = registry.getResourceDefinition('nonexistent-org', 'test-workflow')

      expect(result).toBeNull()
    })

    it('returns null for non-existent resource in existing organization', () => {
      const registry = new ResourceRegistry({
        'test-org': { workflows: [] }
      })

      const result = registry.getResourceDefinition('test-org', 'nonexistent-resource')

      expect(result).toBeNull()
    })

    it('handles organization with only workflows', () => {
      const workflow = createMockWorkflow('test-workflow')
      const registry = new ResourceRegistry({
        'test-org': { workflows: [workflow] }
      })

      const result = registry.getResourceDefinition('test-org', 'test-workflow')

      expect(result).toBe(workflow)
    })

    it('handles organization with only agents', () => {
      const agent = createMockAgent('test-agent')
      const registry = new ResourceRegistry({
        'test-org': { agents: [agent] }
      })

      const result = registry.getResourceDefinition('test-org', 'test-agent')

      expect(result).toBe(agent)
    })

    it('handles multiple organizations', () => {
      const workflow1 = createMockWorkflow('workflow-1')
      const workflow2 = createMockWorkflow('workflow-2')

      const registry = new ResourceRegistry({
        'org-1': { workflows: [workflow1] },
        'org-2': { workflows: [workflow2] }
      })

      expect(registry.getResourceDefinition('org-1', 'workflow-1')).toBe(workflow1)
      expect(registry.getResourceDefinition('org-2', 'workflow-2')).toBe(workflow2)
      expect(registry.getResourceDefinition('org-1', 'workflow-2')).toBeNull()
    })
  })

  describe('listResourcesForOrganization', () => {
    it('returns empty list for non-existent organization', () => {
      const registry = new ResourceRegistry({})

      const result = registry.listResourcesForOrganization('nonexistent-org')

      expect(result).toEqual({
        workflows: [],
        agents: [],
        total: 0,
        organizationName: 'nonexistent-org',
        environment: undefined
      })
    })

    it('lists all workflows for organization', () => {
      const workflow1 = createMockWorkflow('workflow-1')
      const workflow2 = createMockWorkflow('workflow-2')

      const registry = new ResourceRegistry({
        'test-org': { workflows: [workflow1, workflow2] }
      })

      const result = registry.listResourcesForOrganization('test-org')

      expect(result.workflows).toHaveLength(2)
      expect(result.workflows[0]).toEqual({
        resourceId: 'workflow-1',
        name: 'Workflow workflow-1',
        description: 'Test workflow workflow-1',
        version: '1.0.0',
        type: 'workflow',
        status: 'dev',
        origin: 'local'
      })
      expect(result.agents).toHaveLength(0)
      expect(result.total).toBe(2)
    })

    it('lists all agents for organization', () => {
      const agent1 = createMockAgent('agent-1')
      const agent2 = createMockAgent('agent-2')

      const registry = new ResourceRegistry({
        'test-org': { agents: [agent1, agent2] }
      })

      const result = registry.listResourcesForOrganization('test-org')

      expect(result.agents).toHaveLength(2)
      expect(result.agents[0]).toEqual({
        resourceId: 'agent-1',
        name: 'Agent agent-1',
        description: 'Test agent agent-1',
        version: '1.0.0',
        type: 'agent',
        status: 'dev',
        sessionCapable: false,
        origin: 'local'
      })
      expect(result.workflows).toHaveLength(0)
      expect(result.total).toBe(2)
    })

    it('lists both workflows and agents', () => {
      const workflow = createMockWorkflow('workflow-1')
      const agent = createMockAgent('agent-1')

      const registry = new ResourceRegistry({
        'test-org': {
          workflows: [workflow],
          agents: [agent]
        }
      })

      const result = registry.listResourcesForOrganization('test-org')

      expect(result.workflows).toHaveLength(1)
      expect(result.agents).toHaveLength(1)
      expect(result.total).toBe(2)
    })

    it('includes descriptor-derived System and governance metadata', () => {
      const system: SystemEntry = {
        id: 'sys.lead-gen',
        title: 'Lead Generation',
        description: 'Lead acquisition workflows.',
        kind: 'operational',
        governedByKnowledge: [],
        drivesGoals: [],
        lifecycle: 'active',
        order: 10
      }
      const resource: ResourceEntry = {
        id: 'workflow-1',
        kind: 'workflow',
        systemPath: system.id,
        status: 'active',
        order: 10
      }
      const workflow = createMockWorkflow('workflow-1')
      workflow.config.resource = resource

      const registry = new ResourceRegistry({
        'test-org': {
          organizationModel: {
            systems: { [system.id]: system },
            resources: { [resource.id]: resource }
          },
          workflows: [workflow]
        }
      })

      const result = registry.listResourcesForOrganization('test-org')

      expect(result.workflows[0]).toMatchObject({
        resourceId: 'workflow-1',
        systemPath: 'sys.lead-gen',
        governanceStatus: 'active',
        system: {
          id: 'sys.lead-gen',
          title: 'Lead Generation',
          kind: 'operational',
          lifecycle: 'active'
        }
      })
    })

    it('filters resources by dev environment', () => {
      const devWorkflow = createMockWorkflow('workflow-dev', 'dev')
      const prodWorkflow = createMockWorkflow('workflow-prod', 'prod')

      const registry = new ResourceRegistry({
        'test-org': { workflows: [devWorkflow, prodWorkflow] }
      })

      const result = registry.listResourcesForOrganization('test-org', 'dev')

      expect(result.workflows).toHaveLength(1)
      expect(result.workflows[0].resourceId).toBe('workflow-dev')
      expect(result.workflows[0].status).toBe('dev')
      expect(result.environment).toBe('dev')
    })

    it('filters resources by prod environment', () => {
      const devAgent = createMockAgent('agent-dev', 'dev')
      const prodAgent = createMockAgent('agent-prod', 'prod')

      const registry = new ResourceRegistry({
        'test-org': { agents: [devAgent, prodAgent] }
      })

      const result = registry.listResourcesForOrganization('test-org', 'prod')

      expect(result.agents).toHaveLength(1)
      expect(result.agents[0].resourceId).toBe('agent-prod')
      expect(result.agents[0].status).toBe('prod')
      expect(result.environment).toBe('prod')
    })

    it('filters both workflows and agents by environment', () => {
      const devWorkflow = createMockWorkflow('workflow-dev', 'dev')
      const prodWorkflow = createMockWorkflow('workflow-prod', 'prod')
      const devAgent = createMockAgent('agent-dev', 'dev')
      const prodAgent = createMockAgent('agent-prod', 'prod')

      const registry = new ResourceRegistry({
        'test-org': {
          workflows: [devWorkflow, prodWorkflow],
          agents: [devAgent, prodAgent]
        }
      })

      const devResult = registry.listResourcesForOrganization('test-org', 'dev')
      expect(devResult.total).toBe(2)
      expect(devResult.workflows[0].status).toBe('dev')
      expect(devResult.agents[0].status).toBe('dev')

      const prodResult = registry.listResourcesForOrganization('test-org', 'prod')
      expect(prodResult.total).toBe(2)
      expect(prodResult.workflows[0].status).toBe('prod')
      expect(prodResult.agents[0].status).toBe('prod')
    })

    it('handles empty workflows array', () => {
      const registry = new ResourceRegistry({
        'test-org': { workflows: [] }
      })

      const result = registry.listResourcesForOrganization('test-org')

      expect(result.workflows).toEqual([])
      expect(result.total).toBe(0)
    })

    it('handles empty agents array', () => {
      const registry = new ResourceRegistry({
        'test-org': { agents: [] }
      })

      const result = registry.listResourcesForOrganization('test-org')

      expect(result.agents).toEqual([])
      expect(result.total).toBe(0)
    })

    it('includes organizationName in result', () => {
      const registry = new ResourceRegistry({
        'test-org': { workflows: [] }
      })

      const result = registry.listResourcesForOrganization('test-org')

      expect(result.organizationName).toBe('test-org')
    })
  })

  describe('listAllResources', () => {
    it('returns entire registry', () => {
      const workflow = createMockWorkflow('workflow-1')
      const agent = createMockAgent('agent-1')

      const registryData = {
        'org-1': { workflows: [workflow] },
        'org-2': { agents: [agent] }
      }

      const registry = new ResourceRegistry(registryData)

      const result = registry.listAllResources()

      expect(result).toBe(registryData)
    })

    it('returns empty object for empty registry', () => {
      const registry = new ResourceRegistry({})

      const result = registry.listAllResources()

      expect(result).toEqual({})
    })

    it('returns all organizations and resources', () => {
      const registryData = {
        'org-1': {
          workflows: [createMockWorkflow('w1'), createMockWorkflow('w2')],
          agents: [createMockAgent('a1')]
        },
        'org-2': {
          workflows: [createMockWorkflow('w3')],
          agents: [createMockAgent('a2'), createMockAgent('a3')]
        },
        'org-3': {
          workflows: [],
          agents: []
        }
      }

      const registry = new ResourceRegistry(registryData)

      const result = registry.listAllResources()

      expect(Object.keys(result)).toHaveLength(3)
      expect(result['org-1'].workflows).toHaveLength(2)
      expect(result['org-1'].agents).toHaveLength(1)
      expect(result['org-2'].workflows).toHaveLength(1)
      expect(result['org-2'].agents).toHaveLength(2)
    })
  })

  describe('edge cases and organization isolation', () => {
    it('maintains organization isolation (resources not shared)', () => {
      const workflow1 = createMockWorkflow('workflow-1')
      const workflow2 = createMockWorkflow('workflow-2')

      const registry = new ResourceRegistry({
        'org-1': { workflows: [workflow1] },
        'org-2': { workflows: [workflow2] }
      })

      // org-1 should only see workflow-1
      expect(registry.getResourceDefinition('org-1', 'workflow-1')).toBe(workflow1)
      expect(registry.getResourceDefinition('org-1', 'workflow-2')).toBeNull()

      // org-2 should only see workflow-2
      expect(registry.getResourceDefinition('org-2', 'workflow-2')).toBe(workflow2)
      expect(registry.getResourceDefinition('org-2', 'workflow-1')).toBeNull()
    })

    it('handles organization with undefined workflows', () => {
      const registry = new ResourceRegistry({
        'test-org': { agents: [createMockAgent('agent-1')] }
      })

      const result = registry.listResourcesForOrganization('test-org')

      expect(result.workflows).toEqual([])
      expect(result.agents).toHaveLength(1)
    })

    it('handles organization with undefined agents', () => {
      const registry = new ResourceRegistry({
        'test-org': { workflows: [createMockWorkflow('workflow-1')] }
      })

      const result = registry.listResourcesForOrganization('test-org')

      expect(result.workflows).toHaveLength(1)
      expect(result.agents).toEqual([])
    })

    it('handles large number of resources', () => {
      const workflows = Array.from({ length: 100 }, (_, i) => createMockWorkflow(`workflow-${i}`))
      const agents = Array.from({ length: 100 }, (_, i) => createMockAgent(`agent-${i}`))

      const registry = new ResourceRegistry({
        'test-org': { workflows, agents }
      })

      const result = registry.listResourcesForOrganization('test-org')

      expect(result.workflows).toHaveLength(100)
      expect(result.agents).toHaveLength(100)
      expect(result.total).toBe(200)
    })

    it('handles special characters in organization names', () => {
      const workflow = createMockWorkflow('test-workflow')

      const registry = new ResourceRegistry({
        'org-with-dashes': { workflows: [workflow] },
        org_with_underscores: { workflows: [workflow] },
        'org.with.dots': { workflows: [workflow] }
      })

      expect(registry.getResourceDefinition('org-with-dashes', 'test-workflow')).toBe(workflow)
      expect(registry.getResourceDefinition('org_with_underscores', 'test-workflow')).toBe(workflow)
      expect(registry.getResourceDefinition('org.with.dots', 'test-workflow')).toBe(workflow)
    })
  })

  describe('duplicate resourceId validation', () => {
    it('throws error on duplicate workflow resourceIds', () => {
      expect(() => {
        new ResourceRegistry({
          'test-org': {
            workflows: [createMockWorkflow('duplicate-id'), createMockWorkflow('duplicate-id')]
          }
        })
      }).toThrow('Duplicate resourceId "duplicate-id" in organization "test-org"')
    })

    it('throws error on duplicate agent resourceIds', () => {
      expect(() => {
        new ResourceRegistry({
          'test-org': {
            agents: [createMockAgent('duplicate-id'), createMockAgent('duplicate-id')]
          }
        })
      }).toThrow('Duplicate resourceId "duplicate-id" in organization "test-org"')
    })

    it('throws error on workflow/agent resourceId collision', () => {
      expect(() => {
        new ResourceRegistry({
          'test-org': {
            workflows: [createMockWorkflow('collision-id')],
            agents: [createMockAgent('collision-id')]
          }
        })
      }).toThrow('Duplicate resourceId "collision-id" in organization "test-org"')
    })

    it('allows same resourceId across different organizations', () => {
      expect(() => {
        new ResourceRegistry({
          'org-1': {
            workflows: [createMockWorkflow('same-id')]
          },
          'org-2': {
            workflows: [createMockWorkflow('same-id')]
          }
        })
      }).not.toThrow()
    })

    it('throws error on multiple duplicate resourceIds', () => {
      expect(() => {
        new ResourceRegistry({
          'test-org': {
            workflows: [
              createMockWorkflow('id-1'),
              createMockWorkflow('id-2'),
              createMockWorkflow('id-1') // Duplicate
            ]
          }
        })
      }).toThrow('Duplicate resourceId "id-1" in organization "test-org"')
    })

    it('validates across multiple organizations independently', () => {
      // org-1 has duplicate, org-2 is valid - should fail on org-1
      expect(() => {
        new ResourceRegistry({
          'org-1': {
            workflows: [createMockWorkflow('duplicate'), createMockWorkflow('duplicate')]
          },
          'org-2': {
            workflows: [createMockWorkflow('valid-id')]
          }
        })
      }).toThrow('Duplicate resourceId "duplicate" in organization "org-1"')
    })

    it('allows empty workflows and agents arrays', () => {
      expect(() => {
        new ResourceRegistry({
          'test-org': {
            workflows: [],
            agents: []
          }
        })
      }).not.toThrow()
    })

    it('allows undefined workflows and agents', () => {
      expect(() => {
        new ResourceRegistry({
          'test-org': {}
        })
      }).not.toThrow()
    })

    it('validates organization with only workflows', () => {
      expect(() => {
        new ResourceRegistry({
          'test-org': {
            workflows: [createMockWorkflow('dup'), createMockWorkflow('dup')]
          }
        })
      }).toThrow('Duplicate resourceId "dup"')
    })

    it('validates organization with only agents', () => {
      expect(() => {
        new ResourceRegistry({
          'test-org': {
            agents: [createMockAgent('dup'), createMockAgent('dup')]
          }
        })
      }).toThrow('Duplicate resourceId "dup"')
    })

    it('includes organization name in error message', () => {
      expect(() => {
        new ResourceRegistry({
          'my-special-org': {
            workflows: [createMockWorkflow('id'), createMockWorkflow('id')]
          }
        })
      }).toThrow('organization "my-special-org"')
    })

    it('includes resourceId in error message', () => {
      expect(() => {
        new ResourceRegistry({
          'test-org': {
            workflows: [createMockWorkflow('my-workflow-id'), createMockWorkflow('my-workflow-id')]
          }
        })
      }).toThrow('resourceId "my-workflow-id"')
    })
  })

  describe('model config validation', () => {
    it('validates agent model configs on construction', () => {
      const validAgent = createMockAgent('valid-agent')
      validAgent.modelConfig = {
        provider: 'openai',
        model: 'gpt-5',
        apiKey: 'test-key',
        temperature: 1,
        maxOutputTokens: 8000
      }

      expect(() => {
        new ResourceRegistry({
          'test-org': { agents: [validAgent] }
        })
      }).not.toThrow()
    })

    it('throws error for invalid agent temperature', () => {
      const invalidAgent = createMockAgent('invalid-agent')
      invalidAgent.modelConfig = {
        provider: 'openai',
        model: 'gpt-5',
        apiKey: 'test-key',
        temperature: 0.7, // Invalid - gpt-5 requires temperature=1
        maxOutputTokens: 8000
      }

      expect(() => {
        new ResourceRegistry({
          'test-org': { agents: [invalidAgent] }
        })
      }).toThrow('Invalid model config in test-org/invalid-agent')
      expect(() => {
        new ResourceRegistry({
          'test-org': { agents: [invalidAgent] }
        })
      }).toThrow('expected 1 (field: temperature)')
    })

    it('throws error for invalid agent maxOutputTokens', () => {
      const invalidAgent = createMockAgent('invalid-agent')
      invalidAgent.modelConfig = {
        provider: 'openai',
        model: 'gpt-5',
        apiKey: 'test-key',
        temperature: 1,
        maxOutputTokens: 2000 // Invalid - below minimum of 4000
      }

      expect(() => {
        new ResourceRegistry({
          'test-org': { agents: [invalidAgent] }
        })
      }).toThrow('Invalid model config in test-org/invalid-agent')
      expect(() => {
        new ResourceRegistry({
          'test-org': { agents: [invalidAgent] }
        })
      }).toThrow('expected number to be >=4000 (field: maxOutputTokens)')
    })

    it('validates workflow model configs if present', () => {
      const workflowWithModel = createMockWorkflow('workflow-with-model') as unknown as Record<string, unknown>
      ;(workflowWithModel as Record<string, unknown>).modelConfig = {
        provider: 'openai',
        model: 'gpt-5',
        apiKey: 'test-key',
        temperature: 0.5, // Invalid
        maxOutputTokens: 8000
      }

      expect(() => {
        new ResourceRegistry({
          'test-org': { workflows: [workflowWithModel] }
        })
      }).toThrow('Invalid model config in test-org/workflow-with-model')
    })

    it('allows workflows without model configs', () => {
      const workflowWithoutModel = createMockWorkflow('workflow-no-model')

      expect(() => {
        new ResourceRegistry({
          'test-org': { workflows: [workflowWithoutModel] }
        })
      }).not.toThrow()
    })

    it('validates multiple agents in same organization', () => {
      const validAgent1 = createMockAgent('agent-1')
      validAgent1.modelConfig = {
        provider: 'openai',
        model: 'gpt-5',
        apiKey: 'test-key',
        temperature: 1,
        maxOutputTokens: 8000
      }

      const invalidAgent2 = createMockAgent('agent-2')
      invalidAgent2.modelConfig = {
        provider: 'openai',
        model: 'gpt-5-mini',
        apiKey: 'test-key',
        temperature: 0.7, // Invalid
        maxOutputTokens: 8000
      }

      expect(() => {
        new ResourceRegistry({
          'test-org': { agents: [validAgent1, invalidAgent2] }
        })
      }).toThrow('Invalid model config in test-org/agent-2')
    })

    it('validates across multiple organizations', () => {
      const invalidAgent = createMockAgent('invalid-agent')
      invalidAgent.modelConfig = {
        provider: 'openai',
        model: 'gpt-5',
        apiKey: 'test-key',
        temperature: 0.7,
        maxOutputTokens: 8000
      }

      expect(() => {
        new ResourceRegistry({
          'org-1': { agents: [createMockAgent('valid-agent')] },
          'org-2': { agents: [invalidAgent] }
        })
      }).toThrow('Invalid model config in org-2/invalid-agent')
    })

    it('includes field name in error message', () => {
      const invalidAgent = createMockAgent('invalid-agent')
      invalidAgent.modelConfig = {
        provider: 'openai',
        model: 'gpt-5',
        apiKey: 'test-key',
        temperature: 0.7,
        maxOutputTokens: 8000
      }

      expect(() => {
        new ResourceRegistry({
          'test-org': { agents: [invalidAgent] }
        })
      }).toThrow('field: temperature')
    })

    it('allows mock models with any temperature', () => {
      const mockAgent = createMockAgent('mock-agent')
      mockAgent.modelConfig = {
        provider: 'mock',
        model: 'mock',
        apiKey: 'test-key',
        temperature: 0.5, // Any temperature OK for mock
        maxOutputTokens: 1000
      }

      expect(() => {
        new ResourceRegistry({
          'test-org': { agents: [mockAgent] }
        })
      }).not.toThrow()
    })
  })

  describe('environment filtering', () => {
    it('shows all resources in development environment', () => {
      // Mock development environment
      const originalEnv = process.env.NODE_ENV
      process.env.NODE_ENV = 'development'

      const devWorkflow = createMockWorkflow('dev-workflow', 'dev')
      const prodWorkflow = createMockWorkflow('prod-workflow', 'prod')
      const devAgent = createMockAgent('dev-agent', 'dev')
      const prodAgent = createMockAgent('prod-agent', 'prod')

      const registry = new ResourceRegistry({
        'test-org': {
          workflows: [devWorkflow, prodWorkflow],
          agents: [devAgent, prodAgent]
        }
      })

      const result = registry.listResourcesForOrganization('test-org')

      expect(result.total).toBe(4) // All resources visible
      expect(result.workflows).toHaveLength(2)
      expect(result.agents).toHaveLength(2)
      expect(result.workflows.some((w) => w.status === 'dev')).toBe(true)
      expect(result.workflows.some((w) => w.status === 'prod')).toBe(true)

      // Restore environment
      process.env.NODE_ENV = originalEnv
    })

    it('shows only prod resources when explicit environment filter is passed', () => {
      const devWorkflow = createMockWorkflow('dev-workflow', 'dev')
      const prodWorkflow = createMockWorkflow('prod-workflow', 'prod')
      const devAgent = createMockAgent('dev-agent', 'dev')
      const prodAgent = createMockAgent('prod-agent', 'prod')

      const registry = new ResourceRegistry({
        'test-org': {
          workflows: [devWorkflow, prodWorkflow],
          agents: [devAgent, prodAgent]
        }
      })

      const result = registry.listResourcesForOrganization('test-org', 'prod')

      expect(result.total).toBe(2) // Only prod resources
      expect(result.workflows).toHaveLength(1)
      expect(result.agents).toHaveLength(1)
      expect(result.workflows[0].status).toBe('prod')
      expect(result.agents[0].status).toBe('prod')
      expect(result.workflows.some((w) => w.status === 'dev')).toBe(false)
      expect(result.agents.some((a) => a.status === 'dev')).toBe(false)
    })

    it('returns all resources when no environment filter is passed', () => {
      const devWorkflow = createMockWorkflow('dev-workflow', 'dev')
      const prodWorkflow = createMockWorkflow('prod-workflow', 'prod')

      const registry = new ResourceRegistry({
        'test-org': {
          workflows: [devWorkflow, prodWorkflow]
        }
      })

      // No environment filter -- returns all resources regardless of status
      const result = registry.listResourcesForOrganization('test-org')

      expect(result.total).toBe(2)
      expect(result.workflows).toHaveLength(2)
    })

    it('returns empty list when filtering for prod but only dev resources exist', () => {
      const devWorkflow = createMockWorkflow('dev-workflow', 'dev')
      const devAgent = createMockAgent('dev-agent', 'dev')

      const registry = new ResourceRegistry({
        'test-org': {
          workflows: [devWorkflow],
          agents: [devAgent]
        }
      })

      const result = registry.listResourcesForOrganization('test-org', 'prod')

      expect(result.total).toBe(0)
      expect(result.workflows).toHaveLength(0)
      expect(result.agents).toHaveLength(0)
    })

    it('handles mixed status resources correctly with explicit prod filter', () => {
      const registry = new ResourceRegistry({
        'test-org': {
          workflows: [
            createMockWorkflow('w1', 'dev'),
            createMockWorkflow('w2', 'prod'),
            createMockWorkflow('w3', 'dev'),
            createMockWorkflow('w4', 'prod')
          ],
          agents: [createMockAgent('a1', 'dev'), createMockAgent('a2', 'prod'), createMockAgent('a3', 'dev')]
        }
      })

      const result = registry.listResourcesForOrganization('test-org', 'prod')

      expect(result.total).toBe(3) // 2 prod workflows + 1 prod agent
      expect(result.workflows).toHaveLength(2)
      expect(result.agents).toHaveLength(1)
    })

    it('includes environment in response when explicit filter is passed', () => {
      const registry = new ResourceRegistry({
        'test-org': {
          workflows: [createMockWorkflow('w1', 'prod')]
        }
      })

      const result = registry.listResourcesForOrganization('test-org', 'prod')

      expect(result.environment).toBe('prod')
    })

    it('does not include environment in response for development', () => {
      const originalEnv = process.env.NODE_ENV
      process.env.NODE_ENV = 'development'

      const registry = new ResourceRegistry({
        'test-org': {
          workflows: [createMockWorkflow('w1', 'dev')]
        }
      })

      const result = registry.listResourcesForOrganization('test-org')

      expect(result.environment).toBeUndefined()

      process.env.NODE_ENV = originalEnv
    })
  })

  describe('Resource Manifest Accessors', () => {
    // Helper to create mock triggers, integrations, etc.
    const createMockTrigger = (resourceId: string): import('../types').TriggerDefinition => ({
      resourceId,
      type: 'trigger',
      triggerType: 'manual',
      name: `Trigger ${resourceId}`,
      description: `Test trigger ${resourceId}`,
      version: '1.0.0',
      status: 'dev'
      // NOTE: No triggers field - will be added in tests as needed to reference valid resources
    })

    const createMockIntegration = (resourceId: string): import('../types').IntegrationDefinition => ({
      resourceId,
      type: 'integration',
      name: `Integration ${resourceId}`,
      description: `Test integration ${resourceId}`,
      version: '1.0.0',
      status: 'dev',
      provider: 'webhook',
      credentialName: 'test-cred'
    })

    const createMockExternalResource = (resourceId: string): import('../types').ExternalResourceDefinition => ({
      resourceId,
      type: 'external',
      name: `External ${resourceId}`,
      description: `Test external ${resourceId}`,
      version: '1.0.0',
      status: 'dev',
      platform: 'n8n'
      // NOTE: No triggeredBy field
    })

    const createMockHumanCheckpoint = (resourceId: string): import('../types').HumanCheckpointDefinition => ({
      resourceId,
      type: 'human',
      name: `Human ${resourceId}`,
      description: `Test human checkpoint ${resourceId}`,
      version: '1.0.0',
      status: 'dev'
    })

    describe('getTrigger', () => {
      it('finds trigger by resourceId', () => {
        const agent = createMockAgent('basic-agent')
        const trigger = createMockTrigger('test-trigger')
        trigger.triggers = { agents: ['basic-agent'] }

        const registry = new ResourceRegistry({
          'test-org': {
            agents: [agent],
            triggers: [trigger]
          }
        })

        const result = registry.getTrigger('test-org', 'test-trigger')

        expect(result).toBe(trigger)
        expect(result?.resourceId).toBe('test-trigger')
        expect(result?.type).toBe('trigger')
      })

      it('returns null for non-existent trigger', () => {
        const agent = createMockAgent('basic-agent')
        const trigger = createMockTrigger('trigger-1')
        trigger.triggers = { agents: ['basic-agent'] }

        const registry = new ResourceRegistry({
          'test-org': {
            agents: [agent],
            triggers: [trigger]
          }
        })

        const result = registry.getTrigger('test-org', 'nonexistent-trigger')

        expect(result).toBeNull()
      })

      it('returns null for non-existent organization', () => {
        const registry = new ResourceRegistry({})

        const result = registry.getTrigger('nonexistent-org', 'test-trigger')

        expect(result).toBeNull()
      })
    })

    describe('getIntegration', () => {
      it('finds integration by resourceId', () => {
        const integration = createMockIntegration('test-integration')
        const registry = new ResourceRegistry({
          'test-org': { integrations: [integration] }
        })

        const result = registry.getIntegration('test-org', 'test-integration')

        expect(result).toBe(integration)
        expect(result?.resourceId).toBe('test-integration')
        expect(result?.type).toBe('integration')
      })

      it('returns null for non-existent integration', () => {
        const registry = new ResourceRegistry({
          'test-org': { integrations: [createMockIntegration('integration-1')] }
        })

        const result = registry.getIntegration('test-org', 'nonexistent-integration')

        expect(result).toBeNull()
      })

      it('returns null for non-existent organization', () => {
        const registry = new ResourceRegistry({})

        const result = registry.getIntegration('nonexistent-org', 'test-integration')

        expect(result).toBeNull()
      })
    })

    describe('getExternalResource', () => {
      it('finds external resource by resourceId', () => {
        const external = createMockExternalResource('test-external')
        const registry = new ResourceRegistry({
          'test-org': { externalResources: [external] }
        })

        const result = registry.getExternalResource('test-org', 'test-external')

        expect(result).toBe(external)
        expect(result?.resourceId).toBe('test-external')
        expect(result?.platform).toBe('n8n')
      })

      it('returns null for non-existent external resource', () => {
        const registry = new ResourceRegistry({
          'test-org': { externalResources: [createMockExternalResource('external-1')] }
        })

        const result = registry.getExternalResource('test-org', 'nonexistent-external')

        expect(result).toBeNull()
      })

      it('returns null for non-existent organization', () => {
        const registry = new ResourceRegistry({})

        const result = registry.getExternalResource('nonexistent-org', 'test-external')

        expect(result).toBeNull()
      })
    })

    describe('getHumanCheckpoint', () => {
      it('finds human checkpoint by resourceId', () => {
        const humanCheckpoint = createMockHumanCheckpoint('test-human')
        const registry = new ResourceRegistry({
          'test-org': { humanCheckpoints: [humanCheckpoint] }
        })

        const result = registry.getHumanCheckpoint('test-org', 'test-human')

        expect(result).toBe(humanCheckpoint)
        expect(result?.resourceId).toBe('test-human')
        expect(result?.type).toBe('human')
      })

      it('returns null for non-existent human checkpoint', () => {
        const registry = new ResourceRegistry({
          'test-org': { humanCheckpoints: [createMockHumanCheckpoint('human-1')] }
        })

        const result = registry.getHumanCheckpoint('test-org', 'nonexistent-human')

        expect(result).toBeNull()
      })

      it('returns null for non-existent organization', () => {
        const registry = new ResourceRegistry({})

        const result = registry.getHumanCheckpoint('nonexistent-org', 'test-human')

        expect(result).toBeNull()
      })
    })

    describe('getTriggers, getIntegrations, getExternalResources, getHumanCheckpoints', () => {
      it('returns all triggers for organization', () => {
        const agent = createMockAgent('basic-agent')
        const trigger1 = createMockTrigger('trigger-1')
        trigger1.triggers = { agents: ['basic-agent'] }
        const trigger2 = createMockTrigger('trigger-2')
        trigger2.triggers = { agents: ['basic-agent'] }

        const registry = new ResourceRegistry({
          'test-org': {
            agents: [agent],
            triggers: [trigger1, trigger2]
          }
        })

        const result = registry.getTriggers('test-org')

        expect(result).toHaveLength(2)
        expect(result[0]).toBe(trigger1)
        expect(result[1]).toBe(trigger2)
      })

      it('returns all integrations for organization', () => {
        const integration1 = createMockIntegration('integration-1')
        const integration2 = createMockIntegration('integration-2')
        const registry = new ResourceRegistry({
          'test-org': { integrations: [integration1, integration2] }
        })

        const result = registry.getIntegrations('test-org')

        expect(result).toHaveLength(2)
        expect(result[0]).toBe(integration1)
        expect(result[1]).toBe(integration2)
      })

      it('returns all external resources for organization', () => {
        const external1 = createMockExternalResource('external-1')
        const external2 = createMockExternalResource('external-2')
        const registry = new ResourceRegistry({
          'test-org': { externalResources: [external1, external2] }
        })

        const result = registry.getExternalResources('test-org')

        expect(result).toHaveLength(2)
        expect(result[0]).toBe(external1)
        expect(result[1]).toBe(external2)
      })

      it('returns all human checkpoints for organization', () => {
        const human1 = createMockHumanCheckpoint('human-1')
        const human2 = createMockHumanCheckpoint('human-2')
        const registry = new ResourceRegistry({
          'test-org': { humanCheckpoints: [human1, human2] }
        })

        const result = registry.getHumanCheckpoints('test-org')

        expect(result).toHaveLength(2)
        expect(result[0]).toBe(human1)
        expect(result[1]).toBe(human2)
      })

      it('returns empty array for organization with no manifest data', () => {
        const registry = new ResourceRegistry({
          'test-org': { workflows: [createMockWorkflow('workflow-1')] }
        })

        expect(registry.getTriggers('test-org')).toEqual([])
        expect(registry.getIntegrations('test-org')).toEqual([])
        expect(registry.getExternalResources('test-org')).toEqual([])
        expect(registry.getHumanCheckpoints('test-org')).toEqual([])
      })
    })
  })

  describe('getCommandViewData', () => {
    it('returns correct edge types (triggers, uses, approval only)', () => {
      const trigger = {
        resourceId: 'trigger-1',
        type: 'trigger' as const,
        triggerType: 'manual' as const,
        name: 'Manual Trigger',
        description: 'Test trigger',
        version: '1.0.0',
        status: 'dev' as const,
        triggers: { workflows: ['workflow-1'] }
      }

      const integration = {
        resourceId: 'integration-1',
        type: 'integration' as const,
        name: 'Test Integration',
        description: 'Test integration',
        version: '1.0.0',
        status: 'dev' as const,
        provider: 'webhook' as const,
        credentialName: 'test-cred'
      }

      const humanCheckpoint = {
        resourceId: 'human-1',
        type: 'human' as const,
        name: 'Approval Point',
        description: 'Test human checkpoint',
        version: '1.0.0',
        status: 'dev' as const,
        requestedBy: { workflows: ['workflow-1'] },
        routesTo: { agents: ['agent-1'] }
      }

      const relationships = {
        'workflow-1': {
          uses: { integrations: ['integration-1'] }
        }
      }

      const registry = new ResourceRegistry({
        'test-org': {
          workflows: [createMockWorkflow('workflow-1')],
          agents: [createMockAgent('agent-1')],
          triggers: [trigger],
          integrations: [integration],
          humanCheckpoints: [humanCheckpoint],
          relationships
        }
      })

      const result = registry.getCommandViewData('test-org')

      // Verify all edge types are valid
      const edgeTypes = new Set(result.edges.map((e) => e.relationship))
      expect(edgeTypes.size).toBeGreaterThan(0)
      for (const edgeType of edgeTypes) {
        expect(['triggers', 'uses', 'approval']).toContain(edgeType)
      }
    })

    it('does NOT return edges with type invokes', () => {
      const trigger = {
        resourceId: 'trigger-1',
        type: 'trigger' as const,
        triggerType: 'manual' as const,
        name: 'Manual Trigger',
        description: 'Test trigger',
        version: '1.0.0',
        status: 'dev' as const,
        triggers: { workflows: ['workflow-1'] }
      }

      const registry = new ResourceRegistry({
        'test-org': {
          workflows: [createMockWorkflow('workflow-1')],
          triggers: [trigger]
        }
      })

      const result = registry.getCommandViewData('test-org')

      // Verify no 'invokes' edge type exists
      const hasInvokes = result.edges.some((e) => e.relationship === 'invokes')
      expect(hasInvokes).toBe(false)
    })

    it('includes all resource types in response', () => {
      const registry = new ResourceRegistry({
        'test-org': {
          workflows: [createMockWorkflow('workflow-1')],
          agents: [createMockAgent('agent-1')],
          triggers: [
            {
              resourceId: 'trigger-1',
              type: 'trigger' as const,
              triggerType: 'manual' as const,
              name: 'Manual Trigger',
              description: 'Test trigger',
              version: '1.0.0',
              status: 'dev' as const,
              triggers: { workflows: ['workflow-1'] }
            }
          ],
          integrations: [
            {
              resourceId: 'integration-1',
              type: 'integration' as const,
              name: 'Test Integration',
              description: 'Test integration',
              version: '1.0.0',
              status: 'dev' as const,
              provider: 'webhook' as const,
              credentialName: 'test-cred'
            }
          ],
          externalResources: [
            {
              resourceId: 'external-1',
              type: 'external' as const,
              name: 'External Resource',
              description: 'Test external',
              version: '1.0.0',
              status: 'dev' as const,
              platform: 'n8n' as const
            }
          ],
          humanCheckpoints: [
            {
              resourceId: 'human-1',
              type: 'human' as const,
              name: 'Approval Point',
              description: 'Test human checkpoint',
              version: '1.0.0',
              status: 'dev' as const
            }
          ]
        }
      })

      const result = registry.getCommandViewData('test-org')

      expect(result.workflows).toHaveLength(1)
      expect(result.agents).toHaveLength(1)
      expect(result.triggers).toHaveLength(1)
      expect(result.integrations).toHaveLength(1)
      expect(result.externalResources).toHaveLength(1)
      expect(result.humanCheckpoints).toHaveLength(1)
      expect(result.edges).toBeDefined()
    })

    it('returns empty data for non-existent organization', () => {
      const registry = new ResourceRegistry({})

      const result = registry.getCommandViewData('nonexistent-org')

      expect(result).toEqual({
        workflows: [],
        agents: [],
        triggers: [],
        integrations: [],
        externalResources: [],
        humanCheckpoints: [],
        edges: []
      })
    })

    it('returns edges referencing valid resourceIds', () => {
      const trigger = {
        resourceId: 'trigger-1',
        type: 'trigger' as const,
        triggerType: 'manual' as const,
        name: 'Manual Trigger',
        description: 'Test trigger',
        version: '1.0.0',
        status: 'dev' as const,
        triggers: { workflows: ['workflow-1'], agents: ['agent-1'] }
      }

      const integration = {
        resourceId: 'integration-1',
        type: 'integration' as const,
        name: 'Test Integration',
        description: 'Test integration',
        version: '1.0.0',
        status: 'dev' as const,
        provider: 'webhook' as const,
        credentialName: 'test-cred'
      }

      const relationships = {
        'workflow-1': {
          uses: { integrations: ['integration-1'] }
        }
      }

      const registry = new ResourceRegistry({
        'test-org': {
          workflows: [createMockWorkflow('workflow-1')],
          agents: [createMockAgent('agent-1')],
          triggers: [trigger],
          integrations: [integration],
          relationships
        }
      })

      const result = registry.getCommandViewData('test-org')

      // Collect all valid resourceIds
      const validIds = new Set(['workflow-1', 'agent-1', 'trigger-1', 'integration-1'])

      // Verify all edge sources and targets reference valid resourceIds
      for (const edge of result.edges) {
        expect(validIds.has(edge.source) || validIds.has(edge.target)).toBe(true)
      }
    })
  })

  describe('New Field Validation on Construction', () => {
    it('validates triggers use resourceId (not id)', () => {
      const agent = createMockAgent('basic-agent')
      const trigger = {
        resourceId: 'trigger-1',
        type: 'trigger' as const,
        triggerType: 'manual' as const,
        name: 'Manual Trigger',
        description: 'Test trigger',
        version: '1.0.0',
        status: 'dev' as const,
        triggers: { agents: ['basic-agent'] }
      }

      expect(() => {
        new ResourceRegistry({
          'test-org': {
            agents: [agent],
            triggers: [trigger]
          }
        })
      }).not.toThrow()

      // Verify trigger is stored with resourceId
      const registry = new ResourceRegistry({
        'test-org': {
          agents: [agent],
          triggers: [trigger]
        }
      })
      const result = registry.getTrigger('test-org', 'trigger-1')
      expect(result?.resourceId).toBe('trigger-1')
    })

    it('validates triggers have triggerType field', () => {
      const workflow = createMockWorkflow('test-workflow')
      const trigger = {
        resourceId: 'trigger-1',
        type: 'trigger' as const,
        triggerType: 'webhook' as const,
        name: 'Webhook Trigger',
        description: 'Test webhook trigger',
        version: '1.0.0',
        status: 'dev' as const,
        webhookPath: '/webhooks/test',
        triggers: { workflows: ['test-workflow'] }
      }

      expect(() => {
        new ResourceRegistry({
          'test-org': {
            workflows: [workflow],
            triggers: [trigger]
          }
        })
      }).not.toThrow()

      const registry = new ResourceRegistry({
        'test-org': {
          workflows: [workflow],
          triggers: [trigger]
        }
      })
      const result = registry.getTrigger('test-org', 'trigger-1')
      expect(result?.triggerType).toBe('webhook')
    })

    it('validates integrations have status field', () => {
      const integration = {
        resourceId: 'integration-1',
        type: 'integration' as const,
        name: 'Test Integration',
        description: 'Test integration',
        version: '1.0.0',
        status: 'prod' as const,
        provider: 'webhook' as const,
        credentialName: 'test-cred'
      }

      expect(() => {
        new ResourceRegistry({
          'test-org': { integrations: [integration] }
        })
      }).not.toThrow()

      const registry = new ResourceRegistry({
        'test-org': { integrations: [integration] }
      })
      const result = registry.getIntegration('test-org', 'integration-1')
      expect(result?.status).toBe('prod')
    })

    it('validates integrations have version field', () => {
      const integration = {
        resourceId: 'integration-1',
        type: 'integration' as const,
        name: 'Test Integration',
        description: 'Test integration',
        version: '2.1.0',
        status: 'dev' as const,
        provider: 'webhook' as const,
        credentialName: 'test-cred'
      }

      expect(() => {
        new ResourceRegistry({
          'test-org': { integrations: [integration] }
        })
      }).not.toThrow()

      const registry = new ResourceRegistry({
        'test-org': { integrations: [integration] }
      })
      const result = registry.getIntegration('test-org', 'integration-1')
      expect(result?.version).toBe('2.1.0')
    })

    it('validates human checkpoints have description (required)', () => {
      const humanCheckpoint = {
        resourceId: 'human-1',
        type: 'human' as const,
        name: 'Approval Point',
        description: 'Human decision point for high-value orders',
        version: '1.0.0',
        status: 'dev' as const
      }

      expect(() => {
        new ResourceRegistry({
          'test-org': { humanCheckpoints: [humanCheckpoint] }
        })
      }).not.toThrow()

      const registry = new ResourceRegistry({
        'test-org': { humanCheckpoints: [humanCheckpoint] }
      })
      const result = registry.getHumanCheckpoint('test-org', 'human-1')
      expect(result?.description).toBe('Human decision point for high-value orders')
    })
  })

  describe('Runtime Registration', () => {
    const createMockRemoteConfig = (overrides: Partial<RemoteOrgConfig> = {}): RemoteOrgConfig => ({
      storagePath: 'test-org/deploy-001/bundle.js',
      deploymentId: 'deploy-001',
      ...overrides
    })

    describe('registerOrganization -- merge into existing org', () => {
      it('registers remote workflows alongside existing static workflows', () => {
        const staticWorkflow = createMockWorkflow('static-wf')
        const remoteWorkflow = createMockWorkflow('remote-wf')

        const registry = new ResourceRegistry({
          'test-org': { workflows: [staticWorkflow] }
        })

        registry.registerOrganization('test-org', { workflows: [remoteWorkflow] }, createMockRemoteConfig())

        const result = registry.listResourcesForOrganization('test-org')
        expect(result.workflows).toHaveLength(2)
        expect(result.workflows.find((w) => w.resourceId === 'static-wf')).toBeDefined()
        expect(result.workflows.find((w) => w.resourceId === 'remote-wf')).toBeDefined()
      })

      it('registers remote agents alongside existing static agents', () => {
        const staticAgent = createMockAgent('static-agent')
        const remoteAgent = createMockAgent('remote-agent')

        const registry = new ResourceRegistry({
          'test-org': { agents: [staticAgent] }
        })

        registry.registerOrganization('test-org', { agents: [remoteAgent] }, createMockRemoteConfig())

        const result = registry.listResourcesForOrganization('test-org')
        expect(result.agents).toHaveLength(2)
        expect(result.agents.find((a) => a.resourceId === 'static-agent')).toBeDefined()
        expect(result.agents.find((a) => a.resourceId === 'remote-agent')).toBeDefined()
      })

      it('marks remote resources with origin "remote" and static resources with origin "local"', () => {
        const staticWorkflow = createMockWorkflow('static-wf')
        const remoteWorkflow = createMockWorkflow('remote-wf')

        const registry = new ResourceRegistry({
          'test-org': { workflows: [staticWorkflow] }
        })

        registry.registerOrganization('test-org', { workflows: [remoteWorkflow] }, createMockRemoteConfig())

        const result = registry.listResourcesForOrganization('test-org')
        expect(result.workflows.find((w) => w.resourceId === 'static-wf')?.origin).toBe('local')
        expect(result.workflows.find((w) => w.resourceId === 'remote-wf')?.origin).toBe('remote')
      })

      it('getRemoteConfig returns config for remote resource and null for static resource', () => {
        const staticWorkflow = createMockWorkflow('static-wf')
        const remoteWorkflow = createMockWorkflow('remote-wf')
        const remoteConfig = createMockRemoteConfig({ deploymentId: 'deploy-xyz' })

        const registry = new ResourceRegistry({
          'test-org': { workflows: [staticWorkflow] }
        })

        registry.registerOrganization('test-org', { workflows: [remoteWorkflow] }, remoteConfig)

        expect(registry.getRemoteConfig('test-org', 'remote-wf')).toMatchObject({
          storagePath: 'test-org/deploy-001/bundle.js',
          deploymentId: 'deploy-xyz'
        })
        expect(registry.getRemoteConfig('test-org', 'static-wf')).toBeNull()
      })

      it('isRemote returns true for org with remote resources', () => {
        const staticWorkflow = createMockWorkflow('static-wf')
        const remoteWorkflow = createMockWorkflow('remote-wf')

        const registry = new ResourceRegistry({
          'test-org': { workflows: [staticWorkflow] }
        })

        expect(registry.isRemote('test-org')).toBe(false)

        registry.registerOrganization('test-org', { workflows: [remoteWorkflow] }, createMockRemoteConfig())

        expect(registry.isRemote('test-org')).toBe(true)
      })
    })

    describe('registerOrganization -- conflict detection', () => {
      it('throws when remote resourceId collides with an existing static resource', () => {
        const staticWorkflow = createMockWorkflow('shared-id')
        const remoteWorkflow = createMockWorkflow('shared-id')

        const registry = new ResourceRegistry({
          'test-org': { workflows: [staticWorkflow] }
        })

        expect(() => {
          registry.registerOrganization('test-org', { workflows: [remoteWorkflow] }, createMockRemoteConfig())
        }).toThrow("Resource 'shared-id' already exists in 'test-org' as an internal resource")
      })

      it('throws when deployment contains duplicate resourceIds within itself', () => {
        const workflow1 = createMockWorkflow('dup-id')
        const workflow2 = createMockWorkflow('dup-id')

        const registry = new ResourceRegistry({})

        expect(() => {
          registry.registerOrganization('new-org', { workflows: [workflow1, workflow2] }, createMockRemoteConfig())
        }).toThrow("Duplicate resource ID 'dup-id' in deployment")
      })

      it('throws a validation error when incoming relationships reference missing resources after merge', () => {
        const remoteWorkflow = createMockWorkflow('remote-wf')

        const registry = new ResourceRegistry({
          'test-org': {
            workflows: [createMockWorkflow('static-wf')]
          }
        })

        expect(() => {
          registry.registerOrganization(
            'test-org',
            {
              workflows: [remoteWorkflow],
              relationships: {
                'remote-wf': {
                  triggers: { workflows: ['missing-target'] }
                }
              }
            },
            createMockRemoteConfig()
          )
        }).toThrow("[test-org] Resource 'remote-wf' triggers non-existent workflow: missing-target")
      })
    })

    describe('registerOrganization -- new org (no static resources)', () => {
      it('registers an org that does not exist in the static registry', () => {
        const remoteWorkflow = createMockWorkflow('remote-wf')
        const remoteAgent = createMockAgent('remote-agent')

        const registry = new ResourceRegistry({})

        registry.registerOrganization(
          'new-org',
          {
            workflows: [remoteWorkflow],
            agents: [remoteAgent]
          },
          createMockRemoteConfig()
        )

        const result = registry.listResourcesForOrganization('new-org')
        expect(result.workflows).toHaveLength(1)
        expect(result.workflows[0].resourceId).toBe('remote-wf')
        expect(result.agents).toHaveLength(1)
        expect(result.agents[0].resourceId).toBe('remote-agent')
        expect(result.total).toBe(2)
      })

      it('getResourceDefinition finds the registered remote resource', () => {
        const remoteWorkflow = createMockWorkflow('remote-wf')

        const registry = new ResourceRegistry({})

        registry.registerOrganization('new-org', { workflows: [remoteWorkflow] }, createMockRemoteConfig())

        const definition = registry.getResourceDefinition('new-org', 'remote-wf')
        expect(definition).not.toBeNull()
        expect(definition?.config.resourceId).toBe('remote-wf')
        expect(definition?.config.type).toBe('workflow')
      })
    })

    describe('unregisterOrganization -- cleanup', () => {
      it('remote resources no longer appear in listing after unregister', () => {
        const remoteWorkflow = createMockWorkflow('remote-wf')

        const registry = new ResourceRegistry({})
        registry.registerOrganization('test-org', { workflows: [remoteWorkflow] }, createMockRemoteConfig())

        registry.unregisterOrganization('test-org')

        const result = registry.listResourcesForOrganization('test-org')
        expect(result.workflows).toHaveLength(0)
        expect(result.total).toBe(0)
      })

      it('getRemoteConfig returns null after unregister', () => {
        const remoteWorkflow = createMockWorkflow('remote-wf')

        const registry = new ResourceRegistry({})
        registry.registerOrganization('test-org', { workflows: [remoteWorkflow] }, createMockRemoteConfig())

        expect(registry.getRemoteConfig('test-org', 'remote-wf')).not.toBeNull()

        registry.unregisterOrganization('test-org')

        expect(registry.getRemoteConfig('test-org', 'remote-wf')).toBeNull()
      })

      it('isRemote returns false after unregister', () => {
        const remoteWorkflow = createMockWorkflow('remote-wf')

        const registry = new ResourceRegistry({})
        registry.registerOrganization('test-org', { workflows: [remoteWorkflow] }, createMockRemoteConfig())

        expect(registry.isRemote('test-org')).toBe(true)

        registry.unregisterOrganization('test-org')

        expect(registry.isRemote('test-org')).toBe(false)
      })

      it('static resources survive unregister -- only remote resources are removed', () => {
        const staticWorkflow = createMockWorkflow('static-wf')
        const remoteWorkflow = createMockWorkflow('remote-wf')

        const registry = new ResourceRegistry({
          'test-org': { workflows: [staticWorkflow] }
        })
        registry.registerOrganization('test-org', { workflows: [remoteWorkflow] }, createMockRemoteConfig())

        // Both should be present before unregister
        expect(registry.listResourcesForOrganization('test-org').workflows).toHaveLength(2)

        registry.unregisterOrganization('test-org')

        const result = registry.listResourcesForOrganization('test-org')
        expect(result.workflows).toHaveLength(1)
        expect(result.workflows[0].resourceId).toBe('static-wf')
        expect(result.workflows[0].origin).toBe('local')
      })

      it('unregistering an org with no remote resources is a no-op', () => {
        const staticWorkflow = createMockWorkflow('static-wf')

        const registry = new ResourceRegistry({
          'test-org': { workflows: [staticWorkflow] }
        })

        // Should not throw or alter existing resources
        registry.unregisterOrganization('test-org')

        const result = registry.listResourcesForOrganization('test-org')
        expect(result.workflows).toHaveLength(1)
        expect(result.workflows[0].resourceId).toBe('static-wf')
      })
    })

    describe('registerOrganization -- redeploy (register twice)', () => {
      it('validates redeploy candidates against the incoming Organization Model snapshot', () => {
        const registry = new ResourceRegistry({})
        const remoteConfig = createMockRemoteConfig({ deploymentId: 'deploy-old' })
        const resourceId = 'remote-wf'
        const system = {
          id: 'sales.lead-gen',
          title: 'Lead Gen',
          description: 'Lead generation system',
          kind: 'domain',
          lifecycle: 'active'
        } as unknown as SystemEntry
        const makeResource = (actionId: string): ResourceEntry =>
          ({
            id: resourceId,
            kind: 'workflow',
            systemPath: system.id,
            title: 'Remote workflow',
            description: 'Remote workflow',
            status: 'active',
            ontology: {
              actions: [actionId],
              primaryAction: actionId
            }
          }) as ResourceEntry
        const makeModel = (resource: ResourceEntry) => ({
          systems: { [system.id]: system },
          resources: { [resource.id]: resource }
        })
        const makeDescriptorBackedWorkflow = (resource: ResourceEntry): WorkflowDefinition => {
          const workflow = createMockWorkflow(resource.id)

          return {
            ...workflow,
            config: {
              ...workflow.config,
              resource
            }
          } as WorkflowDefinition
        }

        const oldResource = makeResource('sales.lead-gen:action/old-import')
        const newResource = makeResource('sales.lead-gen:action/new-import')

        registry.registerOrganization(
          'test-org',
          {
            version: '1.0.0',
            organizationModel: makeModel(oldResource),
            workflows: [makeDescriptorBackedWorkflow(oldResource)]
          },
          remoteConfig
        )

        expect(() =>
          registry.registerOrganization(
            'test-org',
            {
              version: '1.0.1',
              organizationModel: makeModel(newResource),
              workflows: [makeDescriptorBackedWorkflow(newResource)]
            },
            createMockRemoteConfig({ deploymentId: 'deploy-new' })
          )
        ).not.toThrow()

        expect(registry.getRemoteConfig('test-org', resourceId)?.deploymentId).toBe('deploy-new')
      })

      it('second registerOrganization call replaces previous remote resources', () => {
        const remoteWorkflowV1 = createMockWorkflow('remote-wf')
        const remoteWorkflowV2 = createMockWorkflow('remote-wf-v2')

        const registry = new ResourceRegistry({})

        registry.registerOrganization(
          'test-org',
          { workflows: [remoteWorkflowV1] },
          createMockRemoteConfig({ deploymentId: 'deploy-v1' })
        )
        expect(registry.listResourcesForOrganization('test-org').workflows).toHaveLength(1)
        expect(registry.listResourcesForOrganization('test-org').workflows[0].resourceId).toBe('remote-wf')

        registry.registerOrganization(
          'test-org',
          { workflows: [remoteWorkflowV2] },
          createMockRemoteConfig({ deploymentId: 'deploy-v2' })
        )

        const result = registry.listResourcesForOrganization('test-org')
        expect(result.workflows).toHaveLength(1)
        expect(result.workflows[0].resourceId).toBe('remote-wf-v2')
      })

      it('getRemoteConfig returns the new config after redeploy, not the old one', () => {
        const remoteWorkflow = createMockWorkflow('remote-wf')

        const registry = new ResourceRegistry({})

        registry.registerOrganization(
          'test-org',
          { workflows: [remoteWorkflow] },
          createMockRemoteConfig({
            deploymentId: 'deploy-old',
            storagePath: 'test-org/deploy-old/bundle.js'
          })
        )

        expect(registry.getRemoteConfig('test-org', 'remote-wf')?.deploymentId).toBe('deploy-old')

        // Redeploy with same resource but new config
        registry.registerOrganization(
          'test-org',
          { workflows: [remoteWorkflow] },
          createMockRemoteConfig({
            deploymentId: 'deploy-new',
            storagePath: 'test-org/deploy-new/bundle.js'
          })
        )

        const config = registry.getRemoteConfig('test-org', 'remote-wf')
        expect(config?.deploymentId).toBe('deploy-new')
        expect(config?.storagePath).toBe('test-org/deploy-new/bundle.js')
      })

      it('preserves the current remote deployment when a redeploy fails merged validation', () => {
        const staticWorkflow = createMockWorkflow('static-wf')
        const remoteWorkflow = createMockWorkflow('remote-wf')
        const replacementWorkflow = createMockWorkflow('remote-wf-v2')

        const registry = new ResourceRegistry({
          'test-org': {
            workflows: [staticWorkflow]
          }
        })

        registry.registerOrganization(
          'test-org',
          {
            workflows: [remoteWorkflow],
            relationships: {
              'static-wf': {
                triggers: { workflows: ['remote-wf'] }
              }
            }
          },
          createMockRemoteConfig({ deploymentId: 'deploy-old' })
        )

        expect(() => {
          registry.registerOrganization(
            'test-org',
            { workflows: [replacementWorkflow] },
            createMockRemoteConfig({ deploymentId: 'deploy-new' })
          )
        }).toThrow("[test-org] Resource 'static-wf' triggers non-existent workflow: remote-wf")

        const result = registry.listResourcesForOrganization('test-org')
        expect(result.workflows.find((w) => w.resourceId === 'remote-wf')).toBeDefined()
        expect(result.workflows.find((w) => w.resourceId === 'remote-wf-v2')).toBeUndefined()
        expect(registry.getRemoteConfig('test-org', 'remote-wf')?.deploymentId).toBe('deploy-old')
      })
    })

    describe('environment filter with remote resources', () => {
      it('remote dev resources are filtered out when environment is prod', () => {
        const staticProdWorkflow = createMockWorkflow('static-prod', 'prod')
        const remoteDevWorkflow = createMockWorkflow('remote-dev', 'dev')

        const registry = new ResourceRegistry({
          'test-org': { workflows: [staticProdWorkflow] }
        })
        registry.registerOrganization('test-org', { workflows: [remoteDevWorkflow] }, createMockRemoteConfig())

        const result = registry.listResourcesForOrganization('test-org', 'prod')

        expect(result.workflows).toHaveLength(1)
        expect(result.workflows[0].resourceId).toBe('static-prod')
        expect(result.workflows.find((w) => w.resourceId === 'remote-dev')).toBeUndefined()
      })

      it('remote prod resources are included when environment is prod', () => {
        const staticProdWorkflow = createMockWorkflow('static-prod', 'prod')
        const remoteProdWorkflow = createMockWorkflow('remote-prod', 'prod')

        const registry = new ResourceRegistry({
          'test-org': { workflows: [staticProdWorkflow] }
        })
        registry.registerOrganization('test-org', { workflows: [remoteProdWorkflow] }, createMockRemoteConfig())

        const result = registry.listResourcesForOrganization('test-org', 'prod')

        expect(result.workflows).toHaveLength(2)
        expect(result.workflows.find((w) => w.resourceId === 'static-prod')).toBeDefined()
        expect(result.workflows.find((w) => w.resourceId === 'remote-prod')).toBeDefined()
        expect(result.workflows.find((w) => w.resourceId === 'remote-prod')?.origin).toBe('remote')
      })
    })
  })

  describe('Archived Resource Filtering', () => {
    it('excludes archived workflows from registerStaticResources', () => {
      const activeWorkflow = createMockWorkflow('active-wf')
      const archivedWorkflow: WorkflowDefinition = {
        ...createMockWorkflow('archived-wf'),
        config: {
          ...createMockWorkflow('archived-wf').config,
          archived: true
        }
      }

      const registry = new ResourceRegistry({})
      registry.registerStaticResources('test-org', {
        workflows: [activeWorkflow, archivedWorkflow]
      })

      const result = registry.listResourcesForOrganization('test-org')

      expect(result.workflows).toHaveLength(1)
      expect(result.workflows[0].resourceId).toBe('active-wf')
      expect(result.total).toBe(1)
    })

    it('excludes archived agents from registerStaticResources', () => {
      const activeAgent = createMockAgent('active-agent')
      const archivedAgent: AgentDefinition = {
        ...createMockAgent('archived-agent'),
        config: {
          ...createMockAgent('archived-agent').config,
          archived: true
        }
      }

      const registry = new ResourceRegistry({})
      registry.registerStaticResources('test-org', {
        agents: [activeAgent, archivedAgent]
      })

      const result = registry.listResourcesForOrganization('test-org')

      expect(result.agents).toHaveLength(1)
      expect(result.agents[0].resourceId).toBe('active-agent')
      expect(result.total).toBe(1)
    })

    it('includes resources without archived field (backwards compatibility)', () => {
      const workflow = createMockWorkflow('normal-wf')
      const agent = createMockAgent('normal-agent')

      // Verify neither has archived set
      expect(workflow.config).not.toHaveProperty('archived')
      expect(agent.config).not.toHaveProperty('archived')

      const registry = new ResourceRegistry({})
      registry.registerStaticResources('test-org', {
        workflows: [workflow],
        agents: [agent]
      })

      const result = registry.listResourcesForOrganization('test-org')

      expect(result.workflows).toHaveLength(1)
      expect(result.agents).toHaveLength(1)
      expect(result.total).toBe(2)
    })

    it('excludes archived workflows from registerOrganization', () => {
      const createMockRemoteConfig = (): RemoteOrgConfig => ({
        storagePath: 'test-org/deploy-001/bundle.js',
        deploymentId: 'deploy-001'
      })

      const activeWorkflow = createMockWorkflow('remote-active-wf')
      const archivedWorkflow: WorkflowDefinition = {
        ...createMockWorkflow('remote-archived-wf'),
        config: {
          ...createMockWorkflow('remote-archived-wf').config,
          archived: true
        }
      }

      const registry = new ResourceRegistry({})
      registry.registerOrganization(
        'test-org',
        { workflows: [activeWorkflow, archivedWorkflow] },
        createMockRemoteConfig()
      )

      const result = registry.listResourcesForOrganization('test-org')

      expect(result.workflows).toHaveLength(1)
      expect(result.workflows[0].resourceId).toBe('remote-active-wf')
    })

    it('excludes archived agents from registerOrganization', () => {
      const createMockRemoteConfig = (): RemoteOrgConfig => ({
        storagePath: 'test-org/deploy-001/bundle.js',
        deploymentId: 'deploy-001'
      })

      const activeAgent = createMockAgent('remote-active-agent')
      const archivedAgent: AgentDefinition = {
        ...createMockAgent('remote-archived-agent'),
        config: {
          ...createMockAgent('remote-archived-agent').config,
          archived: true
        }
      }

      const registry = new ResourceRegistry({})
      registry.registerOrganization('test-org', { agents: [activeAgent, archivedAgent] }, createMockRemoteConfig())

      const result = registry.listResourcesForOrganization('test-org')

      expect(result.agents).toHaveLength(1)
      expect(result.agents[0].resourceId).toBe('remote-active-agent')
    })
  })
})
