import { describe, expect, it } from 'vitest'
import type { KbxNavigationResolvedEntry } from '@kbx/contracts'
import { buildKbxHomeQuickStart, buildKbxHomeWorkbench, matchKbxRoutePattern, resolveKbxSafeRecentPath, resolveKbxSafeWorkspacePath } from '@kbx/ui'

const entry=(screenId:string,path:string,homePriority?:number):KbxNavigationResolvedEntry=>({screenId,path,title:screenId,module:'ERP',section:'업무',permissions:[],menuVisible:true,favoriteAllowed:true,recentPolicy:'screen',homePriority})

describe('KBX navigation hardening',()=>{
  it('deduplicates home quick start in favorite, tab, recent, priority order',()=>{
    const a=entry('A','/a',30),b=entry('B','/b',10),c=entry('C','/c',20)
    const result=buildKbxHomeQuickStart([a,b,c],[a],[{screenId:'B',path:'/b',title:'B',visitedAt:'2026-08-08T10:00:00Z'}],[{key:'C:/c',screenId:'C',title:'C',path:'/c',openedAt:'2026-08-08T09:00:00Z',lastActivatedAt:'2026-08-08T11:00:00Z'}])
    expect(result.map(x=>x.screenId)).toEqual(['A','C','B'])
  })

  it('never trusts a persisted route unless route mode and path boundary are both valid',()=>{
    const base={...entry('A','/erp/items'),recentPolicy:'route' as const}
    expect(resolveKbxSafeRecentPath(base,'/erp/items/123?tab=stock')).toBe('/erp/items/123')
    expect(resolveKbxSafeRecentPath(base,'/erp/items-evil/123')).toBe('/erp/items')
    expect(resolveKbxSafeRecentPath(base,'https://evil.example/x')).toBe('/erp/items')
    expect(resolveKbxSafeRecentPath({...base,recentPolicy:'screen'},'/erp/items/123')).toBe('/erp/items')
  })

  it('keeps dirty/open work ahead of favorites and avoids duplicate home launch rows',()=>{
    const a=entry('A','/a',30),b=entry('B','/b',10)
    const result=buildKbxHomeWorkbench([a,b],[a],[],[
      {key:'A:/a',screenId:'A',title:'A',path:'/a',openedAt:'2026-08-08T09:00:00Z',lastActivatedAt:'2026-08-08T11:00:00Z',dirty:true},
    ])
    expect(result.filter(x=>x.screenId==='A')).toHaveLength(1)
    expect(result[0]?.source).toBe('dirty')
  })

  it('validates workspace deep links against the registered route capability',()=>{
    expect(matchKbxRoutePattern('/oms/orders/:orderId/edit','/oms/orders/123/edit')).toBe(true)
    expect(matchKbxRoutePattern('/oms/orders/:orderId/edit','/oms/orders/123/delete')).toBe(false)
    expect(resolveKbxSafeWorkspacePath(['/oms/orders/:orderId/edit'],'/oms/orders/123/edit','/home')).toBe('/oms/orders/123/edit')
    expect(resolveKbxSafeWorkspacePath(['/oms/orders/:orderId/edit'],'https://evil.example/oms/orders/123/edit','/home')).toBe('/home')
  })

  it('rejects oversized and control-character workspace paths',()=>{
    const fallback='/home'
    expect(resolveKbxSafeWorkspacePath(['/erp/items/:itemId'],`/erp/items/${'a'.repeat(2100)}`,fallback)).toBe(fallback)
    expect(resolveKbxSafeWorkspacePath(['/erp/items/:itemId'],'/erp/items/abc\n123',fallback)).toBe(fallback)
    expect(resolveKbxSafeWorkspacePath(['/erp/items/:itemId'],'/erp/items/%2e%2e',fallback)).toBe(fallback)
  })

})
