import { getPanelPlugin } from '@grafana/data/test';
import { reportInteraction, setPluginImportUtils } from '@grafana/runtime';
import { type Spec as DashboardV2Spec } from '@grafana/schema/apis/dashboard.grafana.app/v2';

import nestedDashboard from '../serialization/testfiles/nested_dashboard.json';

import { getTestDashboardSceneFromSaveModel } from './test-utils';
import { trackDashboardSceneCreatedOrSaved, trackDashboardSceneLoaded } from './tracking';

jest.mock('@grafana/runtime', () => ({
  ...jest.requireActual('@grafana/runtime'),
  reportInteraction: jest.fn(),
  config: {
    ...jest.requireActual('@grafana/runtime').config,
    featureToggles: {
      dashboardNewLayouts: true,
    },
  },
  getDataSourceSrv: () => ({
    getInstanceSettings: () => {
      return { apiVersion: 'v1', meta: { multiValueFilterOperators: true } };
    },
  }),
}));

// mock useSaveDashboardMutation
jest.mock('app/features/browse-dashboards/api/browseDashboardsAPI', () => ({
  useSaveDashboardMutation: () => [() => Promise.resolve({ data: { version: 2, uid: 'new-uid' } })],
}));

setPluginImportUtils({
  importPanelPlugin: (id: string) => Promise.resolve(getPanelPlugin({})),
  getPanelPluginFromCache: (id: string) => undefined,
});

export function buildTestScene() {
  const dashboard = getTestDashboardSceneFromSaveModel(nestedDashboard as Partial<DashboardV2Spec>);
  return dashboard;
}

describe('dashboard tracking', () => {
  afterEach(() => {
    jest.clearAllMocks();
    jest.resetAllMocks();
  });

  describe('save v2 dashboard tracking', () => {
    it('should call report interaction with correct parameters when saving a new dashboard', async () => {
      const scene = buildTestScene();
      await trackDashboardSceneCreatedOrSaved(true, scene, { name: 'new dashboard', url: 'new-url' });
      expect(reportInteraction).toHaveBeenCalledWith('grafana_dashboard_created', {
        isDynamicDashboard: true,
        uid: 'dashboard-test',
        name: 'new dashboard',
        url: 'new-url',
        numPanels: 6,
        numRows: 6,
        numTabs: 4,
        conditionalRenderRules: 3,
        autoLayoutCount: 3,
        customGridLayoutCount: 2,
        panelsByDatasourceType: {
          cloudwatch: 5,
          datasource: 1,
        },
        variable_type_custom_count: 3,
        variable_type_custom_csv_count: 2,
        variable_type_custom_json_count: 1,
        variable_type_query_count: 1,
        variable_type_datasource_count: 1,
        variable_type_adhoc_count: 1,
      });
    });

    it('should include transformation and expression counts when provided', async () => {
      const scene = buildTestScene();
      await trackDashboardSceneCreatedOrSaved(true, scene, {
        name: 'new dashboard',
        url: 'new-url',
        transformation_counts: { organize: 2, reduce: 1 },
        expression_counts: { sql: 3, math: 1 },
      });
      expect(reportInteraction).toHaveBeenCalledWith('grafana_dashboard_created', {
        isDynamicDashboard: true,
        uid: 'dashboard-test',
        name: 'new dashboard',
        url: 'new-url',
        numPanels: 6,
        numRows: 6,
        numTabs: 4,
        conditionalRenderRules: 3,
        autoLayoutCount: 3,
        customGridLayoutCount: 2,
        panelsByDatasourceType: {
          cloudwatch: 5,
          datasource: 1,
        },
        variable_type_custom_count: 3,
        variable_type_custom_csv_count: 2,
        variable_type_custom_json_count: 1,
        variable_type_query_count: 1,
        variable_type_datasource_count: 1,
        variable_type_adhoc_count: 1,
        transformation_counts: { organize: 2, reduce: 1 },
        expression_counts: { sql: 3, math: 1 },
      });
    });
  });

  describe('init v2 dashboard tracking', () => {
    it('should call report interaction with correct parameters when a dashboard has been initialized', async () => {
      const scene = buildTestScene();
      trackDashboardSceneLoaded(scene, 42);
      expect(reportInteraction).toHaveBeenCalledWith('dashboards_init_dashboard_completed', {
        isDynamicDashboard: true,
        duration: 42,
        isScene: true,
        tabCount: 4,
        rowCount: 2,
        templateVariableCount: 6,
        maxNestingLevel: 3,
        panel_type_timeseries_count: 6,
        panels_count: 6,
        schemaVersion: 42,
        settings_livenow: true,
        settings_nowdelay: undefined,
        dashStructure:
          '[{"kind":"row","children":[{"kind":"row","children":[{"kind":"tab","children":[{"kind":"panel"},{"kind":"panel"},{"kind":"panel"}]},{"kind":"tab","children":[]}]},{"kind":"row","children":[{"kind":"row","children":[{"kind":"panel"}]}]}]},{"kind":"row","children":[{"kind":"row","children":[{"kind":"tab","children":[{"kind":"panel"}]},{"kind":"tab","children":[{"kind":"panel"}]}]}]}]',
        conditionalRenderRules: 3,
        autoLayoutCount: 3,
        customGridLayoutCount: 2,
        theme: undefined,
        title: 'Cloudwatch ec2 new layout',
        uid: 'dashboard-test',
        variable_type_custom_count: 3,
        variable_type_custom_csv_count: 2,
        variable_type_custom_json_count: 1,
        variable_type_query_count: 1,
        variable_type_datasource_count: 1,
        variable_type_adhoc_count: 1,
        varsWithDataSource: [
          {
            datasource: 'cloudwatch',
            type: 'query',
          },
          {
            datasource: 'opensearch',
            type: 'adhoc',
          },
          {
            datasource: 'bigquery',
            type: 'datasource',
          },
        ],
        hasEditPermissions: true,
        hasSavePermissions: true,
      });
    });
  });
});
