import React, { memo } from "react";

function LogsTab({
  logsTab,
  setLogsTab,
  hasSelectedTask,
  exportLogs,
  clearLogs,
  exportInvites,
  exportProblemInvites,
  exportFallback,
  updateFallbackStatus,
  clearFallback,
  clearInvites,
  logSearch,
  setLogSearch,
  logPage,
  setLogPage,
  logPageCount,
  pagedLogs,
  inviteSearch,
  setInviteSearch,
  invitePage,
  setInvitePage,
  invitePageCount,
  inviteFilter,
  setInviteFilter,
  pagedInvites,
  fallbackSearch,
  setFallbackSearch,
  fallbackPage,
  setFallbackPage,
  fallbackPageCount,
  pagedFallback,
  auditSearch,
  setAuditSearch,
  auditPage,
  setAuditPage,
  auditPageCount,
  pagedAudit,
  formatTimestamp,
  explainInviteError,
  accountById,
  formatAccountLabel,
  expandedInviteId,
  setExpandedInviteId,
  inviteStats,
  selectedTask,
  taskAccountRoles,
  accessStatus,
  inviteAccessStatus,
  selectedTaskName,
  roleSummary,
  mutualContactDiagnostics
}) {
  const strategyLabel = (strategy) => {
    switch (strategy) {
      case "access_hash":
        return "access_hash (из сообщения)";
      case "participants":
        return "участники группы";
      case "username":
        return "username";
      case "entity":
        return "getEntity(userId)";
      case "retry":
        return "повторная попытка";
      default:
        return strategy || "—";
    }
  };

  const formatStrategies = (meta) => {
    if (!meta) return "";
    try {
      const parsed = JSON.parse(meta);
      if (!Array.isArray(parsed)) return meta;
      return parsed
        .map((item) => `${strategyLabel(item.strategy)}: ${item.ok ? "ok" : "fail"}${item.detail ? ` (${item.detail})` : ""}`)
        .map((line) => `- ${line}`)
        .join("\n");
    } catch (error) {
      return meta;
    }
  };

  const hasStrategySuccess = (meta) => {
    if (!meta) return false;
    try {
      const parsed = JSON.parse(meta);
      return Array.isArray(parsed) && parsed.some((item) => item.ok);
    } catch (error) {
      return false;
    }
  };

  const formatTargetType = (value) => {
    if (!value) return "—";
    if (value === "channel") return "канал";
    if (value === "megagroup") return "супергруппа";
    if (value === "group") return "группа";
    return value;
  };
  const formatErrorWithExplain = (value) => {
    if (!value) return "—";
    const code = String(value);
    const explanation = explainInviteError(code.split(/[:(]/, 1)[0].trim());
    if (!explanation) return code;
    if (code.includes("(")) return code;
    return `${code} (${explanation})`;
  };
  const explainRawError = (value) => {
    if (!value) return "";
    const code = String(value).split(/[:(]/, 1)[0].trim();
    return explainInviteError(code);
  };

  const getDurationMs = (start, finish) => {
    const startMs = new Date(start).getTime();
    const finishMs = new Date(finish).getTime();
    if (!Number.isFinite(startMs) || !Number.isFinite(finishMs)) return null;
    return Math.max(0, finishMs - startMs);
  };
  const hasBothRoles = (accountId) => {
    if (!accountId || !taskAccountRoles) return false;
    const roles = taskAccountRoles[String(accountId)] || taskAccountRoles[accountId];
    return Boolean(roles && roles.monitor && roles.invite);
  };
  const formatInviteStatus = (status) => {
    switch (status) {
      case "success":
        return "Успех";
      case "skipped":
        return "Пропуск";
      case "unconfirmed":
        return "Не подтверждено";
      case "failed":
      default:
        return "Ошибка";
    }
  };

  return (
    <section className="card logs">
      <div className="row-header">
        <h2>Логи и история</h2>
        <div className="row-inline">
          {logsTab === "logs" && (
            <>
              <button className="secondary" onClick={() => exportLogs("logs")} disabled={!hasSelectedTask}>Выгрузить</button>
              <button className="danger" onClick={() => clearLogs("logs")} disabled={!hasSelectedTask}>Сбросить</button>
            </>
          )}
          {logsTab === "invites" && (
            <>
              <button className="secondary" onClick={() => exportInvites("invites")} disabled={!hasSelectedTask}>Выгрузить</button>
              <button className="secondary" onClick={() => exportProblemInvites("invites")} disabled={!hasSelectedTask}>Проблемные 30 дней</button>
              <button className="secondary" onClick={() => exportFallback("invites")} disabled={!hasSelectedTask}>Fallback</button>
              <button className="danger" onClick={() => clearInvites("invites")} disabled={!hasSelectedTask}>Сбросить</button>
            </>
          )}
          {logsTab === "fallback" && (
            <>
              <button className="secondary" onClick={() => exportFallback("fallback")} disabled={!hasSelectedTask}>Выгрузить</button>
              <button className="danger" onClick={() => clearFallback("fallback")} disabled={!hasSelectedTask}>Сбросить</button>
            </>
          )}
        </div>
      </div>
      <div className="log-tabs">
        <button
          type="button"
          className={`tab ${logsTab === "logs" ? "active" : ""}`}
          onClick={() => setLogsTab("logs")}
        >
          Логи
        </button>
        <button
          type="button"
          className={`tab ${logsTab === "invites" ? "active" : ""}`}
          onClick={() => setLogsTab("invites")}
        >
          История инвайтов
        </button>
        <button
          type="button"
          className={`tab ${logsTab === "audit" ? "active" : ""}`}
          onClick={() => setLogsTab("audit")}
        >
          Изменения
        </button>
        <button
          type="button"
          className={`tab ${logsTab === "fallback" ? "active" : ""}`}
          onClick={() => setLogsTab("fallback")}
        >
          Fallback
        </button>
        <button
          type="button"
          className={`tab ${logsTab === "diagnostics" ? "active" : ""}`}
          onClick={() => setLogsTab("diagnostics")}
        >
          Диагностика
        </button>
      </div>
      {logsTab === "logs" && (
        <>
          <div className="row-inline">
            <input
              type="text"
              value={logSearch}
              onChange={(event) => {
                setLogSearch(event.target.value);
                setLogPage(1);
              }}
              placeholder="Поиск по логам"
            />
            <div className="pager">
              <button
                className="secondary"
                type="button"
                onClick={() => setLogPage((prev) => Math.max(1, prev - 1))}
                disabled={logPage === 1}
              >
                Назад
              </button>
              <span>{logPage}/{logPageCount}</span>
              <button
                className="secondary"
                type="button"
                onClick={() => setLogPage((prev) => Math.min(logPageCount, prev + 1))}
                disabled={logPage === logPageCount}
              >
                Вперед
              </button>
            </div>
          </div>
          {pagedLogs.length === 0 && <div className="empty">Логи пока пустые.</div>}
          {pagedLogs.map((log) => {
            const successIds = Array.isArray(log.successIds) ? log.successIds : [];
            const errors = Array.isArray(log.errors) ? log.errors : [];
            const errorMap = new Map();
            errors.forEach((err) => {
              const parts = String(err).split(":");
              if (parts.length < 2) return;
              const id = parts[0].trim();
              const code = parts.slice(1).join(":").trim();
              if (!id) return;
              errorMap.set(id, code);
            });
            const resultRows = [
              ...successIds.map((id) => ({
                id: String(id),
                status: "success",
                message: "успех"
              })),
              ...Array.from(errorMap.entries()).map(([id, code]) => ({
                id,
                status: "error",
                message: `${code} (${explainInviteError(code) || "Причина не определена"})`
              }))
            ];
            return (
              <div key={log.id} className="log-row">
                <div className="log-time">
                  <div>Старт цикла: {formatTimestamp(log.startedAt)}</div>
                  <div>Завершение: {formatTimestamp(log.finishedAt)}</div>
                </div>
                <div className="log-details">
                  <div>Добавлено: {log.invitedCount}</div>
                  {log.meta && (log.meta.batchSize || log.meta.cycleLimit || log.meta.queueCount) && (
                    <div className="log-users">
                      Цикл: лимит {log.meta.cycleLimit ?? "—"}, очередь {log.meta.queueCount ?? "—"}, взято {log.meta.batchSize ?? "—"}
                    </div>
                  )}
                  <div className="log-users wrap">
                    Пользователи: {successIds.length ? successIds.join(", ") : "—"}
                  </div>
                  {resultRows.length > 0 && (
                    <div className="log-users">
                      <div>Результаты:</div>
                      <div className="log-result-list">
                        {resultRows.map((row) => (
                          <div key={`${log.id}-${row.id}-${row.status}`} className={`log-result ${row.status}`}>
                            {row.id} — {row.message}
                          </div>
                        ))}
                      </div>
                    </div>
                  )}
                  {log.invitedCount === 0 && errors.length === 0 && (
                    <div className="log-errors">Причина: цикл завершён сразу — очередь пуста</div>
                  )}
                  {errors.length > 0 && (
                    <div className="log-errors">
                      Ошибки: {errors.map((err) => {
                        const code = String(err).split(":").pop().trim();
                        const reason = explainInviteError(code) || "Причина не определена";
                        return code ? `${err} (${reason})` : err;
                      }).join(" | ")}
                    </div>
                  )}
                  {(() => {
                    const durationMs = getDurationMs(log.startedAt, log.finishedAt);
                    if (durationMs != null && durationMs < 1000) {
                      return <div className="log-errors">Цикл завершён сразу: очередь пуста или ошибка на первой попытке.</div>;
                    }
                    return null;
                  })()}
                </div>
              </div>
            );
          })}
        </>
      )}
      {logsTab === "invites" && (
        <>
          {inviteStats && (
            <div className="invite-stats">
              Всего: {inviteStats.total} | Успех: {inviteStats.success} | Ошибка: {inviteStats.failed} | Пропуск: {inviteStats.skipped} | Не подтверждено: {inviteStats.unconfirmed}
            </div>
          )}
          <div className="row-inline">
            <input
              type="text"
              value={inviteSearch}
              onChange={(event) => {
                setInviteSearch(event.target.value);
                setInvitePage(1);
              }}
              placeholder="Поиск по инвайтам"
            />
            <div className="pager">
              <button
                className="secondary"
                type="button"
                onClick={() => setInvitePage((prev) => Math.max(1, prev - 1))}
                disabled={invitePage === 1}
              >
                Назад
              </button>
              <span>{invitePage}/{invitePageCount}</span>
              <button
                className="secondary"
                type="button"
                onClick={() => setInvitePage((prev) => Math.min(invitePageCount, prev + 1))}
                disabled={invitePage === invitePageCount}
              >
                Вперед
              </button>
            </div>
          </div>
          <div className="task-filters">
            <button
              type="button"
              className={`chip ${inviteFilter === "all" ? "active" : ""}`}
              onClick={() => {
                setInviteFilter("all");
                setInvitePage(1);
              }}
            >
              Все
            </button>
            <button
              type="button"
              className={`chip ${inviteFilter === "success" ? "active" : ""}`}
              onClick={() => {
                setInviteFilter("success");
                setInvitePage(1);
              }}
            >
              Успех
            </button>
            <button
              type="button"
              className={`chip ${inviteFilter === "error" ? "active" : ""}`}
              onClick={() => {
                setInviteFilter("error");
                setInvitePage(1);
              }}
            >
              Ошибка
            </button>
            <button
              type="button"
              className={`chip ${inviteFilter === "skipped" ? "active" : ""}`}
              onClick={() => {
                setInviteFilter("skipped");
                setInvitePage(1);
              }}
            >
              Пропуск
            </button>
            <button
              type="button"
              className={`chip ${inviteFilter === "unconfirmed" ? "active" : ""}`}
              onClick={() => {
                setInviteFilter("unconfirmed");
                setInvitePage(1);
              }}
            >
              Не подтверждено
            </button>
          </div>
          {pagedInvites.length === 0 && <div className="empty">История пока пустая.</div>}
          {pagedInvites.map((invite) => (
            <div key={invite.id} className="log-row">
              <div className="log-time">
                <div>{formatTimestamp(invite.invitedAt)}</div>
                <div>
                  <span className={`log-status ${invite.status}`}>{formatInviteStatus(invite.status)}</span>
                </div>
              </div>
              <div className="log-details">
                <div>ID: {invite.userId}</div>
                <div className="log-users wrap">
                  Ник: {invite.username ? `@${invite.username}` : "— (нет username в источнике)"}
                </div>
                <div className="log-users wrap">
                  Источник: {invite.sourceChat || "—"}
                </div>
                <div className="log-users wrap">
                  Цель: {invite.targetChat || "—"}{invite.targetType ? ` (${formatTargetType(invite.targetType)})` : ""}
                </div>
                <div className="log-users">
                  Инвайт: {(() => {
                    const account = accountById.get(invite.accountId);
                    return account ? formatAccountLabel(account) : (invite.accountPhone || "—");
                  })()}
                  {invite.watcherAccountId && invite.accountId && (
                    <span className={`match-badge ${invite.watcherAccountId === invite.accountId ? "ok" : "warn"}`}>
                      {invite.watcherAccountId === invite.accountId
                        ? "Инвайт тем же аккаунтом, что наблюдал"
                        : ""}
                    </span>
                  )}
                </div>
                {invite.watcherAccountId && invite.accountId && invite.watcherAccountId !== invite.accountId
                  && selectedTask && selectedTask.randomAccounts && hasBothRoles(invite.watcherAccountId) && (
                  <div className="log-users">
                    Примечание: у наблюдателя стоят обе роли, но включен случайный выбор — инвайт выполнен другим аккаунтом.
                  </div>
                )}
                <div className="log-users">Наблюдатель: {(() => {
                  const account = accountById.get(invite.watcherAccountId);
                  return account ? formatAccountLabel(account) : (invite.watcherPhone || "—");
                })()}</div>
                {invite.skippedReason && invite.skippedReason !== "" && (
                  <div className="log-errors">Результат: {formatErrorWithExplain(invite.skippedReason)}</div>
                )}
                {invite.error && invite.error !== "" && (
                  <div className="log-errors">Ошибка: {formatErrorWithExplain(invite.error)}</div>
                )}
                <div className="log-errors">
                  Проверка участия: {invite.confirmError
                    ? formatErrorWithExplain(invite.confirmError)
                    : (invite.confirmed ? "OK" : "Не подтверждено")}
                </div>
                {invite.confirmError && invite.confirmError.includes("(") && (
                  <div className="log-users">
                    Проверял: {invite.confirmError.slice(invite.confirmError.indexOf("(") + 1, invite.confirmError.lastIndexOf(")"))}
                  </div>
                )}
                {invite.strategy && (
                  <div className="log-users">Стратегия: {invite.strategy}</div>
                )}
                {invite.strategyMeta && (
                  <div className="log-users">{`Стратегии:\n${formatStrategies(invite.strategyMeta)}`}</div>
                )}
                {invite.strategyMeta && !hasStrategySuccess(invite.strategyMeta) && (
                  <div className="log-errors">Все стратегии не сработали</div>
                )}
                <button
                  type="button"
                  className="ghost"
                  onClick={() => setExpandedInviteId(expandedInviteId === invite.id ? null : invite.id)}
                >
                  {expandedInviteId === invite.id ? "Скрыть детали" : "Подробнее"}
                </button>
                {expandedInviteId === invite.id && (
                  <div className="invite-details">
                    <div>Задача: {invite.taskId}</div>
                    <div>Аккаунт ID: {invite.accountId || "—"}</div>
                    <div>Наблюдатель ID: {invite.watcherAccountId || "—"}</div>
                    <div>Наблюдатель: {(() => {
                      const account = accountById.get(invite.watcherAccountId);
                      return account ? formatAccountLabel(account) : (invite.watcherPhone || "—");
                    })()}</div>
                    <div>Цель: {invite.targetChat || "—"}</div>
                    <div>Тип цели: {formatTargetType(invite.targetType)}</div>
                    <div>Действие: {invite.action || "invite"}</div>
                    <div>Статус: {formatInviteStatus(invite.status)}</div>
                    <div>Результат: {formatErrorWithExplain(invite.skippedReason)}</div>
                    <div>Ошибка: {formatErrorWithExplain(invite.error)}</div>
                    <div>Проверка участия: {invite.confirmError
                      ? formatErrorWithExplain(invite.confirmError)
                      : (invite.confirmed ? "OK" : "Не подтверждено")}</div>
                    {invite.confirmError && invite.confirmError.includes("(") && (
                      <div>Проверял: {invite.confirmError.slice(invite.confirmError.indexOf("(") + 1, invite.confirmError.lastIndexOf(")"))}</div>
                    )}
                    {invite.watcherAccountId && invite.accountId && invite.watcherAccountId !== invite.accountId
                      && selectedTask && selectedTask.randomAccounts && hasBothRoles(invite.watcherAccountId) && (
                      <div>Примечание: у наблюдателя стоят обе роли, но включен случайный выбор — инвайт выполнен другим аккаунтом.</div>
                    )}
                    <div>Пояснение: {explainRawError(invite.error) || explainRawError(invite.confirmError) || "Причина не определена"}</div>
                    <div>Стратегия: {invite.strategy || "—"}</div>
                    <div className="pre-line">
                      {invite.strategyMeta ? `Стратегии:\n${formatStrategies(invite.strategyMeta)}` : "Стратегии: —"}
                    </div>
                    {invite.strategyMeta && !hasStrategySuccess(invite.strategyMeta) && (
                      <div>Результат: все стратегии не сработали</div>
                    )}
                    <div>Access Hash: {invite.userAccessHash || "—"}</div>
                    <div>Время: {formatTimestamp(invite.invitedAt)}</div>
                  </div>
                )}
              </div>
            </div>
          ))}
        </>
      )}
      {logsTab === "fallback" && (
        <>
          <div className="row-inline">
            <input
              type="text"
              value={fallbackSearch}
              onChange={(event) => {
                setFallbackSearch(event.target.value);
                setFallbackPage(1);
              }}
              placeholder="Поиск по fallback"
            />
            <div className="pager">
              <button
                className="secondary"
                type="button"
                onClick={() => setFallbackPage((prev) => Math.max(1, prev - 1))}
                disabled={fallbackPage === 1}
              >
                Назад
              </button>
              <span>{fallbackPage}/{fallbackPageCount}</span>
              <button
                className="secondary"
                type="button"
                onClick={() => setFallbackPage((prev) => Math.min(fallbackPageCount, prev + 1))}
                disabled={fallbackPage === fallbackPageCount}
              >
                Вперед
              </button>
            </div>
          </div>
          {pagedFallback.length === 0 && <div className="empty">Fallback пока пуст.</div>}
          {pagedFallback.map((item) => (
            <div key={item.id} className="log-row">
              <div className="log-time">
                <div>{formatTimestamp(item.createdAt)}</div>
                <div>{item.route}</div>
              </div>
              <div className="log-details">
                <div>ID: {item.userId}</div>
                <div className="log-users wrap">Ник: {item.username ? `@${item.username}` : "—"}</div>
                <div className="log-users wrap">Источник: {item.sourceChat || "—"}</div>
                <div className="log-users wrap">Цель: {item.targetChat || "—"}</div>
                <div className="log-errors">Причина: {item.reason}</div>
                <div className="log-users">Статус: {item.status}</div>
                <div className="log-actions">
                  <button
                    className="secondary"
                    type="button"
                    onClick={() => updateFallbackStatus(item.id, "done")}
                  >
                    Обработано
                  </button>
                  <button
                    className="ghost"
                    type="button"
                    onClick={() => updateFallbackStatus(item.id, "pending")}
                  >
                    Вернуть
                  </button>
                </div>
              </div>
            </div>
          ))}
        </>
      )}
      {logsTab === "audit" && (
        <>
          <div className="row-inline">
            <input
              type="text"
              value={auditSearch}
              onChange={(event) => {
                setAuditSearch(event.target.value);
                setAuditPage(1);
              }}
              placeholder="Поиск по изменениям"
            />
            <div className="pager">
              <button
                className="secondary"
                type="button"
                onClick={() => setAuditPage((prev) => Math.max(1, prev - 1))}
                disabled={auditPage === 1}
              >
                Назад
              </button>
              <span>{auditPage}/{auditPageCount}</span>
              <button
                className="secondary"
                type="button"
                onClick={() => setAuditPage((prev) => Math.min(auditPageCount, prev + 1))}
                disabled={auditPage === auditPageCount}
              >
                Вперед
              </button>
            </div>
          </div>
          {pagedAudit.length === 0 && <div className="empty">История изменений пуста.</div>}
          {pagedAudit.map((item) => (
            <div key={item.id} className="log-row">
              <div className="log-time">
                <div>{formatTimestamp(item.createdAt)}</div>
                <div>{item.action}</div>
              </div>
              <div className="log-details">
                <div className="pre-line">{item.details || "—"}</div>
              </div>
            </div>
          ))}
        </>
      )}
      {logsTab === "diagnostics" && (
        <>
          <div className="log-users">Для: {selectedTaskName}</div>
          {accessStatus && accessStatus.length > 0 && (
            <div className="access-block">
              <div className="access-title">Доступ к группам</div>
              <div className="access-list">
                {accessStatus.map((item, index) => (
                  <div key={`${item.value}-${index}`} className={`access-row ${item.ok ? "ok" : "fail"}`}>
                    <div className="access-title">
                      {item.type === "our" ? "Наша" : "Конкурент"}: {item.title || item.value}
                    </div>
                    <div className="access-status">
                      {item.ok ? "Доступ есть" : "Нет доступа"}
                    </div>
                    {!item.ok && <div className="access-error">{item.details}</div>}
                  </div>
                ))}
              </div>
            </div>
          )}
          {inviteAccessStatus && inviteAccessStatus.length > 0 && (
            <div className="access-block">
              <div className="access-title">Права инвайта</div>
              <div className="access-subtitle">
                Проверяются аккаунты с ролью инвайта: {roleSummary ? roleSummary.invite.length : "—"}
              </div>
              <div className="access-list">
                {inviteAccessStatus.map((item, index) => (
                  <div key={`${item.accountId}-${index}`} className={`access-row ${item.canInvite ? "ok" : "fail"}`}>
                    <div className="access-title">
                      {(() => {
                        const account = accountById.get(item.accountId);
                        return account ? formatAccountLabel(account) : (item.accountPhone || item.accountId);
                      })()}: {item.title || item.targetChat}
                      {item.targetType ? ` (${formatTargetType(item.targetType)})` : ""}
                    </div>
                    <div className="access-status">
                      {item.canInvite ? "Можно инвайтить" : "Нет прав"}
                    </div>
                    {!item.canInvite && <div className="access-error">{item.reason || "—"}</div>}
                  </div>
                ))}
              </div>
            </div>
          )}
          {mutualContactDiagnostics && (
            <div className="access-block">
              <div className="access-title">USER_NOT_MUTUAL_CONTACT</div>
              <div className="access-subtitle">
                Ошибок в истории: {mutualContactDiagnostics.count}
              </div>
              <div className="access-list">
                <div className="access-row">
                  <div className="access-title">
                    Цель: {(() => {
                      const entry = inviteAccessStatus && inviteAccessStatus[0];
                      if (entry) {
                        const label = entry.title || entry.targetChat || (selectedTask ? selectedTask.ourGroup : "—");
                        const typeLabel = formatTargetType(entry.targetType);
                        return typeLabel ? `${label} (${typeLabel})` : label;
                      }
                      return selectedTask ? selectedTask.ourGroup : "—";
                    })()}
                  </div>
                  <div className="access-status">
                    {inviteAccessStatus && inviteAccessStatus.length ? "Права проверены" : "Нет данных проверки"}
                  </div>
                </div>
                {mutualContactDiagnostics.recent.map((item) => (
                  <div key={`mutual-${item.id}`} className="access-row fail">
                    <div className="access-title">
                      Пользователь: {item.userId}{item.username ? ` (@${item.username})` : ""}
                    </div>
                    <div className="access-status">{formatTimestamp(item.invitedAt)}</div>
                  </div>
                ))}
              </div>
              <div className="access-error">
                Возможные причины: Telegram ограничивает инвайт, если пользователь скрывает приём приглашений,
                целевая группа требует взаимного контакта, или у пользователя есть приватные ограничения.
              </div>
            </div>
          )}
          {!accessStatus?.length && !inviteAccessStatus?.length && (
            <div className="empty">Диагностика пока пустая.</div>
          )}
        </>
      )}
    </section>
  );
}

export default memo(LogsTab);
