import { describe, it, beforeEach, afterEach, expect, vi } from 'vitest';
import { renderTemplate, resetDom } from '../utils/domFixtures.js';

const { CORE_MODULE, UI_HELPERS_MODULE, STATISTICS_MODULE } = vi.hoisted(() => ({
  CORE_MODULE: new URL('../../../static/js/core.js', import.meta.url).pathname,
  UI_HELPERS_MODULE: new URL('../../../static/js/utils/uiHelpers.js', import.meta.url).pathname,
  STATISTICS_MODULE: new URL('../../../static/js/statistics.js', import.meta.url).pathname,
}));

const appCoreInitializeMock = vi.fn();
const showToastMock = vi.fn();

vi.mock(CORE_MODULE, () => ({
  appCore: {
    initialize: appCoreInitializeMock,
  },
}));

vi.mock(UI_HELPERS_MODULE, () => ({
  showToast: showToastMock,
}));

describe('Statistics dashboard rendering', () => {
  beforeEach(() => {
    resetDom();
    appCoreInitializeMock.mockResolvedValue();
    showToastMock.mockReset();
    globalThis.Chart = undefined;
  });

  afterEach(() => {
    delete window.statsManager;
  });

  it('hydrates dashboard panels with fetched data and wires tab interactions', async () => {
    renderTemplate('statistics.html');

    const dataset = {
      '/api/lm/stats/collection-overview': {
        data: {
          total_models: 4,
          total_size: 4096,
          total_generations: 200,
          lora_count: 2,
          checkpoint_count: 1,
          embedding_count: 1,
          unused_loras: 1,
          unused_checkpoints: 0,
          unused_embeddings: 0,
          lora_size: 2048,
          checkpoint_size: 1024,
          embedding_size: 1024,
        },
      },
      '/api/lm/stats/usage-analytics': {
        data: {
          top_loras: [
            { name: 'Lora A', base_model: 'SDXL', folder: 'loras', usage_count: 10 },
          ],
          top_checkpoints: [
            { name: 'Checkpoint A', base_model: 'SDXL', folder: 'checkpoints', usage_count: 5 },
          ],
          top_embeddings: [
            { name: 'Embedding A', base_model: 'SDXL', folder: 'embeddings', usage_count: 7 },
          ],
          usage_timeline: [
            { date: '2024-01-01', lora_usage: 5, checkpoint_usage: 3, embedding_usage: 2 },
          ],
        },
      },
      '/api/lm/stats/base-model-distribution': {
        data: {
          loras: { SDXL: 2 },
          checkpoints: { SDXL: 1 },
          embeddings: { SDXL: 1 },
        },
      },
      '/api/lm/stats/tag-analytics': {
        data: {
          top_tags: [
            { tag: 'anime', count: 5 },
            { tag: 'photo', count: 3 },
          ],
          total_unique_tags: 2,
        },
      },
      '/api/lm/stats/storage-analytics': {
        data: {
          loras: [
            { name: 'Lora A', base_model: 'SDXL', size: 2048, usage_count: 10 },
          ],
          checkpoints: [
            { name: 'Checkpoint A', base_model: 'SDXL', size: 1024, usage_count: 5 },
          ],
          embeddings: [],
        },
      },
      '/api/lm/stats/insights': {
        data: {
          insights: [
            {
              type: 'info',
              title: 'Balance usage',
              description: 'Redistribute usage across models.',
              suggestion: 'Try lesser-used checkpoints.',
            },
          ],
        },
      },
      '/api/lm/stats/model-usage-list?type=lora&sort=desc&offset=0&limit=50': {
        success: true,
        data: {
          items: [
            { name: 'Lora A', base_model: 'SDXL', folder: 'loras', usage_count: 10, preview_url: '' },
          ],
          total: 1,
        },
      },
      '/api/lm/stats/model-usage-list?type=checkpoint&sort=desc&offset=0&limit=50': {
        success: true,
        data: {
          items: [
            { name: 'Checkpoint A', base_model: 'SDXL', folder: 'checkpoints', usage_count: 5, preview_url: '' },
          ],
          total: 1,
        },
      },
      '/api/lm/stats/model-usage-list?type=embedding&sort=desc&offset=0&limit=50': {
        success: true,
        data: {
          items: [
            { name: 'Embedding A', base_model: 'SDXL', folder: 'embeddings', usage_count: 7, preview_url: '' },
          ],
          total: 1,
        },
      },
    };

    const { StatisticsManager } = await import(STATISTICS_MODULE);
    const manager = new StatisticsManager();
    const refreshSpy = vi.spyOn(manager, 'refreshChartsInPanel');
    vi.spyOn(manager, 'fetchData').mockImplementation((endpoint) => Promise.resolve(dataset[endpoint]));

    await manager.initialize();

    expect(manager.initialized).toBe(true);
    expect(document.querySelectorAll('.metric-card').length).toBeGreaterThan(0);
    expect(document.querySelector('#topLorasList .model-item')).not.toBeNull();
    expect(document.querySelector('#tagCloud').textContent).toContain('anime');
    expect(document.querySelector('#insightsList .insight-card')).not.toBeNull();

    const usageButton = document.querySelector('.tab-button[data-tab="usage"]');
    usageButton.click();

    expect(refreshSpy).toHaveBeenCalledWith('usage');
    expect(document.getElementById('usage-panel').classList.contains('active')).toBe(true);
    expect(document.querySelector('.tab-button.active').dataset.tab).toBe('usage');
  });

  it('surfaces an error toast when statistics data fails to load', async () => {
    const { StatisticsManager } = await import(STATISTICS_MODULE);
    const manager = new StatisticsManager();
    vi.spyOn(manager, 'fetchData').mockRejectedValue(new Error('unavailable'));

    await manager.loadAllData();

    expect(showToastMock).toHaveBeenCalledWith('toast.general.statisticsLoadFailed', {}, 'error');
  });
});
