import { Injector } from '@angular/core';
import type { ElectronApi } from '../../../core/platform/electron/electron-api.models';
import { ElectronBridgeService } from '../../../core/platform/electron/electron-bridge.service';
import type { TojuPluginManifest } from '../../../shared-kernel';
import { LocalPluginDiscoveryService } from './local-plugin-discovery.service';

const TEST_PLUGIN_MANIFEST = createTestPluginManifest();

describe('LocalPluginDiscoveryService', () => {
  let electronApi: ElectronApi | null;

  beforeEach(() => {
    electronApi = null;
  });

  it('returns a safe empty result outside Electron', async () => {
    const service = createDiscoveryService(() => electronApi);

    expect(service.isAvailable).toBe(false);
    await expect(service.getPluginsPath()).resolves.toBeNull();
    await expect(service.discoverManifests()).resolves.toEqual({
      errors: [],
      plugins: [],
      pluginsPath: ''
    });
  });

  it('maps Electron discovery results into plugin runtime models', async () => {
    electronApi = {
      getLocalPluginsPath: vi.fn(async () => '/plugins'),
      listLocalPluginManifests: vi.fn(async () => ({
        errors: [],
        plugins: [
          {
            discoveredAt: 1,
            entrypointPath: '/plugins/api-test-plugin/dist/main.js',
            manifest: TEST_PLUGIN_MANIFEST,
            manifestPath: '/plugins/api-test-plugin/toju-plugin.json',
            pluginRoot: '/plugins/api-test-plugin',
            readmePath: '/plugins/api-test-plugin/README.md'
          }
        ],
        pluginsPath: '/plugins'
      }))
    } as Partial<ElectronApi> as ElectronApi;

    const service = createDiscoveryService(() => electronApi);

    expect(service.isAvailable).toBe(true);
    await expect(service.getPluginsPath()).resolves.toBe('/plugins');
    await expect(service.discoverManifests()).resolves.toEqual({
      errors: [],
      plugins: [
        {
          discoveredAt: 1,
          entrypointPath: '/plugins/api-test-plugin/dist/main.js',
          manifest: TEST_PLUGIN_MANIFEST,
          manifestPath: '/plugins/api-test-plugin/toju-plugin.json',
          pluginRoot: '/plugins/api-test-plugin',
          readmePath: '/plugins/api-test-plugin/README.md'
        }
      ],
      pluginsPath: '/plugins'
    });
  });
});

function createDiscoveryService(readElectronApi: () => ElectronApi | null): LocalPluginDiscoveryService {
  const injector = Injector.create({
    providers: [
      LocalPluginDiscoveryService,
      {
        provide: ElectronBridgeService,
        useValue: {
          get isAvailable(): boolean {
            return readElectronApi() !== null;
          },
          getApi: vi.fn(() => readElectronApi())
        }
      }
    ]
  });

  return injector.get(LocalPluginDiscoveryService);
}

function createTestPluginManifest(): TojuPluginManifest {
  return {
    apiVersion: '1.0.0',
    capabilities: [
      'storage.serverData.read',
      'storage.serverData.write',
      'events.server.publish'
    ],
    compatibility: {
      minimumTojuVersion: '1.0.0'
    },
    description: 'Fixture plugin used by automated tests for plugin support APIs.',
    entrypoint: './dist/main.js',
    events: [
      {
        direction: 'serverRelay',
        eventName: 'e2e:relay',
        maxPayloadBytes: 2048,
        scope: 'server'
      }
    ],
    id: 'e2e.plugin-api',
    kind: 'client',
    schemaVersion: 1,
    title: 'E2E Plugin API Fixture',
    version: '1.0.0'
  };
}
