import { createHash } from 'node:crypto';
import { mount } from '@vue/test-utils';
import { describe, expect, it } from 'vitest';
import {
    KVIEW_ICON_ALIASES,
    KVIEW_ICON_FALLBACK,
    KVIEW_ICON_PATHS,
    kviewIconMarkup,
    resolveKviewIconName,
    resolveKviewIconPath,
} from '@kview/ui-core/js/icon-registry';
import KviewIcon from '@kview/ui-core/vue/KviewIcon.vue';

const EXPECTED_ICON_NAMES = [
    'home',
    'dashboard',
    'portfolio',
    'fund',
    'globe',
    'chart',
    'document',
    'spreadsheet',
    'excel',
    'download',
    'upload',
    'filter',
    'search',
    'user',
    'settings',
    'sliders',
    'import-export',
    'plus',
    'minus',
    'more-horizontal',
    'check',
    'x',
    'edit',
    'trash',
    'external',
    'arrow-right',
    'arrow-left',
    'chevron-up',
    'chevron-down',
    'chevron-left',
    'chevron-right',
    'panel-left-close',
    'panel-left-open',
    'trend-up',
    'trend-down',
    'euro',
    'wallet',
    'coins',
    'transfer',
    'refresh',
    'users',
    'capital',
    'investment',
    'status',
    'info',
    'calendar',
    'lock',
    'alert',
    'eye',
    'grid',
    'layers',
    'building',
    'landmark',
    'database-settings',
    'sort',
    'grip-vertical',
] as const;

function normalizeSvgFragment(fragment: string): string {
    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');

    svg.innerHTML = fragment;

    return svg.innerHTML;
}

describe('kView shared icon registry', () => {
    it('keeps the complete characterized icon geometry available to TypeScript', () => {
        expect(Object.keys(KVIEW_ICON_PATHS)).toEqual(EXPECTED_ICON_NAMES);
        expect(createHash('sha256')
            .update(JSON.stringify(KVIEW_ICON_PATHS))
            .digest('hex'))
            .toBe('37d8a2782c3bc33a196ffe39a86280e0e15f0bc9d634382c438b97aa091f3be9');

        for (const name of EXPECTED_ICON_NAMES) {
            expect(resolveKviewIconName(name)).toBe(name);
            expect(resolveKviewIconPath(name)).toBe(KVIEW_ICON_PATHS[name]);
        }
    });

    it('resolves every legacy alias and unknown names with the Blade fallback policy', () => {
        for (const [alias, target] of Object.entries(KVIEW_ICON_ALIASES)) {
            expect(resolveKviewIconName(alias)).toBe(target);
            expect(resolveKviewIconPath(alias)).toBe(resolveKviewIconPath(target));
        }

        expect(KVIEW_ICON_FALLBACK).toBe('external');
        expect(resolveKviewIconName('unknown-icon')).toBe('external');
        expect(resolveKviewIconPath('unknown-icon')).toBe(KVIEW_ICON_PATHS.external);
        expect(kviewIconMarkup('unknown-icon')).toContain(KVIEW_ICON_PATHS.external);
    });

    it.each(['dashboard', 'chart', 'status', 'excel'] as const)(
        'renders the %s geometry through the Vue adapter',
        (name) => {
            const wrapper = mount(KviewIcon, { props: { name } });

            expect(wrapper.get('g').element.innerHTML).toBe(normalizeSvgFragment(KVIEW_ICON_PATHS[name]));
        },
    );
});
