import { describe, expect, it } from 'vitest'
import { buildOmCrossRefIndex, getClientProfile, getClientProfileBySlug, listClientProfiles } from '..'
import { buildOrganizationGraph } from '../graph/build'
import { OrganizationModelSchema } from '../schema'
import { resolveOrganizationModel } from '../resolve'

const CLIENT_ID = '11111111-1111-4111-8111-111111111111'

function makeClientProfile(overrides: Record<string, unknown> = {}) {
  return {
    id: CLIENT_ID,
    slug: 'byron-for-irvine',
    name: 'Byron for Irvine',
    status: 'onboarding',
    source: 'word_of_mouth',
    identity: {
      organizationName: 'Byron for Irvine',
      shortName: 'Byron',
      clientBrief: 'Irvine City Council District 5 campaign client.',
      geographicFocus: ['Irvine, CA'],
      timeZone: 'America/Los_Angeles'
    },
    branding: {
      voice: 'Direct and civic-minded',
      tagline: 'Byron for Irvine',
      values: ['Trust', 'Service']
    },
    workspace: {
      kind: 'external-project',
      owner: 'developer',
      projectId: 'developer-owned-project-or-slug'
    },
    links: {
      projectIds: ['22222222-2222-4222-8222-222222222222']
    },
    prompts: {
      defaultContext: 'Campaign context.'
    },
    config: {
      campaignSlug: 'byron-for-irvine'
    },
    customValues: {
      tenantOwned: false
    },
    ...overrides
  }
}

describe('client profile domain', () => {
  it('parses top-level clients keyed by canonical public.clients.id', () => {
    const model = resolveOrganizationModel({
      clients: {
        [CLIENT_ID]: makeClientProfile()
      }
    })

    expect(model.clients[CLIENT_ID]).toMatchObject({
      id: CLIENT_ID,
      slug: 'byron-for-irvine',
      name: 'Byron for Irvine',
      source: 'word_of_mouth'
    })
    expect(model.clients[CLIENT_ID].identity.geographicFocus).toEqual(['Irvine, CA'])
    expect(model.clients[CLIENT_ID].customValues.tenantOwned).toBe(false)
  })

  it('rejects a client profile whose id does not match its map key', () => {
    const result = OrganizationModelSchema.safeParse({
      clients: {
        [CLIENT_ID]: makeClientProfile({ id: '33333333-3333-4333-8333-333333333333' })
      }
    })

    expect(result.success).toBe(false)
    if (!result.success) {
      expect(result.error.issues.some((issue) => issue.message.includes('Each client profile id must match'))).toBe(
        true
      )
    }
  })

  it('rejects alternate OM link fields on client profiles', () => {
    const result = OrganizationModelSchema.safeParse({
      clients: {
        [CLIENT_ID]: makeClientProfile({ om_client_id: 'byron' })
      }
    })

    expect(result.success).toBe(false)
  })

  it('projects helper lookups by id and slug', () => {
    const model = resolveOrganizationModel({
      clients: {
        [CLIENT_ID]: makeClientProfile()
      }
    })

    expect(getClientProfile(model, CLIENT_ID)?.slug).toBe('byron-for-irvine')
    expect(getClientProfileBySlug(model, 'byron-for-irvine')?.id).toBe(CLIENT_ID)
    expect(listClientProfiles(model).map((client) => client.id)).toEqual([CLIENT_ID])
  })

  it('indexes client profiles as knowledge targets', () => {
    const model = resolveOrganizationModel({
      clients: {
        [CLIENT_ID]: makeClientProfile()
      },
      knowledge: {
        'knowledge.byron-client-context': {
          id: 'knowledge.byron-client-context',
          kind: 'reference',
          title: 'Byron Client Context',
          summary: 'Client profile context for Byron for Irvine.',
          body: '## Context\n\nByron campaign client context.',
          links: [{ target: { kind: 'client', id: CLIENT_ID } }],
          ownerIds: [],
          updatedAt: '2026-05-30'
        }
      }
    })
    const index = buildOmCrossRefIndex(model)

    expect(index.clientIds.has(CLIENT_ID)).toBe(true)
    expect(model.knowledge['knowledge.byron-client-context'].links[0].nodeId).toBe(`client:${CLIENT_ID}`)
  })

  it('projects client profiles into the organization graph', () => {
    const model = resolveOrganizationModel({
      clients: {
        [CLIENT_ID]: makeClientProfile()
      }
    })
    const graph = buildOrganizationGraph({ organizationModel: model })

    expect(graph.nodes.find((node) => node.id === `client:${CLIENT_ID}`)).toMatchObject({
      kind: 'client',
      sourceId: CLIENT_ID,
      label: 'Byron for Irvine',
      description: 'Irvine City Council District 5 campaign client.'
    })
    expect(
      graph.edges.find((edge) => edge.sourceId === 'organization-model' && edge.targetId === `client:${CLIENT_ID}`)
    ).toMatchObject({ kind: 'contains' })
  })
})
