const { app, BrowserWindow, Menu, ipcMain } = require('electron');
const { systemPreferences } = require('electron');
const path = require('node:path');

let mainWindow;

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 900,
    height: 700,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: true,
      preload: path.join(__dirname, 'preload.js')
    }
  });

  mainWindow.loadFile('index.html');

  Menu.setApplicationMenu(Menu.buildFromTemplate([
    {
      label: '操作',
      submenu: [
        { label: '开发者工具', accelerator: 'F12', role: 'toggleDevTools' },
        { label: '刷新', accelerator: 'F5', role: 'reload' },
        { type: 'separator' },
        { label: '退出', accelerator: 'CommandOrControl+Q', role: 'quit' },
      ]
    }
  ]));
}

app.whenReady().then(() => {
  createWindow();
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit();
});

// ============================================================
// EtsBridge test infrastructure
// ============================================================

async function callArkTSFunction(name, returnType, params = []) {
  const res = await systemPreferences.callArkTSFunction(name, returnType, params);
  return res;
}

// Run a single test case and return { name, passed, expected, actual, error }
async function runTest(name, returnType, params, expectedType, expectedValue) {
  try {
    const res = await callArkTSFunction(name, returnType, params);
    const actualStr = JSON.stringify(res.value);
    const expectedStr = JSON.stringify(expectedValue);
    const passed = res.type === expectedType && actualStr === expectedStr;
    return { name, passed, expected: { type: expectedType, value: expectedValue }, actual: res, error: null };
  } catch (error) {
    return { name, passed: false, expected: { type: expectedType, value: expectedValue }, actual: null, error: error.message };
  }
}

async function runAllTests() {
  const results = [];

  // Section 1: No params + various return types
  results.push(await runTest('EtsBridge.TestReturnArrayString', 'string[]', [], 'string[]', ['ets', 'bridge', 'adapter']));
  results.push(await runTest('EtsBridge.TestReturnArrayNumber', 'number[]', [], 'number[]', [1, 2, 3]));
  results.push(await runTest('EtsBridge.TestReturnString', 'string', [], 'string', 'ets bridge adapter'));
  results.push(await runTest('EtsBridge.TestReturnNumber', 'number', [], 'number', 42));
  results.push(await runTest('EtsBridge.TestReturnBoolean', 'boolean', [], 'boolean', true));
  results.push(await runTest('EtsBridge.TestVoidReturn', 'void', [], 'void', 0));

  // Section 2: Single param + return value
  results.push(await runTest('EtsBridge.TestReturnByStringParam', 'string', ['Hello ArkTS'], 'string', 'Received param: Hello ArkTS'));
  results.push(await runTest('EtsBridge.TestReturnByNumberParam', 'number', [123456], 'number', 246912));
  results.push(await runTest('EtsBridge.TestReturnByBooleanParam', 'boolean', [true], 'boolean', false));
  results.push(await runTest('EtsBridge.TestReturnByStringArrayParam', 'string[]', [['a', 'b', 'c']], 'string[]', ['a', 'b', 'c']));
  results.push(await runTest('EtsBridge.TestReturnByNumberArrayParam', 'number[]', [[10, 20, 30]], 'number[]', [10, 20, 30]));

  // Section 3: Multiple parameters
  results.push(await runTest('EtsBridge.TestTwoParams', 'string', ['hello', 42], 'string', 'hello_42'));
  results.push(await runTest('EtsBridge.TestMultipleParams', 'string', ['test', 100, true], 'string', 'Combined: test_100_true'));
  results.push(await runTest('EtsBridge.TestVoidReturnWithParams', 'void', ['test', 100, true], 'void', 0));
  results.push(await runTest('EtsBridge.TestThreeNumbers', 'number', [10, 20, 30], 'number', 60));
  results.push(await runTest('EtsBridge.TestTwoStrings', 'string', ['Hello', ' World'], 'string', 'Hello World'));

  // Section 4: Numeric boundary / special values
  results.push(await runTest('EtsBridge.TestReturnFloat', 'number', [], 'number', 3.1415926535));
  results.push(await runTest('EtsBridge.TestReturnNegativeNumber', 'number', [], 'number', -999));
  results.push(await runTest('EtsBridge.TestReturnZero', 'number', [], 'number', 0));
  results.push(await runTest('EtsBridge.TestReturnFalse', 'boolean', [], 'boolean', false));
  results.push(await runTest('EtsBridge.TestReturnLargeNumber', 'number', [], 'number', 2147483647));

  // Section 5: Empty values / empty collections
  results.push(await runTest('EtsBridge.TestReturnEmptyString', 'string', [], 'string', ''));
  results.push(await runTest('EtsBridge.TestReturnEmptyNumberArray', 'number[]', [], 'number[]', []));
  results.push(await runTest('EtsBridge.TestReturnEmptyStringArray', 'string[]', [], 'string[]', []));
  results.push(await runTest('EtsBridge.TestReturnArrayWithEmptyStrings', 'string[]', [], 'string[]', ['', 'hello', '']));

  // Section 6: Special string content
  results.push(await runTest('EtsBridge.TestReturnChineseString', 'string', [], 'string', '你好,鸿蒙!'));
  results.push(await runTest('EtsBridge.TestReturnSpecialChars', 'string', [], 'string', 'line1\nline2\ttab "quotes" \\backslash'));
  results.push(await runTest('EtsBridge.TestEchoString', 'string', ['abc\ndef\t123'], 'string', 'abc\ndef\t123'));

  // Section 7: Large arrays
  const largeNumExpected = Array.from({ length: 100 }, (_, i) => i);
  results.push(await runTest('EtsBridge.TestReturnLargeNumberArray', 'number[]', [], 'number[]', largeNumExpected));

  const largeStrExpected = Array.from({ length: 50 }, (_, i) => `item_${i}`);
  results.push(await runTest('EtsBridge.TestReturnLargeStringArray', 'string[]', [], 'string[]', largeStrExpected));

  return results;
}

// IPC: run all tests
ipcMain.handle('run-etsbridge-tests', async () => {
  return await runAllTests();
});