import { useRef } from "react";

export default function useTaskActions({
  taskForm,
  setTaskForm,
  sanitizeTaskForm,
  taskAccountRoles,
  setTaskAccountRoles,
  selectedAccountIds,
  setSelectedAccountIds,
  accounts,
  selectedTaskId,
  selectedTaskName,
  competitorGroups,
  hasSelectedTask,
  setTaskNotice,
  showNotification,
  setAutosaveNote,
  autosaveNoteTimer,
  loadTasks,
  loadAccountAssignments,
  loadTaskStatuses,
  refreshMembership,
  checkInviteAccess,
  checkAccess,
  setLogs,
  setInvites,
  setTaskStatus,
  setSelectedTaskId,
  resetTaskForm,
  setCompetitorText,
  resetSelectedAccountIds,
  resetTaskAccountRoles,
  setFallbackList,
  setConfirmQueue,
  setAccountEvents,
  setTaskActionLoading,
  taskActionLoading,
  loadBase,
  createTask,
  setActiveTab
}) {
  const withTimeout = (promise, ms) => (
    Promise.race([
      promise,
      new Promise((_, reject) => setTimeout(() => reject(new Error("TIMEOUT")), ms))
    ])
  );

  const saveTask = async (source = "editor", options = {}) => {
    const silent = Boolean(options.silent);
    if (!window.api) {
      if (!silent) {
        showNotification("Electron API недоступен. Откройте приложение в Electron.", "error");
      }
      return;
    }
    try {
      if (!silent) {
        showNotification("Сохраняем задачу...", "info");
      }
      const nextForm = sanitizeTaskForm(taskForm);
      setTaskForm(nextForm);
      const validateLink = (value) => {
        const trimmed = String(value || "").trim();
        if (!trimmed) return false;
        if (trimmed.startsWith("@")) return true;
        if (trimmed.startsWith("https://t.me/")) return true;
        if (trimmed.startsWith("http://t.me/")) return true;
        return false;
      };
      const invalidCompetitors = competitorGroups.filter((link) => !validateLink(link));
      if (!validateLink(nextForm.ourGroup)) {
        showNotification("Наша группа должна быть ссылкой t.me или @username.", "error");
        return;
      }
      if (invalidCompetitors.length) {
        showNotification(`Некорректные ссылки конкурентов: ${invalidCompetitors.join(", ")}`, "error");
        return;
      }
      let accountRolesMap = { ...taskAccountRoles };
      let accountIds = Object.keys(accountRolesMap).map((id) => Number(id));
      if (nextForm.requireSameBotInBoth) {
        const required = Math.max(1, Number(nextForm.maxCompetitorBots || 1));
        const pool = (selectedAccountIds && selectedAccountIds.length ? selectedAccountIds : accounts.map((account) => account.id))
          .filter((id) => Number.isFinite(id));
        const chosen = pool.slice(0, required);
        accountRolesMap = {};
        chosen.forEach((accountId) => {
          const existing = accountRolesMap[accountId] || {};
          accountRolesMap[accountId] = { monitor: true, invite: true, confirm: true, inviteLimit: existing.inviteLimit || 1 };
        });
        accountIds = chosen;
        setTaskAccountRoles(accountRolesMap);
        setSelectedAccountIds(chosen);
      }
      if (nextForm.autoAssignAccounts && (!accountIds || accountIds.length === 0)) {
        accountIds = accounts.map((account) => account.id);
        accountRolesMap = {};
        accountIds.forEach((accountId) => {
          const existing = accountRolesMap[accountId] || {};
          accountRolesMap[accountId] = { monitor: true, invite: true, confirm: true, inviteLimit: existing.inviteLimit || 1 };
        });
        setTaskAccountRoles(accountRolesMap);
        setSelectedAccountIds(accountIds);
        if (accountIds.length && !silent) {
          setTaskNotice({ text: `Автоназначены аккаунты: ${accountIds.length}`, tone: "success", source });
        }
      }
      if (!accountIds.length) {
        if (!silent) {
          showNotification("Нет аккаунтов для этой задачи.", "error");
        }
        return;
      }
      const roleEntries = Object.values(accountRolesMap);
      if (roleEntries.length) {
        const hasMonitor = roleEntries.some((item) => item.monitor);
        const hasInvite = roleEntries.some((item) => item.invite);
        const hasConfirm = roleEntries.some((item) => item.confirm);
        if (!hasMonitor) {
          if (!silent) {
            showNotification("Нужен хотя бы один аккаунт с ролью мониторинга.", "error");
          }
          return;
        }
        if (!hasInvite) {
          if (!silent) {
            showNotification("Нужен хотя бы один аккаунт с ролью инвайта.", "error");
          }
          return;
        }
        if (nextForm.separateConfirmRoles && !hasConfirm) {
          if (!silent) {
            showNotification("Нужен хотя бы один аккаунт с ролью подтверждения.", "error");
          }
          return;
        }
      } else {
        const requiredAccounts = nextForm.requireSameBotInBoth
          ? Math.max(1, Number(nextForm.maxCompetitorBots || 1))
          : nextForm.separateBotRoles
            ? Math.max(1, Number(nextForm.maxCompetitorBots || 1))
              + Math.max(1, Number(nextForm.maxOurBots || 1))
              + (nextForm.separateConfirmRoles ? Math.max(1, Number(nextForm.maxConfirmBots || 1)) : 0)
            : 1;
        if (accountIds.length < requiredAccounts) {
          if (!silent) {
            showNotification(`Нужно минимум ${requiredAccounts} аккаунтов для выбранного режима.`, "error");
          }
          return;
        }
      }
      const accountRoles = Object.entries(accountRolesMap).map(([id, roles]) => ({
        accountId: Number(id),
        roleMonitor: Boolean(roles.monitor),
        roleInvite: Boolean(roles.invite),
        roleConfirm: Boolean(roles.confirm != null ? roles.confirm : roles.invite),
        inviteLimit: Number(roles.inviteLimit || 0)
      }));
      const result = await window.api.saveTask({
        task: nextForm,
        competitors: competitorGroups,
        accountIds,
        accountRoles
      });
      if (result.ok) {
        if (!silent) {
          setTaskNotice({ text: "Задача сохранена.", tone: "success", source });
        } else {
          setAutosaveNote("Автосохранено");
          if (autosaveNoteTimer.current) {
            clearTimeout(autosaveNoteTimer.current);
          }
          autosaveNoteTimer.current = setTimeout(() => {
            setAutosaveNote("");
          }, 1500);
        }
        await loadTasks();
        await loadAccountAssignments();
        setSelectedTaskId(result.taskId);
      } else {
        if (!silent) {
          showNotification(result.error || "Не удалось сохранить задачу", "error");
        }
      }
    } catch (error) {
      if (!silent) {
        showNotification(error.message || String(error), "error");
      }
    }
  };

  const deleteTask = async () => {
    if (!window.api || selectedTaskId == null) {
      return;
    }
    try {
      await window.api.deleteTask(selectedTaskId);
      setTaskNotice({ text: "Задача удалена.", tone: "success", source: "tasks" });
      const tasksData = await loadTasks();
      await loadAccountAssignments();
      if (!tasksData.length) {
        createTask();
        setActiveTab("task");
      }
    } catch (error) {
      showNotification(error.message || String(error), "error");
    }
  };

  const startTask = async (source = "sidebar") => {
    if (!window.api || selectedTaskId == null) {
      showNotification("Сначала выберите задачу.", "error");
      return;
    }
    if (taskActionLoading) return;
    setTaskActionLoading(true);
    showNotification("Запуск...", "info");
    try {
      const result = await withTimeout(window.api.startTaskById(selectedTaskId), 15000);
      if (result && result.ok) {
        setTaskNotice({ text: "Запущено.", tone: "success", source });
        if (result.warnings && result.warnings.length) {
          showNotification(`Предупреждения: ${result.warnings.join(" | ")}`, "info");
        }
        await refreshMembership("start_task");
        checkInviteAccess("auto", true);
      } else {
        showNotification(result.error || "Не удалось запустить", "error");
      }
    } catch (error) {
      const message = error.message === "TIMEOUT"
        ? "Запуск не ответил за 15 секунд. Проверьте логи/события и попробуйте снова."
        : (error.message || String(error));
      setTaskNotice({ text: message, tone: "error", source });
      showNotification(message, "error");
    } finally {
      setTaskActionLoading(false);
    }
  };

  const startAllTasks = async () => {
    if (!window.api) {
      showNotification("Electron API недоступен. Откройте приложение в Electron.", "error");
      return;
    }
    showNotification("Запускаем все задачи...", "info");
    try {
      const result = await window.api.startAllTasks();
      if (result && result.errors && result.errors.length) {
        const errorText = result.errors.map((item) => `${item.id}: ${item.error}`).join(" | ");
        showNotification(`Ошибки запуска: ${errorText}`, "error");
      }
      const tasksData = await loadTasks();
      await loadTaskStatuses(tasksData);
    } catch (error) {
      showNotification(error.message || String(error), "error");
    }
  };

  const stopTask = async (source = "sidebar") => {
    if (!window.api || selectedTaskId == null) {
      showNotification("Сначала выберите задачу.", "error");
      return;
    }
    if (taskActionLoading) return;
    if (!window.confirm(`Остановить задачу: ${selectedTaskName}?`)) {
      return;
    }
    setTaskActionLoading(true);
    showNotification("Остановка...", "info");
    try {
      await withTimeout(window.api.stopTaskById(selectedTaskId), 15000);
      setTaskNotice({ text: "Остановлено.", tone: "success", source });
    } catch (error) {
      const message = error.message === "TIMEOUT"
        ? "Остановка не ответила за 15 секунд. Проверьте логи/события и попробуйте снова."
        : (error.message || String(error));
      setTaskNotice({ text: message, tone: "error", source });
      showNotification(message, "error");
    } finally {
      setTaskActionLoading(false);
    }
  };

  const stopAllTasks = async () => {
    if (!window.api) {
      showNotification("Electron API недоступен. Откройте приложение в Electron.", "error");
      return;
    }
    if (!window.confirm("Остановить все задачи?")) {
      return;
    }
    showNotification("Останавливаем все задачи...", "info");
    try {
      await window.api.stopAllTasks();
      const tasksData = await loadTasks();
      await loadTaskStatuses(tasksData);
    } catch (error) {
      showNotification(error.message || String(error), "error");
    }
  };

  const parseHistory = async (source = "editor") => {
    if (!window.api || selectedTaskId == null) {
      showNotification("Сначала выберите задачу.", "error");
      return;
    }
    showNotification("Собираем историю...", "info");
    try {
      const result = await window.api.parseHistoryByTask(selectedTaskId);
      if (result && result.ok) {
        setTaskNotice({ text: "История добавлена в очередь.", tone: "success", source });
        if (result.errors && result.errors.length) {
          showNotification(`Ошибки истории: ${result.errors.join(" | ")}`, "error");
        }
        setLogs(await window.api.listLogs({ limit: 100, taskId: selectedTaskId }));
        setInvites(await window.api.listInvites({ limit: 200, taskId: selectedTaskId }));
        return;
      }
      const message = result.error || "Ошибка при сборе истории";
      setTaskNotice({ text: message, tone: "error", source });
      showNotification(message, "error");
    } catch (error) {
      const message = error.message || String(error);
      setTaskNotice({ text: message, tone: "error", source });
      showNotification(message, "error");
    }
  };

  const checkAll = async (source = "bar") => {
    if (!window.api || selectedTaskId == null) {
      showNotification("Сначала выберите задачу.", "error");
      return;
    }
    showNotification("Проверяем всё: доступ, права, участие...", "info");
    await checkAccess(source, true);
    await checkInviteAccess(source, true);
    await refreshMembership(source, true);
    setTaskNotice({ text: "Проверка завершена.", tone: "success", source });
  };

  const joinGroupsForTask = async (source = "editor") => {
    if (!window.api || selectedTaskId == null) {
      showNotification("Сначала выберите задачу.", "error");
      return;
    }
    try {
      showNotification("Отправляем заявки на вступление...", "info");
      const result = await window.api.joinGroupsByTask(selectedTaskId);
      if (!result || !result.ok) {
        showNotification(result?.error || "Не удалось отправить заявки", "error");
        return;
      }
      setTaskNotice({ text: "Заявки на вступление отправлены.", tone: "success", source });
      await refreshMembership("join_groups");
    } catch (error) {
      showNotification(error.message || String(error), "error");
    }
  };

  const clearLogs = async (source = "editor") => {
    if (!window.api || selectedTaskId == null) {
      showNotification("Сначала выберите задачу.", "error");
      return;
    }
    try {
      await window.api.clearLogs(selectedTaskId);
      setLogs([]);
      setTaskNotice({ text: "Логи очищены.", tone: "success", source });
    } catch (error) {
      showNotification(error.message || String(error), "error");
    }
  };

  const clearInvites = async (source = "editor") => {
    if (!window.api || selectedTaskId == null) {
      showNotification("Сначала выберите задачу.", "error");
      return;
    }
    try {
      await window.api.clearInvites(selectedTaskId);
      setInvites([]);
      setTaskNotice({ text: "История инвайтов очищена.", tone: "success", source });
    } catch (error) {
      showNotification(error.message || String(error), "error");
    }
  };

  const clearAccountEvents = async () => {
    if (!window.api) {
      showNotification("Electron API недоступен. Откройте приложение в Electron.", "error");
      return;
    }
    try {
      await window.api.clearAccountEvents();
      setAccountEvents([]);
      showNotification("События очищены.", "success");
    } catch (error) {
      showNotification(error.message || String(error), "error");
    }
  };

  const exportLogs = async (source = "editor") => {
    if (!window.api || selectedTaskId == null) {
      showNotification("Сначала выберите задачу.", "error");
      return;
    }
    try {
      const result = await window.api.exportLogs(selectedTaskId);
      if (result && result.canceled) return;
      setTaskNotice({ text: `Логи выгружены: ${result.filePath}`, tone: "success", source });
    } catch (error) {
      showNotification(error.message || String(error), "error");
    }
  };

  const exportInvites = async (source = "editor") => {
    if (!window.api || selectedTaskId == null) {
      showNotification("Сначала выберите задачу.", "error");
      return;
    }
    try {
      const result = await window.api.exportInvites(selectedTaskId);
      if (result && result.canceled) return;
      setTaskNotice({ text: `История инвайтов выгружена: ${result.filePath}`, tone: "success", source });
    } catch (error) {
      showNotification(error.message || String(error), "error");
    }
  };

  const exportProblemInvites = async (source = "editor") => {
    if (!window.api || selectedTaskId == null) {
      showNotification("Сначала выберите задачу.", "error");
      return;
    }
    try {
      const result = await window.api.exportProblemInvites(selectedTaskId);
      if (result.canceled) return;
      setTaskNotice({ text: `Проблемные инвайты выгружены: ${result.filePath}`, tone: "success", source });
    } catch (error) {
      showNotification(error.message || String(error), "error");
    }
  };

  const exportFallback = async (source = "editor") => {
    if (!window.api || selectedTaskId == null) {
      showNotification("Сначала выберите задачу.", "error");
      return;
    }
    try {
      const result = await window.api.exportFallback(selectedTaskId);
      if (result.canceled) return;
      setTaskNotice({ text: `Fallback выгружен: ${result.filePath}`, tone: "success", source });
    } catch (error) {
      showNotification(error.message || String(error), "error");
    }
  };

  const updateFallbackStatus = async (id, status) => {
    if (!window.api) return;
    try {
      await window.api.updateFallback({ id, status });
      if (selectedTaskId != null) {
        setFallbackList(await window.api.listFallback({ limit: 500, taskId: selectedTaskId }));
      }
    } catch (error) {
      showNotification(error.message || String(error), "error");
    }
  };

  const clearFallback = async (source = "editor") => {
    if (!window.api || selectedTaskId == null) {
      showNotification("Сначала выберите задачу.", "error");
      return;
    }
    try {
      await window.api.clearFallback(selectedTaskId);
      setFallbackList(await window.api.listFallback({ limit: 500, taskId: selectedTaskId }));
      setTaskNotice({ text: "Fallback очищен.", tone: "success", source });
    } catch (error) {
      showNotification(error.message || String(error), "error");
    }
  };

  const clearConfirmQueue = async (source = "editor") => {
    if (!window.api || selectedTaskId == null) {
      showNotification("Сначала выберите задачу.", "error");
      return;
    }
    try {
      await window.api.clearConfirmQueue(selectedTaskId);
      setConfirmQueue(await window.api.listConfirmQueue({ limit: 500, taskId: selectedTaskId }));
      setTaskNotice({ text: "Очередь подтверждений очищена.", tone: "success", source });
    } catch (error) {
      showNotification(error.message || String(error), "error");
    }
  };

  const clearQueue = async (source = "editor") => {
    if (!window.api || selectedTaskId == null) {
      showNotification("Сначала выберите задачу.", "error");
      return;
    }
    try {
      await window.api.clearQueue(selectedTaskId);
      const data = await window.api.taskStatus(selectedTaskId);
      setTaskStatus(data);
      setTaskNotice({ text: "Очередь очищена.", tone: "success", source });
    } catch (error) {
      showNotification(error.message || String(error), "error");
    }
  };

  const clearDatabase = async () => {
    if (!window.api) {
      showNotification("Electron API недоступен. Откройте приложение в Electron.", "error");
      return;
    }
    if (!window.confirm("Удалить все данные из базы? Это действие нельзя отменить.")) {
      return;
    }
    try {
      await window.api.clearDatabase();
      showNotification("База очищена.", "info");
      setSelectedTaskId(null);
      resetTaskForm();
      setCompetitorText("");
      resetSelectedAccountIds([]);
      resetTaskAccountRoles({});
      setLogs([]);
      setInvites([]);
      setTaskStatus({
        running: false,
        queueCount: 0,
        dailyRemaining: 0,
        dailyUsed: 0,
        dailyLimit: 0,
        monitorInfo: { monitoring: false, accountId: 0, accountIds: [], groups: [], lastMessageAt: "", lastSource: "" }
      });
      await loadBase();
    } catch (error) {
      showNotification(error.message || String(error), "error");
    }
  };

  const resetSessions = async () => {
    if (!window.api) {
      showNotification("Electron API недоступен. Откройте приложение в Electron.", "error");
      return;
    }
    try {
      await window.api.resetSessions();
      showNotification("Сессии сброшены.", "info");
      resetSelectedAccountIds([]);
      resetTaskAccountRoles({});
      await loadBase();
    } catch (error) {
      showNotification(error.message || String(error), "error");
    }
  };

  return {
    saveTask,
    deleteTask,
    startTask,
    stopTask,
    startAllTasks,
    stopAllTasks,
    parseHistory,
    checkAll,
    joinGroupsForTask,
    clearLogs,
    clearInvites,
    clearAccountEvents,
    exportLogs,
    exportInvites,
    exportProblemInvites,
    exportFallback,
    updateFallbackStatus,
    clearFallback,
    clearConfirmQueue,
    clearQueue,
    clearDatabase,
    resetSessions
  };
}
