/**
 * Tests for js/router.js
 */

import { test, describe, assertEquals, assertDeepEquals, assertTrue } from './test-runner.js'
import { router } from '../js/router.js'

describe('router.parseHash', () => {
    test('parses simple path', () => {
        // Save original hash
        const original = window.location.hash
        
        window.location.hash = '/home'
        const result = router.parseHash()
        assertEquals(result.path, '/home')
        assertDeepEquals(result.params, {})
        
        // Restore
        window.location.hash = original
    })

    test('parses path with query params', () => {
        const original = window.location.hash
        
        window.location.hash = '/search?q=test&page=2'
        const result = router.parseHash()
        assertEquals(result.path, '/search')
        assertEquals(result.params.q, 'test')
        assertEquals(result.params.page, '2')
        
        window.location.hash = original
    })

    test('returns / for empty hash', () => {
        const original = window.location.hash
        
        window.location.hash = ''
        const result = router.parseHash()
        assertEquals(result.path, '/')
        
        window.location.hash = original
    })
})

describe('router.matchRoute', () => {
    // Register test routes
    router.register('/test', 'test-page')
    router.register('/user/:id', 'user-page')
    router.register('/post/:id/comment/:commentId', 'comment-page')

    test('matches exact route', () => {
        const match = router.matchRoute('/test')
        assertEquals(match.componentTag, 'test-page')
        assertDeepEquals(match.params, {})
    })

    test('matches route with single param', () => {
        const match = router.matchRoute('/user/123')
        assertEquals(match.componentTag, 'user-page')
        assertEquals(match.params.id, '123')
    })

    test('matches route with multiple params', () => {
        const match = router.matchRoute('/post/456/comment/789')
        assertEquals(match.componentTag, 'comment-page')
        assertEquals(match.params.id, '456')
        assertEquals(match.params.commentId, '789')
    })

    test('returns null for unmatched route', () => {
        const match = router.matchRoute('/unknown/path')
        assertEquals(match, null)
    })

    test('does not match wrong segment count', () => {
        const match = router.matchRoute('/user/123/extra')
        assertEquals(match, null)
    })
})

describe('router.register', () => {
    test('returns router for chaining', () => {
        const result = router.register('/chain-test', 'chain-page')
        assertEquals(result, router)
    })
})

describe('router.getCurrentRoute', () => {
    test('returns null before navigation', () => {
        // Note: May have a value if other tests triggered navigation
        const route = router.getCurrentRoute()
        assertTrue(route === null || typeof route === 'object')
    })
})

describe('router.navigate', () => {
    test('sets hash', () => {
        const original = window.location.hash
        
        router.navigate('/nav-test')
        assertTrue(window.location.hash.includes('nav-test'))
        
        window.location.hash = original
    })

    test('includes query params', () => {
        const original = window.location.hash
        
        router.navigate('/nav-test', { foo: 'bar', num: '42' })
        assertTrue(window.location.hash.includes('foo=bar'))
        assertTrue(window.location.hash.includes('num=42'))
        
        window.location.hash = original
    })
})
