import { app, BrowserWindow, ipcMain, dialog } from 'electron';
import { fileURLToPath } from 'url';
import { dirname, join, resolve } from 'path';
import { existsSync, readFileSync, writeFile, writeFileSync } from 'fs';
import pkg from 'electron-updater';

const { autoUpdater } = pkg;

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

function getCarOptionsPath() {
  return app.isPackaged
    ? join(process.resourcesPath, 'carOptions.json')
    : resolve(__dirname, '..', 'src', 'frontend', 'carOptions.json');
}

function getSharedCarsPath() {
  return join(getDefaultCarsFolder(), 'shared-cars.json');
}

function getSettingsPath() {
  return join(app.getPath('userData'), 'kenteken-settings.json');
}

function getDefaultCarsFolder() {
  return app.isPackaged
    ? app.getPath('userData')
    : resolve(__dirname, '..');
}

function normalizeCarsFolder(folder) {
  if (!folder || typeof folder !== 'string') {
    return '';
  }
  if (!existsSync(folder)) {
    return '';
  }
  return folder;
}

function loadSettings() {
  // Persist the chosen cars folder so users can keep using the same location.
  try {
    const raw = readFileSync(getSettingsPath(), 'utf-8');
    const parsed = JSON.parse(raw);
    const carsFolder = normalizeCarsFolder(parsed?.carsFolder);
    return { carsFolder };
  } catch {
    return { carsFolder: '' };
  }
}

function saveSettings(nextSettings) {
  writeFileSync(getSettingsPath(), JSON.stringify(nextSettings, null, 2));
}

function getCarsFolder() {
  return settings.carsFolder || getDefaultCarsFolder();
}

function setCarsFolder(folder) {
  const normalized = normalizeCarsFolder(folder);
  settings.carsFolder = normalized;
  saveSettings(settings);
  storeFile = join(getCarsFolder(), 'shared-cars.json');
}

function loadBaseCarOptions() {
  const p = getCarOptionsPath();
  const json = readFileSync(p, 'utf-8');
  return JSON.parse(json);
}

function createWindow() {
  const win = new BrowserWindow({
    width: 1024,
    height: 768,
    webPreferences: {
      contextIsolation: true,
      nodeIntegration: false,
      preload: join(__dirname, 'preload.cjs'),
    },
  });

  if (app.isPackaged) {
    win.loadFile(join(__dirname, '../dist/index.html'));
  } else {
    win.loadURL('http://localhost:5173');
    win.webContents.openDevTools();
  }
}

let storeFile;
let cars = [];
let saveTimer;
let settings = { carsFolder: '' };

function loadCars() {
  try {
    const data = JSON.parse(readFileSync(storeFile, 'utf-8'));
    if (!Array.isArray(data)) throw new Error('Invalid data');
    if (
      !data.every(
        (c) =>
          typeof c.name === 'string' &&
          typeof c.width === 'number' &&
          typeof c.height === 'number'
      )
    ) {
      throw new Error('Invalid schema');
    }
    cars = data;
  } catch {
    cars = loadBaseCarOptions();
    saveCars(cars, true);
  }
  return cars;
}

function saveCars(newCars, immediate = false) {
  cars = newCars;
  const write = () =>
    writeFile(storeFile, JSON.stringify(cars, null, 2), () => {});
  if (immediate) {
    write();
  } else {
    clearTimeout(saveTimer);
    saveTimer = setTimeout(write, 250);
  }
}

ipcMain.handle('cars:load', () => loadCars());
ipcMain.handle('cars:save', (_e, newCars) => {
  saveCars(newCars);
  return cars;
});
ipcMain.handle('cars:folder:get', () => getCarsFolder());
ipcMain.handle('cars:folder:select', async () => {
  const result = await dialog.showOpenDialog({
    properties: ['openDirectory', 'createDirectory'],
  });
  if (result.canceled || !result.filePaths?.[0]) {
    return { canceled: true, folder: getCarsFolder(), cars };
  }
  setCarsFolder(result.filePaths[0]);
  const updatedCars = loadCars();
  return { canceled: false, folder: getCarsFolder(), cars: updatedCars };
});
ipcMain.handle('cars:folder:reset', () => {
  settings.carsFolder = '';
  saveSettings(settings);
  storeFile = getSharedCarsPath();
  const updatedCars = loadCars();
  return { folder: getCarsFolder(), cars: updatedCars };
});

app.whenReady().then(() => {
  settings = loadSettings();
  storeFile = settings.carsFolder
    ? join(getCarsFolder(), 'shared-cars.json')
    : getSharedCarsPath();
  loadCars();
  createWindow();

  try {
    autoUpdater.checkForUpdatesAndNotify();
  } catch (e) {
    // fail silently
  }

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

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