import { describe, expect, it } from 'vitest'
import { ResourceMappingSchema, TechStackEntrySchema } from '../../domains/shared'
import { resolveOrganizationModel } from '../../resolve'

// ---------------------------------------------------------------------------
// Minimal valid resource mapping fixture (no techStack) for reuse.
// ---------------------------------------------------------------------------

const MINIMAL_MAPPING = {
  id: 'rm-hubspot-sync',
  label: 'HubSpot Sync',
  resourceId: 'hubspot-sync-workflow',
  resourceType: 'workflow' as const,
  systemIds: [],
  entityIds: [],
  surfaceIds: [],
  actionIds: []
}

// ---------------------------------------------------------------------------
// Group 1: TechStackEntrySchema — positive parse
// ---------------------------------------------------------------------------

describe('TechStackEntrySchema — positive parse', () => {
  it('accepts a fully-populated tech stack entry', () => {
    const result = TechStackEntrySchema.safeParse({
      platform: 'HubSpot',
      purpose: 'Primary CRM and contact management',
      credentialStatus: 'configured',
      isSystemOfRecord: true
    })
    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.platform).toBe('HubSpot')
      expect(result.data.credentialStatus).toBe('configured')
      expect(result.data.isSystemOfRecord).toBe(true)
    }
  })

  it('isSystemOfRecord defaults to false when omitted', () => {
    const result = TechStackEntrySchema.safeParse({
      platform: 'Stripe',
      purpose: 'Payment processing',
      credentialStatus: 'pending'
    })
    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.isSystemOfRecord).toBe(false)
    }
  })

  it('accepts all four credentialStatus enum values', () => {
    const statuses = ['configured', 'pending', 'expired', 'missing'] as const
    for (const status of statuses) {
      const result = TechStackEntrySchema.safeParse({
        platform: 'SomePlatform',
        purpose: 'Some purpose',
        credentialStatus: status
      })
      expect(result.success).toBe(true)
    }
  })
})

// ---------------------------------------------------------------------------
// Group 2: TechStackEntrySchema — negative parse
// ---------------------------------------------------------------------------

describe('TechStackEntrySchema — negative parse', () => {
  it('rejects invalid credentialStatus enum value', () => {
    const result = TechStackEntrySchema.safeParse({
      platform: 'HubSpot',
      purpose: 'CRM',
      credentialStatus: 'active'
    })
    expect(result.success).toBe(false)
  })

  it('rejects missing platform', () => {
    const result = TechStackEntrySchema.safeParse({
      purpose: 'CRM',
      credentialStatus: 'configured'
    })
    expect(result.success).toBe(false)
  })

  it('rejects empty string platform', () => {
    const result = TechStackEntrySchema.safeParse({
      platform: '',
      purpose: 'CRM',
      credentialStatus: 'configured'
    })
    expect(result.success).toBe(false)
  })

  it('rejects missing purpose', () => {
    const result = TechStackEntrySchema.safeParse({
      platform: 'HubSpot',
      credentialStatus: 'configured'
    })
    expect(result.success).toBe(false)
  })

  it('rejects empty string purpose', () => {
    const result = TechStackEntrySchema.safeParse({
      platform: 'HubSpot',
      purpose: '',
      credentialStatus: 'configured'
    })
    expect(result.success).toBe(false)
  })

  it('rejects missing credentialStatus', () => {
    const result = TechStackEntrySchema.safeParse({
      platform: 'HubSpot',
      purpose: 'CRM'
    })
    expect(result.success).toBe(false)
  })
})

// ---------------------------------------------------------------------------
// Group 3: ResourceMappingSchema — backward compatibility (no techStack)
// ---------------------------------------------------------------------------

describe('ResourceMappingSchema — backward compatibility without techStack', () => {
  it('parses a mapping with no techStack key (legacy shape)', () => {
    const result = ResourceMappingSchema.safeParse(MINIMAL_MAPPING)
    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.techStack).toBeUndefined()
    }
  })

  it('parses a mapping with techStack explicitly set to undefined', () => {
    const result = ResourceMappingSchema.safeParse({ ...MINIMAL_MAPPING, techStack: undefined })
    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.techStack).toBeUndefined()
    }
  })

  it('all existing reference ID fields still default to empty arrays', () => {
    const result = ResourceMappingSchema.safeParse({
      id: 'rm-bare',
      label: 'Bare mapping',
      resourceId: 'bare-workflow',
      resourceType: 'workflow'
    })
    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.systemIds).toEqual([])
      expect(result.data.entityIds).toEqual([])
      expect(result.data.surfaceIds).toEqual([])
      expect(result.data.actionIds).toEqual([])
      expect(result.data.techStack).toBeUndefined()
    }
  })
})

// ---------------------------------------------------------------------------
// Group 4: ResourceMappingSchema — with techStack
// ---------------------------------------------------------------------------

describe('ResourceMappingSchema — with techStack', () => {
  it('parses a mapping with a full techStack object', () => {
    const result = ResourceMappingSchema.safeParse({
      ...MINIMAL_MAPPING,
      techStack: {
        platform: 'HubSpot',
        purpose: 'Contact and deal management',
        credentialStatus: 'configured',
        isSystemOfRecord: true
      }
    })
    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.techStack).toBeDefined()
      expect(result.data.techStack?.platform).toBe('HubSpot')
      expect(result.data.techStack?.credentialStatus).toBe('configured')
      expect(result.data.techStack?.isSystemOfRecord).toBe(true)
    }
  })

  it('isSystemOfRecord defaults to false inside techStack when omitted', () => {
    const result = ResourceMappingSchema.safeParse({
      ...MINIMAL_MAPPING,
      techStack: {
        platform: 'Notion',
        purpose: 'Internal knowledge base',
        credentialStatus: 'pending'
      }
    })
    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.techStack?.isSystemOfRecord).toBe(false)
    }
  })

  it('rejects a mapping with an invalid credentialStatus in techStack', () => {
    const result = ResourceMappingSchema.safeParse({
      ...MINIMAL_MAPPING,
      techStack: {
        platform: 'Stripe',
        purpose: 'Billing',
        credentialStatus: 'broken'
      }
    })
    expect(result.success).toBe(false)
  })

  it('rejects a mapping with techStack missing platform', () => {
    const result = ResourceMappingSchema.safeParse({
      ...MINIMAL_MAPPING,
      techStack: {
        purpose: 'Something',
        credentialStatus: 'configured'
      }
    })
    expect(result.success).toBe(false)
  })
})

// ---------------------------------------------------------------------------
// Group 5: Multiple mappings with mixed techStack presence
// ---------------------------------------------------------------------------

describe('ResourceMappingSchema — mixed techStack presence across entries', () => {
  it('resolves a model with multiple mappings — some with techStack, some without', () => {
    const withStack = {
      ...MINIMAL_MAPPING,
      id: 'rm-with-stack',
      resourceId: 'workflow-with-stack',
      techStack: {
        platform: 'Intercom',
        purpose: 'Customer support',
        credentialStatus: 'expired' as const
      }
    }
    const withoutStack = {
      id: 'rm-without-stack',
      label: 'Plain mapping',
      resourceId: 'plain-workflow',
      resourceType: 'integration' as const,
      systemIds: [],
      entityIds: [],
      surfaceIds: [],
      actionIds: []
    }

    const withResult = ResourceMappingSchema.safeParse(withStack)
    const withoutResult = ResourceMappingSchema.safeParse(withoutStack)

    expect(withResult.success).toBe(true)
    expect(withoutResult.success).toBe(true)

    if (withResult.success) {
      expect(withResult.data.techStack?.credentialStatus).toBe('expired')
    }
    if (withoutResult.success) {
      expect(withoutResult.data.techStack).toBeUndefined()
    }
  })
})

// ---------------------------------------------------------------------------
// Group 6: Integration via resolveOrganizationModel
// ---------------------------------------------------------------------------

describe('resolveOrganizationModel resource mapping removal', () => {
  it('resolved model validates without resourceMappings', () => {
    expect(() => resolveOrganizationModel({})).not.toThrow()
  })

  it('drops resourceMappings overrides because graph links now live on resources', () => {
    const model = resolveOrganizationModel({
      resourceMappings: [
        {
          id: 'rm-legacy',
          label: 'Legacy mapping',
          resourceId: 'legacy-workflow',
          resourceType: 'workflow',
          systemIds: [],
          entityIds: [],
          surfaceIds: [],
          actionIds: []
        }
      ]
    } as Parameters<typeof resolveOrganizationModel>[0])

    expect('resourceMappings' in model).toBe(false)
  })
})
