const { app, BrowserWindow, ipcMain, dialog } = require("electron");
const path = require("path");
const fs = require("fs");
const { execFileSync } = require("child_process");
const { initStore } = require("./store");
const { TelegramManager } = require("./telegram");
const { Scheduler } = require("./scheduler");
const { TaskRunner } = require("./taskRunner");

let mainWindow;
let store;
let telegram;
let scheduler;
const taskRunners = new Map();

const filterTaskRolesByAccounts = (taskId, roles, accounts) => {
  const accountMap = new Map(accounts.map((acc) => [acc.id, acc]));
  const filtered = [];
  let removedMissing = 0;
  let removedError = 0;
  roles.forEach((row) => {
    const account = accountMap.get(row.account_id);
    if (!account) {
      removedMissing += 1;
      return;
    }
    if (account.status && account.status !== "ok") {
      removedError += 1;
      return;
    }
    filtered.push({
      accountId: row.account_id,
      roleMonitor: Boolean(row.role_monitor),
      roleInvite: Boolean(row.role_invite)
    });
  });
  if (removedMissing || removedError) {
    store.setTaskAccountRoles(taskId, filtered);
  }
  return { filtered, removedMissing, removedError };
};

const startTaskWithChecks = async (id) => {
  const task = store.getTask(id);
  if (!task) return { ok: false, error: "Task not found" };
  const competitors = store.listTaskCompetitors(id).map((row) => row.link);
  const taskAccounts = store.listTaskAccounts(id);
  const existingAccounts = store.listAccounts();
  const filteredResult = filterTaskRolesByAccounts(id, taskAccounts, existingAccounts);
  const filteredRoles = filteredResult.filtered;
  const inviteIds = filteredRoles.filter((row) => row.roleInvite).map((row) => row.accountId);
  const monitorIds = filteredRoles.filter((row) => row.roleMonitor).map((row) => row.accountId);
  if (!inviteIds.length) {
    return { ok: false, error: "Нет аккаунтов с ролью инвайта." };
  }
  if (!monitorIds.length) {
    return { ok: false, error: "Нет аккаунтов с ролью мониторинга." };
  }
  const accessCheck = await telegram.checkGroupAccess(competitors, task.our_group);
  if (accessCheck && accessCheck.ok) {
    const ourAccess = accessCheck.result.find((item) => item.type === "our");
    if (ourAccess && !ourAccess.ok) {
      return { ok: false, error: `Нет доступа к нашей группе: ${ourAccess.details || ourAccess.value}` };
    }
  }
  const inviteAccess = await telegram.checkInvitePermissions(task, inviteIds);
  if (inviteAccess && inviteAccess.ok) {
    store.setTaskInviteAccess(id, inviteAccess.result || []);
  } else if (inviteAccess && inviteAccess.error) {
    return { ok: false, error: inviteAccess.error };
  }

  let runner = taskRunners.get(id);
  if (!runner) {
    runner = new TaskRunner(store, telegram, task);
    taskRunners.set(id, runner);
  } else {
    runner.task = task;
  }
  await runner.start();
  const warnings = [];
  if (accessCheck && accessCheck.ok) {
    const competitorIssues = accessCheck.result.filter((item) => item.type === "competitor" && !item.ok);
    if (competitorIssues.length) {
      warnings.push(`Нет доступа к ${competitorIssues.length} группе(ам) конкурентов.`);
    }
  }
  if (inviteAccess && inviteAccess.ok) {
    const missingSessions = (inviteAccess.result || []).filter((row) => !row.ok || row.reason === "Сессия не подключена");
    if (missingSessions.length) {
      warnings.push(`Сессии не подключены: ${missingSessions.length} аккаунт(ов).`);
    }
    const noRights = (inviteAccess.result || []).filter((row) => !row.canInvite);
    if (noRights.length) {
      warnings.push(`Нет прав инвайта у ${noRights.length} аккаунт(ов).`);
    }
  }
  if (filteredResult.removedError) {
    warnings.push(`Отключены аккаунты с ошибкой: ${filteredResult.removedError}.`);
  }
  if (filteredResult.removedMissing) {
    warnings.push(`Удалены отсутствующие аккаунты: ${filteredResult.removedMissing}.`);
  }
  return { ok: true, warnings };
};

function createWindow() {
  const iconPath = path.join(__dirname, "..", "..", "resources", "icon.png");
  mainWindow = new BrowserWindow({
    width: 1200,
    height: 800,
    icon: iconPath,
    webPreferences: {
      preload: path.join(__dirname, "preload.js"),
      contextIsolation: true,
      nodeIntegration: false
    }
  });

  const devUrl = process.env.VITE_DEV_SERVER_URL || "http://127.0.0.1:5173";
  if (app.isPackaged) {
    mainWindow.loadFile(path.join(__dirname, "..", "..", "dist", "index.html"));
  } else {
    mainWindow.loadURL(devUrl);
  }
}

async function bootstrap() {
  store = initStore(app.getPath("userData"));
  telegram = new TelegramManager(store);
  try {
    await telegram.init();
  } catch (error) {
    console.error("Failed to initialize Telegram clients:", error);
  }
  scheduler = new Scheduler(store, telegram);
}

app.whenReady().then(async () => {
  await bootstrap();
  createWindow();

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

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

ipcMain.handle("settings:get", () => store.getSettings());
ipcMain.handle("settings:save", (_event, settings) => store.saveSettings(settings));

ipcMain.handle("accounts:list", () => store.listAccounts());
ipcMain.handle("accounts:resetCooldown", async (_event, accountId) => {
  store.clearAccountCooldown(accountId);
  store.addAccountEvent(accountId, "", "manual_reset", "Cooldown reset by user");
  return { ok: true };
});
ipcMain.handle("accounts:delete", async (_event, accountId) => {
  await telegram.removeAccount(accountId);
  store.deleteAccount(accountId);
  store.addAccountEvent(accountId, "", "delete", "Account deleted by user");
  return { ok: true };
});
ipcMain.handle("db:clear", async () => {
  for (const runner of taskRunners.values()) {
    runner.stop();
  }
  taskRunners.clear();
  const accounts = store.listAccounts();
  for (const account of accounts) {
    await telegram.removeAccount(account.id);
  }
  store.clearAllData();
  return { ok: true };
});
ipcMain.handle("accounts:startLogin", async (_event, payload) => {
  const result = await telegram.startLogin(payload);
  return result;
});
ipcMain.handle("accounts:completeLogin", async (_event, payload) => {
  const result = await telegram.completeLogin(payload);
  return result;
});

ipcMain.handle("accounts:importTdata", async (_event, payload) => {
  const { canceled, filePaths } = await dialog.showOpenDialog({
    title: "Выберите папку tdata",
    properties: ["openDirectory", "multiSelections"]
  });
  if (canceled || !filePaths || !filePaths.length) return { ok: false, canceled: true };

  const platformDir = process.platform === "win32" ? "win" : "mac";
  const binaryName = process.platform === "win32" ? "tgconvertor.exe" : "tgconvertor";
  const devBinary = path.join(__dirname, "..", "..", "resources", "converter", platformDir, binaryName);
  const packagedBinary = path.join(process.resourcesPath, "converter", platformDir, binaryName);
  const binaryPath = app.isPackaged ? packagedBinary : devBinary;

  if (!fs.existsSync(binaryPath)) {
    return { ok: false, error: "Встроенный конвертер не найден. Соберите его через scripts/build-converter.*" };
  }

  const imported = [];
  const failed = [];
  const skipped = [];
  const assignedIds = [];

  for (const chosenPath of filePaths) {
    let tdataPath = chosenPath;
    const tdataCandidate = path.join(tdataPath, "tdata");
    if (fs.existsSync(tdataCandidate) && fs.lstatSync(tdataCandidate).isDirectory()) {
      tdataPath = tdataCandidate;
    }
    if (path.basename(tdataPath) !== "tdata") {
      failed.push({ path: chosenPath, error: "Нужна папка tdata или папка с вложенной tdata." });
      continue;
    }

    let output = "";
    try {
      output = execFileSync(binaryPath, [tdataPath], { encoding: "utf8" });
    } catch (error) {
      failed.push({ path: chosenPath, error: "Не удалось запустить встроенный конвертер tdata." });
      continue;
    }

    const lines = output.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
    const candidate = lines.find((line) => line.length > 50) || lines[lines.length - 1];
    if (!candidate) {
      failed.push({ path: chosenPath, error: "Не удалось получить строку сессии из tdata." });
      continue;
    }

    try {
      const result = await telegram.importTdataSession({
        sessionString: candidate,
        apiId: payload && payload.apiId,
        apiHash: payload && payload.apiHash
      });
      if (!result.ok) {
        if (result.error === "DUPLICATE_ACCOUNT") {
          skipped.push({ path: chosenPath, reason: "Дубликат", accountId: result.accountId });
          if (result.accountId) assignedIds.push(result.accountId);
          continue;
        }
        failed.push({ path: chosenPath, error: result.error || "Ошибка импорта" });
        continue;
      }
      imported.push({ path: chosenPath, accountId: result.accountId });
      if (result.accountId) assignedIds.push(result.accountId);
    } catch (error) {
      failed.push({ path: chosenPath, error: error.message || String(error) });
    }
  }

  if (payload && payload.taskId && assignedIds.length) {
    const task = store.getTask(payload.taskId);
    if (task) {
      const existing = store.listTaskAccounts(payload.taskId).map((row) => row.account_id);
      const merged = Array.from(new Set([...(existing || []), ...assignedIds]));
      store.setTaskAccounts(payload.taskId, merged);
    }
  }

  return { ok: true, imported, skipped, failed };
});

ipcMain.handle("logs:list", (_event, payload) => {
  if (payload && typeof payload === "object") {
    return store.listLogs(payload.limit || 100, payload.taskId);
  }
  return store.listLogs(payload || 100);
});
ipcMain.handle("invites:list", (_event, payload) => {
  if (payload && typeof payload === "object") {
    return store.listInvites(payload.limit || 200, payload.taskId);
  }
  return store.listInvites(payload || 200);
});
ipcMain.handle("logs:clear", (_event, taskId) => {
  store.clearLogs(taskId);
  return { ok: true };
});
ipcMain.handle("invites:clear", (_event, taskId) => {
  store.clearInvites(taskId);
  return { ok: true };
});
ipcMain.handle("queue:clear", (_event, taskId) => {
  store.clearQueue(taskId);
  return { ok: true };
});

ipcMain.handle("tasks:list", () => store.listTasks());
ipcMain.handle("tasks:get", (_event, id) => {
  const task = store.getTask(id);
  if (!task) return null;
  return {
    task,
    competitors: store.listTaskCompetitors(id).map((row) => row.link),
    accountIds: store.listTaskAccounts(id).map((row) => row.account_id),
    accountRoles: store.listTaskAccounts(id).map((row) => ({
      accountId: row.account_id,
      roleMonitor: Boolean(row.role_monitor),
      roleInvite: Boolean(row.role_invite)
    }))
  };
});
ipcMain.handle("tasks:save", (_event, payload) => {
  const taskId = store.saveTask(payload.task);
  store.setTaskCompetitors(taskId, payload.competitors || []);
  if (payload.accountRoles && payload.accountRoles.length) {
    store.setTaskAccountRoles(taskId, payload.accountRoles);
  } else {
    store.setTaskAccounts(taskId, payload.accountIds || []);
  }
  return { ok: true, taskId };
});
ipcMain.handle("tasks:delete", (_event, id) => {
  const runner = taskRunners.get(id);
  if (runner) {
    runner.stop();
    taskRunners.delete(id);
  }
  store.deleteTask(id);
  return { ok: true };
});
ipcMain.handle("tasks:start", async (_event, id) => {
  return startTaskWithChecks(id);
});
ipcMain.handle("tasks:stop", (_event, id) => {
  const runner = taskRunners.get(id);
  if (runner) {
    runner.stop();
    taskRunners.delete(id);
  }
  return { ok: true };
});
ipcMain.handle("tasks:accountAssignments", () => {
  return store.listAllTaskAccounts();
});
ipcMain.handle("tasks:appendAccounts", (_event, payload) => {
  if (!payload || !payload.taskId) return { ok: false, error: "Task not found" };
  const task = store.getTask(payload.taskId);
  if (!task) return { ok: false, error: "Task not found" };
  const existingRows = store.listTaskAccounts(payload.taskId);
  const existing = new Map(existingRows.map((row) => [
    row.account_id,
    { accountId: row.account_id, roleMonitor: Boolean(row.role_monitor), roleInvite: Boolean(row.role_invite) }
  ]));
  (payload.accountIds || []).forEach((accountId) => {
    if (!existing.has(accountId)) {
      existing.set(accountId, { accountId, roleMonitor: true, roleInvite: true });
    }
  });
  (payload.accountRoles || []).forEach((item) => {
    existing.set(item.accountId, {
      accountId: item.accountId,
      roleMonitor: Boolean(item.roleMonitor),
      roleInvite: Boolean(item.roleInvite)
    });
  });
  const merged = Array.from(existing.values());
  store.setTaskAccountRoles(payload.taskId, merged);
  return { ok: true, accountIds: merged.map((item) => item.accountId) };
});
ipcMain.handle("tasks:removeAccount", (_event, payload) => {
  if (!payload || !payload.taskId || !payload.accountId) {
    return { ok: false, error: "Task not found" };
  }
  const task = store.getTask(payload.taskId);
  if (!task) return { ok: false, error: "Task not found" };
  const existing = store.listTaskAccounts(payload.taskId)
    .filter((row) => row.account_id !== payload.accountId)
    .map((row) => ({
      accountId: row.account_id,
      roleMonitor: Boolean(row.role_monitor),
      roleInvite: Boolean(row.role_invite)
    }));
  store.setTaskAccountRoles(payload.taskId, existing);
  return { ok: true, accountIds: existing.map((item) => item.accountId) };
});
ipcMain.handle("tasks:startAll", async () => {
  const tasks = store.listTasks();
  let started = 0;
  let skipped = 0;
  const errors = [];
  for (const task of tasks) {
    if (!task.enabled) {
      skipped += 1;
      continue;
    }
    try {
      const result = await startTaskWithChecks(task.id);
      if (!result.ok) {
        errors.push({ id: task.id, error: result.error || "start failed" });
        continue;
      }
      started += 1;
    } catch (error) {
      errors.push({ id: task.id, error: error.message || String(error) });
    }
  }
  return { ok: errors.length === 0, started, skipped, errors };
});
ipcMain.handle("tasks:stopAll", () => {
  let stopped = 0;
  for (const [id, runner] of taskRunners.entries()) {
    runner.stop();
    taskRunners.delete(id);
    stopped += 1;
  }
  return { ok: true, stopped };
});
ipcMain.handle("tasks:status", (_event, id) => {
  const runner = taskRunners.get(id);
  const queueCount = store.getPendingCount(id);
  const dailyUsed = store.countInvitesToday(id);
  const task = store.getTask(id);
  const monitorInfo = telegram.getTaskMonitorInfo(id);
  const warnings = [];
  const readiness = { ok: true, reasons: [] };
  if (task) {
    const accountRows = store.listTaskAccounts(id);
    const accounts = store.listAccounts();
    const accountsById = new Map(accounts.map((acc) => [acc.id, acc]));
    if (runner && runner.isRunning()) {
      const sanitized = filterTaskRolesByAccounts(id, accountRows, accounts);
      if (sanitized.removedError || sanitized.removedMissing) {
        warnings.push(`Авто-синхронизация ролей: удалено ${sanitized.removedMissing + sanitized.removedError} аккаунт(ов).`);
      }
      if (!sanitized.filtered.length) {
        warnings.push("Задача остановлена: нет доступных аккаунтов.");
        runner.stop();
      }
    }
    const inviteRows = accountRows.filter((row) => row.role_invite);
    const monitorRows = accountRows.filter((row) => row.role_monitor);
    if (!inviteRows.length) {
      readiness.ok = false;
      readiness.reasons.push("Нет аккаунтов с ролью инвайта.");
    }
    if (!monitorRows.length) {
      readiness.ok = false;
      readiness.reasons.push("Нет аккаунтов с ролью мониторинга.");
    }
    if (task.require_same_bot_in_both) {
      const hasSame = accountRows.some((row) => row.role_monitor && row.role_invite);
      if (!hasSame) {
        warnings.push("Режим “один бот в обоих группах” включен, но нет аккаунта с обеими ролями.");
        readiness.ok = false;
        readiness.reasons.push("Нет аккаунта с двумя ролями в режиме “один бот”.");
      }
    }
    const allAssignments = store.listAllTaskAccounts();
    const accountTaskMap = new Map();
    allAssignments.forEach((row) => {
      if (!accountTaskMap.has(row.account_id)) accountTaskMap.set(row.account_id, new Set());
      accountTaskMap.get(row.account_id).add(row.task_id);
    });
    const seen = new Set();
    accountRows.forEach((row) => {
      const tasksForAccount = accountTaskMap.get(row.account_id);
      if (tasksForAccount && tasksForAccount.size > 1 && !seen.has(row.account_id)) {
        seen.add(row.account_id);
        const account = accountsById.get(row.account_id);
        const label = account ? (account.phone || account.user_id || row.account_id) : row.account_id;
        warnings.push(`Аккаунт ${label} используется в ${tasksForAccount.size} задачах. Лимиты действий/групп общие.`);
      }
    });

    if (inviteRows.length) {
      const inviteAccounts = inviteRows.map((row) => accountsById.get(row.account_id)).filter(Boolean);
      const badSessions = inviteAccounts.filter((acc) => acc.status && acc.status !== "ok");
      if (badSessions.length) {
        readiness.ok = false;
        readiness.reasons.push(`Есть аккаунты с ошибкой сессии: ${badSessions.length}.`);
      }
    }

    if (runner && runner.isRunning() && queueCount === 0) {
      if (!monitorInfo || !monitorInfo.monitoring) {
        warnings.push("Очередь пуста: мониторинг не активен.");
      } else if (!monitorInfo.groups || monitorInfo.groups.length === 0) {
        warnings.push("Очередь пуста: нет групп в мониторинге.");
      } else if (!monitorInfo.lastMessageAt) {
        warnings.push("Очередь пуста: новых сообщений пока нет.");
      } else {
        warnings.push(`Очередь пуста: последнее сообщение ${monitorInfo.lastMessageAt}.`);
      }
    }

    if (task.our_group && (task.our_group.includes("joinchat/") || task.our_group.includes("t.me/+"))) {
      warnings.push("Целевая группа указана по инвайт-ссылке — доступ может быть ограничен.");
    }

    if (task.task_invite_access) {
      try {
        const parsed = JSON.parse(task.task_invite_access);
        if (Array.isArray(parsed) && parsed.length) {
          const total = parsed.length;
          const canInvite = parsed.filter((row) => row.canInvite).length;
          const disconnected = parsed.filter((row) => row.reason === "Сессия не подключена").length;
          const isChannel = parsed.some((row) => row.targetType === "channel");
          const checkedAt = task.task_invite_access_at || "";
          warnings.push(`Права инвайта: ${canInvite}/${total} аккаунтов могут добавлять.${checkedAt ? ` Проверка: ${checkedAt}.` : ""}`);
          if (disconnected) {
            warnings.push(`Сессия не подключена: ${disconnected} аккаунт(ов).`);
          }
          if (isChannel) {
            warnings.push("Цель — канал: добавлять участников могут только админы.");
          }
          if (canInvite === 0) {
            readiness.ok = false;
            readiness.reasons.push("Нет аккаунтов с правами инвайта.");
          }
        }
      } catch (error) {
        // ignore parsing errors
      }
    }
  }
  return {
    running: runner ? runner.isRunning() : false,
    queueCount,
    dailyUsed,
    dailyLimit: task ? task.daily_limit : 0,
    dailyRemaining: task ? Math.max(0, Number(task.daily_limit || 0) - dailyUsed) : 0,
    monitorInfo,
    nextRunAt: runner ? runner.getNextRunAt() : "",
    nextInviteAccountId: runner ? runner.getNextInviteAccountId() : 0,
    lastInviteAccountId: runner ? runner.getLastInviteAccountId() : 0,
    pendingStats: store.getPendingStats(id),
    warnings,
    readiness
  };
});

ipcMain.handle("tasks:parseHistory", async (_event, id) => {
  const task = store.getTask(id);
  if (!task) return { ok: false, error: "Task not found" };
  const competitors = store.listTaskCompetitors(id).map((row) => row.link);
  const accounts = store.listTaskAccounts(id).map((row) => row.account_id);
  return telegram.parseHistoryForTask(task, competitors, accounts);
});

ipcMain.handle("tasks:checkAccess", async (_event, id) => {
  const task = store.getTask(id);
  if (!task) return { ok: false, error: "Task not found" };
  const competitors = store.listTaskCompetitors(id).map((row) => row.link);
  return telegram.checkGroupAccess(competitors, task.our_group);
});

ipcMain.handle("tasks:membershipStatus", async (_event, id) => {
  const task = store.getTask(id);
  if (!task) return { ok: false, error: "Task not found" };
  const competitors = store.listTaskCompetitors(id).map((row) => row.link);
  return telegram.getMembershipStatus(competitors, task.our_group);
});

ipcMain.handle("tasks:checkInviteAccess", async (_event, id) => {
  const task = store.getTask(id);
  if (!task) return { ok: false, error: "Task not found" };
  const accountRows = store.listTaskAccounts(id).filter((row) => row.role_invite);
  const existingAccounts = store.listAccounts();
  const existingIds = new Set(existingAccounts.map((account) => account.id));
  const missing = accountRows.filter((row) => !existingIds.has(row.account_id));
  if (missing.length) {
    const filtered = accountRows
      .filter((row) => existingIds.has(row.account_id))
      .map((row) => ({
        accountId: row.account_id,
        roleMonitor: Boolean(row.role_monitor),
        roleInvite: Boolean(row.role_invite)
      }));
    store.setTaskAccountRoles(id, filtered);
  }
  const accountIds = accountRows
    .filter((row) => existingIds.has(row.account_id))
    .map((row) => row.account_id);
  const result = await telegram.checkInvitePermissions(task, accountIds);
  if (result && result.ok) {
    store.setTaskInviteAccess(id, result.result || []);
  }
  return result;
});

ipcMain.handle("tasks:groupVisibility", async (_event, id) => {
  const task = store.getTask(id);
  if (!task) return { ok: false, error: "Task not found" };
  const competitors = store.listTaskCompetitors(id).map((row) => row.link);
  const result = await telegram.getGroupVisibility(task, competitors);
  return { ok: true, result };
});

const toCsv = (rows, headers) => {
  const escape = (value) => {
    const text = value == null ? "" : String(value);
    if (text.includes("\"") || text.includes(",") || text.includes("\n")) {
      return `"${text.replace(/\"/g, "\"\"")}"`;
    }
    return text;
  };
  const lines = [headers.join(",")];
  rows.forEach((row) => {
    lines.push(headers.map((key) => escape(row[key])).join(","));
  });
  return lines.join("\n");
};

ipcMain.handle("logs:export", async (_event, taskId) => {
  const { canceled, filePath } = await dialog.showSaveDialog({
    title: "Выгрузить логи",
    defaultPath: "logs.csv"
  });
  if (canceled || !filePath) return { ok: false, canceled: true };

  const logs = store.listLogs(1000, taskId).map((log) => ({
    taskId: log.taskId,
    startedAt: log.startedAt,
    finishedAt: log.finishedAt,
    invitedCount: log.invitedCount,
    successIds: JSON.stringify(log.successIds || []),
    errors: JSON.stringify(log.errors || [])
  }));
  const csv = toCsv(logs, ["taskId", "startedAt", "finishedAt", "invitedCount", "successIds", "errors"]);
  fs.writeFileSync(filePath, csv, "utf8");
  return { ok: true, filePath };
});

ipcMain.handle("invites:export", async (_event, taskId) => {
  const { canceled, filePath } = await dialog.showSaveDialog({
    title: "Выгрузить историю инвайтов",
    defaultPath: "invites.csv"
  });
  if (canceled || !filePath) return { ok: false, canceled: true };

  const invites = store.listInvites(2000, taskId);
  const csv = toCsv(invites, [
    "taskId",
    "invitedAt",
    "userId",
    "username",
    "status",
    "error",
    "accountId",
    "accountPhone",
    "watcherAccountId",
    "watcherPhone",
    "strategy",
    "strategyMeta",
    "sourceChat"
  ]);
  fs.writeFileSync(filePath, csv, "utf8");
  return { ok: true, filePath };
});

ipcMain.handle("accounts:events", async (_event, limit) => {
  return store.listAccountEvents(limit || 200);
});

ipcMain.handle("accounts:events:clear", async () => {
  store.clearAccountEvents();
  return { ok: true };
});

ipcMain.handle("accounts:refreshIdentity", async () => {
  const accounts = store.listAccounts();
  for (const account of accounts) {
    await telegram.refreshAccountIdentity(account.id);
  }
  return { ok: true };
});

ipcMain.handle("task:start", async () => {
  const settings = store.getSettings();
  if (settings.autoJoinOurGroup) {
    await telegram.ensureJoinOurGroup(settings.ourGroup);
  }
  await telegram.joinGroupsForAllAccounts(settings.competitorGroups, settings.ourGroup, settings);
  const monitorResult = await telegram.startMonitoring(settings.competitorGroups);
  scheduler.start(settings);
  return { running: true, monitorErrors: monitorResult && monitorResult.errors ? monitorResult.errors : [] };
});

ipcMain.handle("task:stop", async () => {
  scheduler.stop();
  await telegram.stopMonitoring();
  return { running: false };
});

ipcMain.handle("status:get", () => {
  const settings = store.getSettings();
  const dailyUsed = store.countInvitesToday();
  const dailyRemaining = Math.max(0, Number(settings.dailyLimit || 0) - dailyUsed);
  const queueCount = store.getPendingCount();
  const accounts = store.listAccounts();
  const connectedSessions = telegram.getConnectedCount();
  const accountStats = accounts.map((account) => {
    const used = store.countInvitesTodayByAccount(account.id);
    const limit = Number(account.daily_limit || settings.accountDailyLimit || 0);
    const remaining = limit > 0 ? Math.max(0, limit - used) : null;
    return {
      id: account.id,
      usedToday: used,
      remainingToday: remaining,
      limit
    };
  });
  const monitorInfo = telegram.getMonitorInfo();
  return {
    running: scheduler ? scheduler.isRunning() : false,
    queueCount,
    dailyRemaining,
    dailyUsed,
    dailyLimit: Number(settings.dailyLimit || 0),
    connectedSessions,
    totalAccounts: accounts.length,
    accountStats,
    monitorInfo
  };
});

ipcMain.handle("task:parseHistory", async (_event, limit) => {
  const settings = store.getSettings();
  const result = await telegram.parseHistory(settings.competitorGroups, limit || settings.historyLimit);
  return result;
});

ipcMain.handle("accounts:membershipStatus", async () => {
  const settings = store.getSettings();
  const result = await telegram.getMembershipStatus(settings.competitorGroups, settings.ourGroup);
  return result;
});

ipcMain.handle("groups:checkAccess", async () => {
  const settings = store.getSettings();
  const result = await telegram.checkGroupAccess(settings.competitorGroups, settings.ourGroup);
  return result;
});
