import { describe, expect, it } from 'vitest'
import {
  OrganizationModelNavigationSchema,
  TopbarActionNodeSchema,
  TopbarSectionSchema
} from '../../domains/navigation'
import { OrganizationModelSchema } from '../../schema'

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function makeMinimalSystems() {
  return {
    dashboard: {
      id: 'dashboard',
      order: 10,
      label: 'Dashboard',
      enabled: true,
      lifecycle: 'active' as const,
      path: '/'
    }
  }
}

function makeMinimalModel(overrides: Record<string, unknown> = {}) {
  return {
    version: 1,
    branding: { organizationName: 'Test', productName: 'Test OS', shortName: 'Test' },
    systems: makeMinimalSystems(),
    entities: {},
    actions: {},
    ...overrides
  }
}

// ---------------------------------------------------------------------------
// TopbarActionNodeSchema
// ---------------------------------------------------------------------------

describe('TopbarActionNodeSchema — leaf node shape', () => {
  it('accepts a minimal node (id + label + enabled default)', () => {
    const result = TopbarActionNodeSchema.safeParse({
      id: 'request',
      label: 'Request a feature or report an issue'
    })

    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.enabled).toBe(true)
    }
  })

  it('accepts a fully populated node', () => {
    const result = TopbarActionNodeSchema.safeParse({
      id: 'request',
      label: 'Request a feature or report an issue',
      tooltip: 'Request a feature or report an issue',
      icon: 'message-plus',
      order: 10,
      enabled: true,
      devOnly: false,
      requiresAdmin: false,
      targets: { systems: ['monitoring'], actions: [] }
    })

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

  it('defaults enabled to true when omitted', () => {
    const result = TopbarActionNodeSchema.parse({ id: 'docs', label: 'Docs' })

    expect(result.enabled).toBe(true)
  })

  it('accepts enabled: false to mark an item as hidden', () => {
    const result = TopbarActionNodeSchema.parse({ id: 'docs', label: 'Docs', enabled: false })

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

  it('accepts optional devOnly flag', () => {
    const result = TopbarActionNodeSchema.parse({ id: 'devtools', label: 'Dev Tools', devOnly: true })

    expect(result.devOnly).toBe(true)
  })

  it('accepts optional requiresAdmin flag', () => {
    const result = TopbarActionNodeSchema.parse({ id: 'admin-panel', label: 'Admin Panel', requiresAdmin: true })

    expect(result.requiresAdmin).toBe(true)
  })

  it('rejects a node missing id', () => {
    const result = TopbarActionNodeSchema.safeParse({ label: 'No Id' })

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

  it('rejects a node missing label', () => {
    const result = TopbarActionNodeSchema.safeParse({ id: 'no-label' })

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

  it('does NOT have a path field (leaf, not a route)', () => {
    const result = TopbarActionNodeSchema.parse({ id: 'request', label: 'Request' })

    expect('path' in result).toBe(false)
  })

  it('does NOT have a surfaceType field (closed enum untouched)', () => {
    const result = TopbarActionNodeSchema.parse({ id: 'request', label: 'Request' })

    expect('surfaceType' in result).toBe(false)
  })
})

// ---------------------------------------------------------------------------
// TopbarSectionSchema
// ---------------------------------------------------------------------------

describe('TopbarSectionSchema — flat map of topbar action nodes', () => {
  it('defaults to an empty record', () => {
    const result = TopbarSectionSchema.parse(undefined)

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

  it('accepts a populated map', () => {
    const result = TopbarSectionSchema.safeParse({
      request: { id: 'request', label: 'Request' },
      docs: { id: 'docs', label: 'Docs', icon: 'knowledge' }
    })

    expect(result.success).toBe(true)
    if (result.success) {
      expect(Object.keys(result.data)).toEqual(['request', 'docs'])
    }
  })
})

// ---------------------------------------------------------------------------
// OrganizationModelNavigationSchema — topbar field added
// ---------------------------------------------------------------------------

describe('OrganizationModelNavigationSchema — topbar region', () => {
  it('defaults topbar to an empty record', () => {
    const result = OrganizationModelNavigationSchema.parse({})

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

  it('retains existing sidebar defaults (regression: append only, sidebar untouched)', () => {
    const result = OrganizationModelNavigationSchema.parse({})

    expect(result.sidebar.primary).toEqual({})
    expect(result.sidebar.bottom).toEqual({})
  })

  it('accepts topbar nodes alongside sidebar', () => {
    const result = OrganizationModelNavigationSchema.safeParse({
      sidebar: { primary: {}, bottom: {} },
      topbar: {
        request: {
          id: 'request',
          label: 'Request a feature or report an issue',
          tooltip: 'Request a feature or report an issue',
          icon: 'message-plus',
          order: 10,
          enabled: true
        }
      }
    })

    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.topbar['request']?.id).toBe('request')
      expect(result.data.topbar['request']?.icon).toBe('message-plus')
    }
  })
})

// ---------------------------------------------------------------------------
// OrganizationModelSchema — navigation.topbar propagates through full schema
// ---------------------------------------------------------------------------

describe('OrganizationModelSchema — navigation.topbar contract', () => {
  it('accepts a model with topbar declared', () => {
    const result = OrganizationModelSchema.safeParse(
      makeMinimalModel({
        navigation: {
          topbar: {
            request: {
              id: 'request',
              label: 'Request a feature or report an issue',
              tooltip: 'Request a feature or report an issue',
              icon: 'message-plus',
              order: 10,
              enabled: true
            }
          }
        }
      })
    )

    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.navigation.topbar['request']?.id).toBe('request')
    }
  })

  it('defaults navigation.topbar to empty when navigation is omitted', () => {
    const result = OrganizationModelSchema.safeParse(makeMinimalModel())

    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.navigation.topbar).toEqual({})
    }
  })

  it('defaults navigation.topbar to empty when only sidebar is provided', () => {
    const result = OrganizationModelSchema.safeParse(
      makeMinimalModel({
        navigation: {
          sidebar: {
            primary: {
              dashboard: {
                type: 'surface',
                label: 'Dashboard',
                path: '/',
                surfaceType: 'dashboard',
                order: 10
              }
            },
            bottom: {}
          }
        }
      })
    )

    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.navigation.topbar).toEqual({})
    }
  })

  it('coexists with sidebar — both sections independently populated', () => {
    const result = OrganizationModelSchema.safeParse(
      makeMinimalModel({
        navigation: {
          sidebar: {
            primary: {
              dashboard: {
                type: 'surface',
                label: 'Dashboard',
                path: '/',
                surfaceType: 'dashboard',
                order: 10
              }
            },
            bottom: {}
          },
          topbar: {
            request: {
              id: 'request',
              label: 'Request',
              order: 10,
              enabled: true
            }
          }
        }
      })
    )

    expect(result.success).toBe(true)
    if (result.success) {
      expect(result.data.navigation.sidebar.primary['dashboard']?.label).toBe('Dashboard')
      expect(result.data.navigation.topbar['request']?.label).toBe('Request')
    }
  })
})
