// @ts-nocheck
import { debugLog } from '../common';
import { usePolicyStore } from '../../../stores/policy';
import { useModelStore } from '../../../stores/model';
import { usePersonalizationStore } from '../../../stores/personalization';
import { useTutorialStore } from '../../../stores/tutorial';
import { renderMarkdown as renderMarkdownHelper } from '../../../composables/useMarkdownRenderer';
import { scrollToBottom as scrollToBottomHelper, conditionalScrollToBottom as conditionalScrollToBottomHelper, scrollThinkingToBottom as scrollThinkingToBottomHelper } from '../../../composables/useScrollControl';
import { startResize as startPanelResize, handleResize as handlePanelResize, stopResize as stopPanelResize } from '../../../composables/usePanelResize';
import {
  SUB_AGENT_DONE_PREFIX_RE,
  BG_RUN_COMMAND_DONE_PREFIX_RE,
  userMDebug,
  UI_BOUNCE_TRACE_MAX,
  uiBounceTraceLastTsByKey,
  isUiBounceTraceEnabled,
  uiBounceTrace,
  isConnectionDiagEnabled,
  pushConnectionDiagRecord,
  connectionDiag,
  parseSubAgentDoneLabel,
  parseBackgroundRunCommandDoneLabel,
  parseSystemNoticeLabel,
} from './shared';

export const scrollMethods = {
  clearLocalTaskUiState(reason = 'safe-navigation') {
    // 只清理当前浏览器视图里的运行态/工具态，不取消后端任务。
    // 用于切换对话/工作区后，避免旧任务残留让新视图的发送按钮显示为“停止”。
    try {
      if (typeof this.stopWaitingTaskProbe === 'function') {
        this.stopWaitingTaskProbe();
      }
    } catch (_) {}
    this.streamingMessage = false;
    this.taskInProgress = false;
    this.stopRequested = false;
    this.waitingForSubAgent = false;
    this.waitingForBackgroundCommand = false;
    this.dropToolEvents = false;
    this.runtimeQueuedMessages = [];
    this.runtimeGuidanceFallbackQueue = [];
    this.runtimeQueueAutoSendInProgress = false;
    this.runtimeQueueSyncLockKey = '';
    this.runtimeQueueSyncLockUntil = 0;
    this.goalModeArmed = false;
    this.goalRunning = false;
    this.goalProgress = null;
    this.goalDialogOpen = false;
    if (typeof this.clearRuntimeQueueSuppressionState === 'function') {
      this.clearRuntimeQueueSuppressionState();
    } else {
      this.runtimeQueueSuppressedMessageIds = new Set();
      this.runtimeGuidanceSuppressedTextCounts = {};
    }
    if (typeof this.clearPendingTools === 'function') {
      this.clearPendingTools(reason);
    } else {
      this.preparingTools?.clear?.();
      this.activeTools?.clear?.();
      this.toolActionIndex?.clear?.();
      this.toolStacks?.clear?.();
    }
    if (typeof this.chatClearThinkingLocks === 'function') {
      this.chatClearThinkingLocks();
    }
    this.$forceUpdate?.();
  },
  ensureScrollListener() {
    if (this._scrollListenerReady) {
      return;
    }
    const area = this.getMessagesAreaElement();
    if (!area) {
      return;
    }
    this.initScrollListener();
    this._scrollListenerReady = true;
  },
  handleStickStateChange(payload) {
    const escaped = !!payload?.escapedFromLock;
    const isAtBottom = !!payload?.isAtBottom;
    const isNearBottom = !!payload?.isNearBottom;
    const nearBottom = isAtBottom || isNearBottom;
    const userEscaped = !!this._escapedByUserScroll;
    uiBounceTrace(
      'stick-state-change',
      {
        isAtBottom,
        isNearBottom,
        escapedFromLock: escaped,
        userEscaped,
        autoScrollEnabled: this.autoScrollEnabled,
        userScrolling: this.userScrolling
      },
      'stick-state-change',
      180
    );
    this.stickIsAtBottom = isAtBottom;
    this.stickIsNearBottom = isNearBottom;

    // 用户主动脱离锁定：只要没回到底部/近底部，就保持“手动滚动中”状态
    if (userEscaped) {
      if (nearBottom) {
        this._escapedByUserScroll = false;
        this.chatSetScrollState({ userScrolling: false });
      } else {
        this.chatSetScrollState({ userScrolling: true });
      }
      return;
    }

    // 非用户触发的 escaped（例如高度突增导致的短暂锚点漂移）不应解除锁定
    this.chatSetScrollState({ userScrolling: false });
    if (!escaped) {
      return;
    }
    const active = typeof this.isOutputActive === 'function' ? this.isOutputActive() : true;
    if (!this.autoScrollEnabled || !active) {
      return;
    }
    const chatArea = this.getChatAreaController();
    if (chatArea && typeof chatArea.conditionalStickToBottom === 'function') {
      chatArea.conditionalStickToBottom({ force: false });
      return;
    }
    conditionalScrollToBottomHelper(this);
  },
  handleUserScrollIntent(payload) {
    const ts = Number(payload?.ts || Date.now());
    const chatArea = this.getChatAreaController();
    if (chatArea && typeof chatArea.stopStickScroll === 'function') {
      chatArea.stopStickScroll();
    }
    // 用户手动滚动后，短时间内禁止任何自动追底，规避 escapedFromLock 状态抖动竞态
    this._manualScrollSuppressUntil = Math.max(this._manualScrollSuppressUntil || 0, ts + 1600);
    this._escapedByUserScroll = true;
    this.chatSetScrollState({ userScrolling: true });
    uiBounceTrace(
      'ui.user-scroll-intent',
      {
        ts,
        delta: Number(payload?.delta || 0),
        top: Number(payload?.top || 0),
        suppressUntil: this._manualScrollSuppressUntil
      },
      'ui.user-scroll-intent',
      80
    );
  },
  scrollHistoryToBottomInstant() {
    this._escapedByUserScroll = false;
    const chatArea = this.getChatAreaController();
    if (chatArea && typeof chatArea.stopStickScroll === 'function') {
      chatArea.stopStickScroll();
    }
    const area = this.getMessagesAreaElement();
    if (!area) {
      return;
    }
    const jump = () => {
      area.scrollTop = area.scrollHeight;
    };
    jump();
    requestAnimationFrame(() => {
      jump();
      requestAnimationFrame(jump);
    });
    this.chatSetScrollState({ userScrolling: false });
  },
  async settleHistoryRenderAndScroll() {
    this._escapedByUserScroll = false;
    const chatArea = this.getChatAreaController();
    if (chatArea && typeof chatArea.stopStickScroll === 'function') {
      chatArea.stopStickScroll();
    }
    const area = this.getMessagesAreaElement();
    if (!area) {
      return;
    }
    const nextFrame = () => new Promise((resolve) => requestAnimationFrame(resolve));
    const sleep = (ms) => new Promise((resolve) => window.setTimeout(resolve, ms));
    const jump = () => {
      area.scrollTop = area.scrollHeight;
    };

    let lastHeight = -1;
    let stableFrames = 0;
    const startedAt = Date.now();
    while (Date.now() - startedAt < 900 && stableFrames < 4) {
      await nextFrame();
      jump();
      const height = area.scrollHeight;
      if (Math.abs(height - lastHeight) <= 1) {
        stableFrames += 1;
      } else {
        stableFrames = 0;
        lastHeight = height;
      }
    }

    // 给 show_html / 表格滚动壳等异步同步 DOM 一次短暂稳定窗口；仍在 historyLoading 隐藏期内完成。
    await sleep(80);
    jump();
    await nextFrame();
    jump();
    this.chatSetScrollState({ userScrolling: false });
  },
  scrollToBottom() {
    uiBounceTrace(
      'ui.scrollToBottom:called',
      {
        autoScrollEnabled: this.autoScrollEnabled,
        userScrolling: this.userScrolling
      },
      'ui.scrollToBottom:called',
      80
    );
    this._escapedByUserScroll = false;
    const chatArea = this.getChatAreaController();
    if (chatArea && typeof chatArea.scrollToBottom === 'function') {
      chatArea.scrollToBottom({
        behavior: 'auto',
        force: this.autoScrollEnabled
      });
      this.chatSetScrollState({ userScrolling: false });
      return;
    }
    scrollToBottomHelper(this);
  },
  conditionalScrollToBottom() {
    const active = typeof this.isOutputActive === 'function' ? this.isOutputActive() : true;
    const chatArea = this.getChatAreaController();
    const stickState =
      chatArea && typeof chatArea.getStickState === 'function' ? chatArea.getStickState() : null;
    uiBounceTrace(
      'ui.conditionalScrollToBottom:called',
      {
        active,
        autoScrollEnabled: this.autoScrollEnabled,
        userScrolling: this.userScrolling,
        stickIsNearBottom: this.stickIsNearBottom,
        escapedFromLock: !!stickState?.escapedFromLock
      },
      'ui.conditionalScrollToBottom:called',
      120
    );
    if (!active) {
      return;
    }
    const now = Date.now();
    if (now <= (this._manualScrollSuppressUntil || 0)) {
      uiBounceTrace(
        'ui.conditionalScrollToBottom:skip-manual-cooldown',
        {
          now,
          suppressUntil: this._manualScrollSuppressUntil
        },
        'ui.conditionalScrollToBottom:skip-manual-cooldown',
        120
      );
      return;
    }
    // 仅在“确认是用户主动脱离锁定”时才阻断自动追底；
    // 对于内容高度突变导致的 escapedFromLock，不应长期卡住锁定。
    if (stickState?.escapedFromLock && this._escapedByUserScroll) {
      uiBounceTrace(
        'ui.conditionalScrollToBottom:skip-escaped-lock',
        {
          escapedFromLock: !!stickState?.escapedFromLock,
          escapedByUser: !!this._escapedByUserScroll,
          isNearBottom: !!stickState?.isNearBottom,
          isAtBottom: !!stickState?.isAtBottom
        },
        'ui.conditionalScrollToBottom:skip-escaped-lock',
        120
      );
      return;
    }
    // 只要用户处于手动滚动状态，就停止自动追底，避免“被弹回”
    // （stickIsNearBottom 在 show_html 动态重排时可能短暂失真，不可作为阻断前置条件）
    if (this.userScrolling) {
      uiBounceTrace(
        'ui.conditionalScrollToBottom:skip-user-scrolling',
        {
          userScrolling: this.userScrolling,
          stickIsNearBottom: this.stickIsNearBottom
        },
        'ui.conditionalScrollToBottom:skip-user-scrolling',
        120
      );
      return;
    }
    if (chatArea && typeof chatArea.conditionalStickToBottom === 'function') {
      chatArea.conditionalStickToBottom({ force: false });
      return;
    }
    conditionalScrollToBottomHelper(this);
  },
  toggleScrollLock() {
    uiBounceTrace(
      'ui.scrollToBottomButton:clicked',
      {
        autoScrollEnabled: this.autoScrollEnabled,
        userScrolling: this.userScrolling,
        stickNearBottom: this.stickIsNearBottom
      },
      'ui.scrollToBottomButton:clicked',
      0
    );
    const chatArea = this.getChatAreaController();
    if (chatArea && typeof chatArea.scrollToBottom === 'function') {
      chatArea.scrollToBottom({ behavior: 'smooth', force: true });
    } else {
      scrollToBottomHelper(this, {
        ignoreUserScrolling: true,
        resetUserScrolling: true,
        behavior: 'smooth',
        force: true
      });
    }
    this._escapedByUserScroll = false;
    this.chatSetScrollState({ autoScrollEnabled: true, userScrolling: false });
    return true;
  },
  scrollThinkingToBottom(blockId) {
    scrollThinkingToBottomHelper(this, blockId);
  },
  initScrollListener() {
    const chatArea = this.getChatAreaController();
    if (
      chatArea &&
      typeof chatArea.isUsingStickToBottom === 'function' &&
      chatArea.isUsingStickToBottom()
    ) {
      this._scrollListenerReady = true;
      return;
    }
    const messagesArea = this.getMessagesAreaElement();
    if (!messagesArea) {
      console.warn('消息区域未找到');
      return;
    }
    this._scrollListenerReady = true;
    let scrollDebugCount = 0;
    const SCROLL_DEBUG_MAX = 1200;
    let scrollDebugLastTs = 0;
    const isScrollDebugEnabled = () => {
      if (typeof window === 'undefined') return false;
      const until = Number((window as any).__SHOW_TAG_DRAWING_UNTIL__ || 0);
      return Date.now() <= until;
    };
    const scrollDebug = (event, payload = {}, throttleMs = 80) => {
      if (!isScrollDebugEnabled()) {
        return;
      }
      if (scrollDebugCount >= SCROLL_DEBUG_MAX) {
        return;
      }
      const now = Date.now();
      if (throttleMs > 0 && now - scrollDebugLastTs < throttleMs) {
        return;
      }
      scrollDebugLastTs = now;
      scrollDebugCount += 1;
      if (scrollDebugCount === SCROLL_DEBUG_MAX) {
        console.warn('[SCROLL_DEBUG]', 'listener:log-limit-reached', { max: SCROLL_DEBUG_MAX });
        return;
      }
      console.log('[SCROLL_DEBUG]', event, payload);
    };
    scrollDebug(
      'listener:setup',
      {
        autoScrollEnabled: this.autoScrollEnabled,
        userScrolling: this.userScrolling
      },
      0
    );

    let isProgrammaticScroll = false;
    const bottomThreshold = 12;

    this._setScrollingFlag = (flag) => {
      isProgrammaticScroll = !!flag;
      scrollDebug('listener:programmatic-flag', { flag: !!flag }, 0);
    };

    messagesArea.addEventListener('scroll', () => {
      if (isProgrammaticScroll) {
        scrollDebug(
          'listener:scroll:ignore-programmatic',
          {
            top: messagesArea.scrollTop,
            height: messagesArea.scrollHeight,
            client: messagesArea.clientHeight
          },
          120
        );
        return;
      }

      const scrollTop = messagesArea.scrollTop;
      const scrollHeight = messagesArea.scrollHeight;
      const clientHeight = messagesArea.clientHeight;
      const isAtBottom = scrollHeight - scrollTop - clientHeight < bottomThreshold;
      const nearBottomThreshold = 48;
      const isNearBottom = scrollHeight - scrollTop - clientHeight < nearBottomThreshold;
      const active = typeof this.isOutputActive === 'function' ? this.isOutputActive() : true;
      if (this.autoScrollEnabled && active) {
        // 锁定模式下不让 userScrolling 状态来回抖动
        this.chatSetScrollState({ userScrolling: false });
        scrollDebug('listener:scroll:locked-keep-bottom-state', {
          top: scrollTop,
          height: scrollHeight,
          client: clientHeight,
          remain: scrollHeight - scrollTop - clientHeight,
          isAtBottom,
          isNearBottom
        });
        return;
      }
      // 仅维护状态，不在 scroll 事件中强制写 scrollTop（避免上下抖动）
      this.chatSetScrollState({ userScrolling: !(isAtBottom || isNearBottom) });
      scrollDebug('listener:scroll:update-state', {
        top: scrollTop,
        height: scrollHeight,
        client: clientHeight,
        remain: scrollHeight - scrollTop - clientHeight,
        isAtBottom,
        isNearBottom,
        autoScrollEnabled: this.autoScrollEnabled,
        userScrollingBefore: this.userScrolling,
        userScrollingNext: !(isAtBottom || isNearBottom)
      });
    });
  },
  handleThinkingScroll(blockId, event) {
    if (!blockId || !event || !event.target) {
      return;
    }
    const el = event.target;
    const threshold = 12;
    const atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < threshold;
    this.chatSetThinkingLock(blockId, atBottom);
  },
  toggleBlock(blockId) {
    if (!blockId) {
      return;
    }
    if (this.expandedBlocks && this.expandedBlocks.has(blockId)) {
      this.chatCollapseBlock(blockId);
    } else {
      this.chatExpandBlock(blockId);
    }
  }
};
