// ==UserScript==
// @name         Welearn助手
// @namespace    https://bbs.tampermonkey.net.cn/
// @version      0.1.6
// @author       恶搞之家
// @description  自动选择Welearn平台的选择题、判断题、填空题和下拉框答案
// @match        *://course.sflep.com/*
// @match        *://welearn.sflep.com/*
// @match        *://wetest.sflep.com/*
// @match        *://courseappserver.sflep.com/*
// @match        *://centercourseware.sflep.com/*
// @match        *://*.sflep.com/*
// ==/UserScript==

(function () {
  'use strict';


  let isAutoLoopActive = false;
  let autoLoopTimeout = null;
  let waitTimerActive = false;
  let waitTimerInterval = null;
  let defaultWaitTime = 30;


  const createEvent = (type, options = {}) => new Event(type, {bubbles: true, cancelable: true, ...options});
  const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));


  async function autoFillAnswers() {
    console.log('开始自动填空');

    const answerElements = document.querySelectorAll('span.key, div.key');
    const inputBoxes = document.querySelectorAll('span[autocapitalize="none"], textarea.blank');

    console.log('找到填空题数量:', inputBoxes.length);

    if (answerElements.length === 0 || inputBoxes.length === 0) {
      console.log('没有找到填空题');
      return;
    }


    answerElements.forEach((element, index) => {
      try {
        const answer = element.textContent;
        const inputBox = inputBoxes[index];

        if (!inputBox) return;


        inputBox.tagName === 'SPAN' ? inputBox.textContent = answer : inputBox.value = answer;


        ['click', 'input'].forEach(evt => inputBox.dispatchEvent(createEvent(evt)));

        console.log(`已填写第${index + 1}题答案:`, answer);
      } catch (error) {
        console.log(`填写第${index + 1}题出错:`, error);
      }
    });


    await sleep(500);

    inputBoxes.forEach((inputBox, index) => {
      try {
        if (!document.body.contains(inputBox)) return;


        inputBox.dispatchEvent(createEvent('click'));
        inputBox.dispatchEvent(createEvent('focus'));

        setTimeout(() => {
          inputBox.dispatchEvent(createEvent('blur'));
        }, 50);

        if (inputBox.tagName === 'TEXTAREA') {
          inputBox.dispatchEvent(createEvent('change'));
        }
      } catch (error) {
        console.log(`额外点击第${index + 1}个填空框出错:`, error);
      }
    });

    console.log('填空题处理完成');
  }


  async function autoSelectCorrectAnswers() {
    console.log('开始自动选择答案');


    let allQuestions = [];
    for (let i = 0; i < 10 && allQuestions.length === 0; i++) {
      const choiceQuestions = document.querySelectorAll('et-choice[et-index]');
      const tfQuestions = document.querySelectorAll('et-tof[et-index]');
      allQuestions = [...choiceQuestions, ...tfQuestions];

      if (allQuestions.length === 0) {
        console.log('等待题目加载...');
        await sleep(700);
      }
    }

    console.log('找到题目数量:', allQuestions.length);
    if (allQuestions.length === 0) {
      console.log('没有找到题目');
      return;
    }


    for (let i = 0; i < allQuestions.length; i++) {
      const question = allQuestions[i];
      const isTF = question.tagName.toLowerCase() === 'et-tof';
      let options = [];


      for (let j = 0; j < 10 && options.length === 0; j++) {
        if (isTF) {
          options = question.querySelectorAll('span[ng-class*="chosen:tof.value"], div.wrapper span');
        } else {
          options = question.querySelectorAll('ol > li, div.wrapper li, span[ng-click*="choice.select"], li[class]');
        }

        if (options.length === 0) {
          console.log(`等待第${i + 1}题选项加载...`);
          await sleep(500);
        }
      }

      console.log(`处理第${i + 1}题,选项数量:`, options.length);
      if (options.length === 0) {
        console.log('未找到选项,跳过');
        continue;
      }


      let isCorrect = false;
      for (let attempt = 0; attempt < 3 && !isCorrect; attempt++) {
        for (const option of options) {
          try {

            const wrapper = isTF
              ? option.closest('div[ng-class*="isKeyVisible"]')
              : option.closest('div.wrapper');

            if (wrapper?.classList.contains('correct')) {
              console.log('此选项已经正确');
              isCorrect = true;
              break;
            }


            option.click();
            await sleep(500);


            const updatedWrapper = isTF
              ? option.closest('div[ng-class*="isKeyVisible"]')
              : option.closest('div.wrapper');

            if (updatedWrapper?.classList.contains('correct')) {
              console.log('找到正确答案:', option.textContent.trim());
              isCorrect = true;
              break;
            }
          } catch (error) {
            console.log('点击选项出错:', error);
          }
        }

        if (!isCorrect) await sleep(600);
      }

      await sleep(500);
    }

    console.log('所有题目处理完成');
  }


  function autoSelectDropdownAnswers() {
    console.log('开始处理下拉框选择题');

    const dropdowns = document.querySelectorAll('select[ng-model]');
    console.log('找到下拉框数量:', dropdowns.length);

    if (dropdowns.length === 0) return;

    dropdowns.forEach((dropdown, index) => {
      try {
        const correctOption = dropdown.querySelector('option.key');
        if (!correctOption) return;


        dropdown.value = correctOption.value;
        dropdown.dispatchEvent(createEvent('change'));

        console.log(`已选择第${index + 1}个下拉框答案:`, correctOption.textContent.trim());
      } catch (error) {
        console.log(`处理第${index + 1}个下拉框出错:`, error);
      }
    });
  }


  async function autoMatchLines() {
    console.log('开始处理连线题');


    const matchingElements = document.querySelectorAll('et-matching[et-index]');
    if (matchingElements.length === 0) return;

    console.log(`找到连线题数量: ${matchingElements.length}`);


    for (const matchingElement of matchingElements) {
      const matchingKey = matchingElement.getAttribute('key');
      if (!matchingKey) continue;

      console.log(`处理连线题,答案key: ${matchingKey}`);

      try {

        const pairs = matchingKey.split(',').map(pair => {
          const [left, right] = pair.split('-');
          return {
            leftIndex: parseInt(left) - 1,
            rightIndex: parseInt(right) - 1
          };
        });


        let angularSuccess = false;

        if (typeof angular !== 'undefined') {
          try {
            const scope = angular.element(matchingElement).scope();
            if (scope?.matching) {

              if (Array.isArray(scope.matching.lines)) {
                scope.matching.lines = [];
              }


              for (const {leftIndex, rightIndex} of pairs) {
                const leftCircle = scope.matching.circles?.A?.[leftIndex];
                const rightCircle = scope.matching.circles?.B?.[rightIndex];

                if (!leftCircle || !rightCircle) continue;


                if (typeof leftCircle.select === 'function') {
                  leftCircle.select();
                  await sleep(200);
                  rightCircle.select?.();
                } else if (typeof scope.matching.connect === 'function') {
                  scope.matching.connect(leftCircle, rightCircle);
                } else if (Array.isArray(scope.matching.lines)) {
                  scope.matching.lines.push({
                    x1: leftCircle.x,
                    y1: leftCircle.y,
                    x2: rightCircle.x,
                    y2: rightCircle.y,
                    circleA: leftCircle,
                    circleB: rightCircle
                  });
                }

                await sleep(200);
              }


              scope.$apply?.();
              await sleep(500);

              if (Array.isArray(scope.matching.lines) && scope.matching.lines.length > 0) {
                angularSuccess = true;
              }
            }
          } catch (e) {
            console.error('Angular模型操作失败:', e);
          }
        }


        if (angularSuccess) continue;


        console.log('尝试DOM操作方式');


        let leftCircles = [];
        let rightCircles = [];


        leftCircles = Array.from(matchingElement.querySelectorAll('circle[data-circle="A"]'));
        rightCircles = Array.from(matchingElement.querySelectorAll('circle[data-circle="B"]'));


        if (leftCircles.length === 0 || rightCircles.length === 0) {
          const allCircles = matchingElement.querySelectorAll('circle[ng-repeat]');
          leftCircles = [];
          rightCircles = [];

          for (const circle of allCircles) {
            const ngRepeat = circle.getAttribute('ng-repeat');
            if (ngRepeat?.includes('matching.circles.A')) {
              leftCircles.push(circle);
            } else if (ngRepeat?.includes('matching.circles.B')) {
              rightCircles.push(circle);
            }
          }
        }


        if (leftCircles.length === 0 || rightCircles.length === 0) {
          const allCircles = matchingElement.querySelectorAll('circle');

          if (allCircles.length > 1) {

            const circlesWithCoords = Array.from(allCircles)
              .map(circle => ({
                element: circle,
                x: parseFloat(circle.getAttribute('cx')),
                y: parseFloat(circle.getAttribute('cy'))
              }))
              .filter(c => !isNaN(c.x) && !isNaN(c.y));

            if (circlesWithCoords.length > 1) {
              circlesWithCoords.sort((a, b) => a.x - b.x);
              const midX = (circlesWithCoords[0].x + circlesWithCoords[circlesWithCoords.length - 1].x) / 2;

              leftCircles = circlesWithCoords.filter(c => c.x < midX).map(c => c.element);
              rightCircles = circlesWithCoords.filter(c => c.x >= midX).map(c => c.element);
            }
          }
        }

        if (leftCircles.length === 0 || rightCircles.length === 0) continue;


        for (const {leftIndex, rightIndex} of pairs) {
          if (leftIndex < 0 || leftIndex >= leftCircles.length ||
              rightIndex < 0 || rightIndex >= rightCircles.length) continue;

          const leftCircle = leftCircles[leftIndex];
          const rightCircle = rightCircles[rightIndex];


          const leftX = parseFloat(leftCircle.getAttribute('cx'));
          const leftY = parseFloat(leftCircle.getAttribute('cy'));
          const rightX = parseFloat(rightCircle.getAttribute('cx'));
          const rightY = parseFloat(rightCircle.getAttribute('cy'));

          try {

            const createMouseEvent = (type, x, y) => new MouseEvent(type, {
              bubbles: true, cancelable: true, view: window,
              clientX: x, clientY: y
            });

            ['mousedown', 'click'].forEach(type =>
              leftCircle.dispatchEvent(createMouseEvent(type, leftX, leftY)));

            await sleep(300);


            ['mousedown', 'click'].forEach(type =>
              rightCircle.dispatchEvent(createMouseEvent(type, rightX, rightY)));

            await sleep(300);


            if (typeof angular !== 'undefined') {
              const scope = angular.element(leftCircle).scope();
              scope?.$apply?.();
            }
          } catch (e) {
            console.error('点击圆圈出错:', e);
          }
        }
      } catch (error) {
        console.error(`处理连线题出错:`, error);
      }


      await new Promise(resolve => setTimeout(resolve, 1000));
    }

    console.log('所有连线题处理完成');
  }


  function isElementVisible(element) {
    if (!element) return false;

    try {
      const style = window.getComputedStyle(element);
      return style.display !== 'none' &&
             style.visibility !== 'hidden' &&
             element.offsetParent !== null;
    } catch (e) {
      return true;
    }
  }


  async function clickElement(element) {
    if (!element) return;

    try {

      element.click();
      await sleep(100);


      const cx = parseFloat(element.getAttribute('cx')) || 0;
      const cy = parseFloat(element.getAttribute('cy')) || 0;

      const mouseEventOptions = {
        view: window,
        bubbles: true,
        cancelable: true,
        clientX: cx,
        clientY: cy
      };

      ['mousedown', 'mouseup', 'click'].forEach(type =>
        element.dispatchEvent(new MouseEvent(type, mouseEventOptions)));


      if (typeof angular !== 'undefined') {
        const scope = angular.element(element).scope();
        scope?.$apply?.();


        if (element.tagName === 'circle' && element.hasAttribute('data-index')) {
          const dataIndex = element.getAttribute('data-index');
          const dataCircle = element.getAttribute('data-circle');
          const matchingElement = element.closest('et-matching[et-index]');

          if (matchingElement && dataCircle) {
            const matchingScope = angular.element(matchingElement).scope();
            const circles = matchingScope?.matching?.circles?.[dataCircle];
            const circle = circles?.[dataIndex];

            if (circle?.select) {
              circle.select();
              matchingScope.$apply?.();
            }
          }
        }
      }
    } catch (error) {
      console.error('点击元素出错:', error);
    }
  }


  async function submitAnswers() {
    console.log('准备提交答案');


    let submitButton;
    for (let i = 0; i < 10 && !submitButton; i++) {
      try {

        const etButtons = document.querySelectorAll('et-button[right][action="item.submit()"]');
        for (const etBtn of etButtons) {
          const btn = etBtn.querySelector('button[ng-click="btn.doAction()"]');
          if (btn) {
            submitButton = btn;
            break;
          }
        }


        if (!submitButton) {
          submitButton = Array.from(document.querySelectorAll('button')).find(btn =>
            btn.textContent.trim() === 'Submit' ||
            btn.querySelector('span')?.textContent.trim() === 'Submit'
          );
        }


        if (!submitButton) {
          submitButton = document.querySelector('button[ng-click*="btn.doAction()"]');
        }


        if (!submitButton) {
          for (const etBtn of document.querySelectorAll('et-button')) {
            const btn = etBtn.querySelector('button');
            if (btn?.textContent.includes('Submit') || btn?.innerHTML.includes('Submit')) {
              submitButton = btn;
              break;
            }
          }
        }


        if (submitButton && (!submitButton.disabled && submitButton.offsetParent !== null)) {
          break;
        } else {
          submitButton = null;
        }
      } catch (error) {
        console.log('查找Submit按钮出错:', error);
      }

      if (!submitButton) {
        await sleep(1000);
      }
    }

    if (!submitButton) {
      console.log('未找到Submit按钮');
      return false;
    }

    console.log('找到Submit按钮');

    try {

      submitButton.scrollIntoView({ behavior: 'smooth', block: 'center' });
      await sleep(1000);



      submitButton.click();
      await sleep(500);


      submitButton.dispatchEvent(new MouseEvent('click', {
        bubbles: true,
        cancelable: true,
        view: window
      }));


      if (typeof angular !== 'undefined') {

        const etButtonElement = submitButton.closest('et-button');
        if (etButtonElement?.getAttribute('action') === 'item.submit()') {
          const scope = angular.element(etButtonElement).scope();
          scope?.item?.submit?.();
          scope?.$apply?.();
        }


        const scope = angular.element(submitButton).scope();
        scope?.btn?.doAction?.();
        scope?.$apply?.();
      }


      await sleep(4000);
      return await autoNextSection();
    } catch (error) {
      console.log('点击Submit按钮出错:', error);
      return false;
    }
  }


  async function autoNextSection() {
    console.log('准备自动跳转到下一章节');


    const isInIframe = window !== window.top;
    console.log(`跳转环境: ${isInIframe ? 'iframe内' : '主窗口'}`);


    if (isInIframe) {
      console.log('尝试在父窗口中执行NextSCO函数');

      try {

        const scriptForParent = document.createElement('script');
        scriptForParent.textContent = `
          try {

            if (window.parent && window.parent !== window) {
              if (typeof window.parent.NextSCO === 'function') {
                window.parent.NextSCO();
                console.log("在父窗口中成功调用NextSCO");
              } else {
                console.log("父窗口中不存在NextSCO函数");

                window.parent.location.href = 'javascript:void(0); try { NextSCO(); } catch(e) {}';
              }
            } else {
              console.log("无法访问父窗口");
            }
          } catch(e) {
            console.error("向父窗口发送NextSCO调用失败:", e);
          }
        `;
        document.body.appendChild(scriptForParent);
        document.body.removeChild(scriptForParent);


        try {
          window.parent.postMessage({ action: 'executeNextSCO' }, '*');
          console.log('已向父窗口发送postMessage请求');


          const listenerScript = document.createElement('script');
          listenerScript.textContent = `
            (function() {
              if (window.parent === window) {
                window.addEventListener('message', function(event) {
                  if (event.data && event.data.action === 'executeNextSCO') {
                    console.log('收到执行NextSCO的消息');
                    try {
                      if (typeof NextSCO === 'function') {
                        NextSCO();
                        console.log('成功执行NextSCO');
                      } else {
                        console.log('NextSCO函数不存在');
                        try {
                          location.href = 'javascript:NextSCO();';
                        } catch(e) {}
                      }
                    } catch(e) {
                      console.error('执行NextSCO失败:', e);
                    }
                  }
                });
              }
            })();
          `;
          document.body.appendChild(listenerScript);
          document.body.removeChild(listenerScript);
        } catch (e) {
          console.log('发送postMessage失败:', e);
        }


        try {

          window.top.location.href = 'javascript:void(0); try { NextSCO(); } catch(e) {}';
          console.log('已尝试改变顶层窗口location');
        } catch (e) {
          console.log('改变顶层窗口location失败:', e);
        }

        return true;
      } catch (e) {
        console.log('跳出iframe失败:', e);
      }
    }




    try {
      console.log('尝试点击页面中的javascript:NextSCO()链接');
      const navLinks = document.querySelectorAll('a[href*="javascript:NextSCO()"], a[href*="javascript:PrevSCO()"]');

      if (navLinks.length > 0) {

        const nextLink = Array.from(navLinks).find(link =>
          link.href.includes('NextSCO') && !link.href.includes('PrevSCO')
        );

        if (nextLink) {
          console.log('找到NextSCO链接,尝试点击');
          nextLink.click();
          return;
        }
      }
    } catch (e) {
      console.log('点击NextSCO链接失败:', e);
    }


    try {
      const textNodes = [];
      function findTextNodes(node) {
        if (node.nodeType === 3) {
          if (node.nodeValue.includes('javascript:NextSCO()')) {
            textNodes.push(node);
          }
        } else if (node.nodeType === 1) {
          for (let i = 0; i < node.childNodes.length; i++) {
            findTextNodes(node.childNodes[i]);
          }
        }
      }

      findTextNodes(document.body);

      if (textNodes.length > 0) {
        console.log('找到包含NextSCO文本的节点:', textNodes.length, '个');

        for (const textNode of textNodes) {
          let current = textNode.parentElement;
          while (current && current.tagName !== 'A' && current.tagName !== 'BUTTON') {
            current = current.parentElement;
          }

          if (current) {
            console.log('点击包含NextSCO文本的元素');
            current.click();
            return;
          }
        }
      }
    } catch (e) {
      console.log('查找NextSCO文本失败:', e);
    }


    try {
      console.log('尝试查找侧边栏中的蓝色箭头按钮');


      const potentialNavButtons = [
        ...document.querySelectorAll('.courseware_sidebar a, .courseware_sidebar_2 a'),
        ...document.querySelectorAll('a[class*="nav"], img[src*="arrow"], img[src*="next"]'),
        ...document.querySelectorAll('a img[src*="arrow"], a img[src*="next"]'),
        ...document.querySelectorAll('ul.c_s_3 li a'),
        ...document.querySelectorAll('li.c_s_3_2 a')
      ];





      const navButtons = Array.from(potentialNavButtons).filter(btn => {

        const rect = btn.getBoundingClientRect();
        const isAtSide = rect.left < 100 || rect.right > window.innerWidth - 100;


        try {
          const style = window.getComputedStyle(btn);
          const hasTurquoiseColor =
            style.color.includes('rgb(0, 255, 255)') ||
            style.color.includes('rgb(0, 255, 255)') ||
            style.backgroundColor.includes('rgb(0, 255, 255)') ||
            style.background.includes('rgb(0, 255, 255)') ||
            btn.innerHTML.includes('rgb(0, 255, 255)') ||
            btn.innerHTML.includes('#00ffff') ||
            btn.innerHTML.includes('cyan');


          const isArrow =
            btn.textContent.includes('→') ||
            btn.textContent.includes('▶') ||
            btn.textContent.includes('▷') ||
            btn.innerHTML.includes('arrow') ||
            (btn.querySelector('img') && (
              btn.querySelector('img').src.includes('arrow') ||
              btn.querySelector('img').src.includes('next')
            ));

          return isAtSide || hasTurquoiseColor || isArrow;
        } catch (e) {
          return isAtSide;
        }
      });

      console.log(`找到${navButtons.length}个可能的导航按钮`);


      if (navButtons.length > 0) {

        for (const btn of navButtons) {
          console.log(`点击导航按钮: ${btn.textContent || btn.className || btn.id || '未命名按钮'}`);
          btn.click();
          await new Promise(resolve => setTimeout(resolve, 500));
        }
        return;
      }
    } catch (e) {
      console.log('查找导航按钮出错:', e);
    }


    try {
      console.log('尝试直接执行NextSCO函数');
      const scriptEl = document.createElement('script');
      scriptEl.textContent = `
        try {
          if (typeof NextSCO === 'function') {
            NextSCO();
            console.log("成功执行NextSCO函数");
          } else {
            console.log("NextSCO函数未定义");
          }
        } catch(e) {
          console.error("执行NextSCO出错:", e);
        }
      `;
      document.body.appendChild(scriptEl);
      document.body.removeChild(scriptEl);


      setTimeout(() => {
        try {
          window.location.href = 'javascript:void(0); try { NextSCO(); } catch(e) {}';
        } catch (e) { }
      }, 1000);
    } catch (e) {
      console.log('执行脚本失败:', e);
    }
  }


  async function ensureCorrectContext() {

    const isInIframe = window !== window.top;
    console.log(`当前环境: ${isInIframe ? 'iframe内' : '主窗口'}`);


    if (isInIframe && window.name === 'contentFrame') {
      console.log('已在答题的iframe中,可以直接答题');
      return;
    }


    if (!isInIframe) {
      console.log('在主窗口中,尝试切换到contentFrame');


      let contentFrame = document.getElementById('contentFrame');


      if (!contentFrame) {
        const frames = document.getElementsByTagName('iframe');
        for (let i = 0; i < frames.length; i++) {
          if (frames[i].name === 'contentFrame') {
            contentFrame = frames[i];
            break;
          }
        }
      }


      if (contentFrame) {
        console.log('找到contentFrame,准备在其中执行答题');

        try {

          return executeInContentFrame(contentFrame);
        } catch (e) {
          console.error('向contentFrame执行答题失败:', e);
        }
      } else {

        const iframes = document.querySelectorAll('iframe');
        console.log(`共找到${iframes.length}个iframe`);

        for (let i = 0; i < iframes.length; i++) {
          try {
            const iframe = iframes[i];
            if (!iframe.contentDocument) continue;

            const hasQuizElements =
              iframe.contentDocument.querySelector('et-choice') ||
              iframe.contentDocument.querySelector('et-tof') ||
              iframe.contentDocument.querySelector('span.key') ||
              iframe.contentDocument.querySelector('div.key') ||
              iframe.contentDocument.querySelector('select[ng-model]') ||
              iframe.contentDocument.querySelector('button');

            if (hasQuizElements) {
              console.log(`找到可能的答题iframe: ${iframe.name || iframe.id || i}`);
              return executeInContentFrame(iframe);
            }
          } catch (e) {
            console.log(`检查iframe ${i}失败:`, e);
          }
        }

        console.log('未找到答题iframe,直接在当前窗口执行');
      }
    }
  }


  async function executeInContentFrame(frame) {
    console.log('准备在iframe中执行答题');

    try {

      if (typeof frame.contentWindow.autoSelectCorrectAnswers === 'function') {
        console.log('iframe中已存在答题函数,直接调用');
        return {
          autoSelectCorrectAnswers: frame.contentWindow.autoSelectCorrectAnswers,
          autoFillAnswers: frame.contentWindow.autoFillAnswers,
          autoSelectDropdownAnswers: frame.contentWindow.autoSelectDropdownAnswers,
          autoMatchLines: frame.contentWindow.autoMatchLines,
          submitAnswers: frame.contentWindow.submitAnswers
        };
      }



      const scriptContent = `
        if (!window.weLearnHelperInjected) {
          window.weLearnHelperInjected = true;


          window.parent.postMessage({
            action: 'iframeReady',
            frameId: '${frame.id || frame.name || 'unknown'}'
          }, '*');


          const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
          const createEvent = (type, options = {}) => new Event(type, {bubbles: true, cancelable: true, ...options});


          ${autoFillAnswers.toString()}
          ${autoSelectCorrectAnswers.toString()}
          ${autoSelectDropdownAnswers.toString()}
          ${autoMatchLines.toString()}
          ${submitAnswers.toString()}


          window.addEventListener('message', function(event) {
            if (event.data && event.data.action === 'runQuizFunctions') {
              console.log('iframe收到执行答题请求');

              const executeAsync = async () => {
                try {
                  if (event.data.step === 'selectAnswers') {
                    await autoSelectCorrectAnswers();
                    window.parent.postMessage({ action: 'stepComplete', step: 'selectAnswers' }, '*');
                  } else if (event.data.step === 'fillAnswers') {
                    autoFillAnswers();
                    window.parent.postMessage({ action: 'stepComplete', step: 'fillAnswers' }, '*');
                  } else if (event.data.step === 'selectDropdowns') {
                    autoSelectDropdownAnswers();
                    window.parent.postMessage({ action: 'stepComplete', step: 'selectDropdowns' }, '*');
                  } else if (event.data.step === 'matchLines') {
                    await autoMatchLines();
                    window.parent.postMessage({ action: 'stepComplete', step: 'matchLines' }, '*');
                  } else if (event.data.step === 'submitAnswers') {
                    await submitAnswers();
                    window.parent.postMessage({ action: 'stepComplete', step: 'submitAnswers' }, '*');
                  } else if (event.data.step === 'all') {
                    await autoSelectCorrectAnswers();
                    autoFillAnswers();
                    autoSelectDropdownAnswers();
                    await autoMatchLines();
                    await submitAnswers();
                    window.parent.postMessage({ action: 'stepComplete', step: 'all' }, '*');
                  }
                } catch (error) {
                  console.error('执行iframe中的答题函数出错:', error);
                  window.parent.postMessage({ action: 'stepError', error: error.message }, '*');
                }
              };

              executeAsync();
            }
          });
        }
      `;


      const script = document.createElement('script');
      script.textContent = scriptContent;


      try {
        frame.contentDocument.body.appendChild(script);
        frame.contentDocument.body.removeChild(script);
        console.log('已将答题脚本注入到iframe中');


        window.addEventListener('message', handleIframeMessage);


        return {
          autoSelectCorrectAnswers: () => sendCommandToIframe(frame, 'selectAnswers'),
          autoFillAnswers: () => sendCommandToIframe(frame, 'fillAnswers'),
          autoSelectDropdownAnswers: () => sendCommandToIframe(frame, 'selectDropdowns'),
          autoMatchLines: () => sendCommandToIframe(frame, 'matchLines'),
          submitAnswers: () => sendCommandToIframe(frame, 'submitAnswers')
        };
      } catch (e) {
        console.error('无法向iframe注入脚本:', e);

      }


      console.log('尝试直接在iframe中执行答题代码');

    } catch (e) {
      console.error('iframe操作失败:', e);
    }


    return null;
  }


  function handleIframeMessage(event) {
    if (event.data && event.data.action) {
      if (event.data.action === 'iframeReady') {
        console.log(`iframe已就绪: ${event.data.frameId}`);
      } else if (event.data.action === 'stepComplete') {
        console.log(`iframe完成步骤: ${event.data.step}`);
      } else if (event.data.action === 'stepError') {
        console.error(`iframe执行出错: ${event.data.error}`);
      }
    }
  }


  function sendCommandToIframe(frame, step) {
    return new Promise((resolve, reject) => {

      const timeout = setTimeout(() => {
        cleanup();
        reject(new Error(`向iframe发送${step}命令超时`));
      }, 30000);


      const messageHandler = (event) => {
        if (event.data && event.data.action === 'stepComplete' && event.data.step === step) {
          cleanup();
          resolve();
        } else if (event.data && event.data.action === 'stepError') {
          cleanup();
          reject(new Error(event.data.error || '未知iframe错误'));
        }
      };


      const cleanup = () => {
        clearTimeout(timeout);
        window.removeEventListener('message', messageHandler);
      };


      window.addEventListener('message', messageHandler);


      try {
        frame.contentWindow.postMessage({ action: 'runQuizFunctions', step: step }, '*');
        console.log(`已向iframe发送${step}命令`);
      } catch (e) {
        cleanup();
        reject(e);
      }
    });
  }


  function createIntegratedUI() {

    const globalStyle = document.createElement('style');
    globalStyle.id = 'welearn-helper-style';
    globalStyle.textContent = `
      @keyframes button-pulse {
        0% { transform: scale(1); }
        50% { transform: scale(1.03); }
        100% { transform: scale(1); }
      }

      .welearn-button {
        position: static;
        flex: 1;
        padding: 10px 15px;
        border: none;
        border-radius: 6px;
        cursor: pointer;
        font-weight: bold;
        font-size: 14px;
        transition: all 0.3s ease;
        text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
        box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.1);
      }

      .welearn-button:hover {
        transform: translateY(-2px);
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2), 0 2px 5px rgba(0, 0, 0, 0.1);
      }

      .welearn-button:active {
        transform: translateY(1px);
        box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);
      }

      .welearn-auto-button {
        background: linear-gradient(135deg, #00ff9d 0%, #00c17b 100%);
        color: rgba(0, 0, 0, 0.8);
      }

      .welearn-auto-button:hover {
        background: linear-gradient(135deg, #00ffaa 0%, #00d38a 100%);
      }

      .welearn-loop-button {
        background: linear-gradient(135deg, #4CAF50 0%, #2E7D32 100%);
        color: white;
      }

      .welearn-loop-button:hover {
        background: linear-gradient(135deg, #5CBF60 0%, #3E8D42 100%);
      }

      .welearn-loop-active {
        background: linear-gradient(135deg, #f44336 0%, #d32f2f 100%);
        animation: button-pulse 2s infinite ease-in-out;
      }

      .welearn-loop-active:hover {
        background: linear-gradient(135deg, #ff5252 0%, #e53935 100%);
      }
    `;


    const existingStyle = document.getElementById('welearn-helper-style');
    if (existingStyle) existingStyle.remove();

    document.head.appendChild(globalStyle);


    const mainPanel = document.createElement('div');
    mainPanel.id = 'welearnHelperPanel';
    mainPanel.style.cssText = `
      position: fixed;
      top: 10px;
      left: 10px;
      z-index: 10000;
      background-color: rgba(33, 33, 33, 0.85);
      border-radius: 10px;
      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
      padding: 12px;
      color: white;
      font-size: 13px;
      width: 240px;
      display: flex;
      flex-direction: column;
      gap: 10px;
      backdrop-filter: blur(5px);
      border: 1px solid rgba(255, 255, 255, 0.1);
    `;


    const titleBar = document.createElement('div');
    titleBar.style.cssText = `
      display: flex;
      justify-content: space-between;
      align-items: center;
      border-bottom: 1px solid rgba(255, 255, 255, 0.15);
      padding-bottom: 8px;
      margin-bottom: 5px;
    `;

    const title = document.createElement('div');
    title.textContent = 'Welearn助手';
    title.style.cssText = `
      font-weight: bold;
      font-size: 15px;
      color: #ffffff;
      text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
    `;


    const minimizeBtn = document.createElement('button');
    minimizeBtn.textContent = '-';
    minimizeBtn.style.cssText = `
      background: none;
      border: none;
      color: white;
      font-size: 18px;
      cursor: pointer;
      width: 24px;
      height: 24px;
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 0;
      border-radius: 50%;
      background-color: rgba(255, 255, 255, 0.1);
      transition: background-color 0.2s ease;
    `;

    minimizeBtn.onmouseover = () => {
      minimizeBtn.style.backgroundColor = 'rgba(255, 255, 255, 0.2)';
    };

    minimizeBtn.onmouseout = () => {
      minimizeBtn.style.backgroundColor = 'rgba(255, 255, 255, 0.1)';
    };

    minimizeBtn.onclick = () => {
      const content = document.getElementById('welearnHelperContent');
      if (content.style.display === 'none') {

        content.style.display = 'flex';
        minimizeBtn.textContent = '-';
      } else {

        content.style.display = 'none';
        minimizeBtn.textContent = '+';
      }
    };

    titleBar.appendChild(title);
    titleBar.appendChild(minimizeBtn);
    mainPanel.appendChild(titleBar);


    const content = document.createElement('div');
    content.id = 'welearnHelperContent';
    content.style.cssText = `
      display: flex;
      flex-direction: column;
      gap: 10px;
    `;
    mainPanel.appendChild(content);


    const buttonContainer = document.createElement('div');
    buttonContainer.style.cssText = `
      display: flex;
      gap: 10px;
    `;


    const autoAnswerButton = document.createElement('button');
    autoAnswerButton.id = 'autoAnswerButton';
    autoAnswerButton.textContent = '一键全自动';
    autoAnswerButton.className = 'welearn-button welearn-auto-button';


    const autoLoopButton = document.createElement('button');
    autoLoopButton.id = 'autoLoopButton';
    autoLoopButton.textContent = '开始自动挂机';
    autoLoopButton.className = 'welearn-button welearn-loop-button';


    autoAnswerButton.onclick = async function() {
      await runAutoAnswerProcess(false);
    };

    autoLoopButton.onclick = async function() {
      await toggleAutoLoop();
    };

    buttonContainer.appendChild(autoAnswerButton);
    buttonContainer.appendChild(autoLoopButton);
    content.appendChild(buttonContainer);


    const timerContainer = document.createElement('div');
    timerContainer.id = 'waitTimerContainer';
    timerContainer.style.cssText = `
      display: flex;
      align-items: center;
      background-color: rgba(255, 255, 255, 0.08);
      padding: 8px 10px;
      border-radius: 6px;
      border: 1px solid rgba(255, 255, 255, 0.05);
    `;


    const timeInput = document.createElement('input');
    timeInput.id = 'waitTimeInput';
    timeInput.type = 'number';
    timeInput.min = '1';
    timeInput.max = '3600';
    timeInput.value = defaultWaitTime.toString();
    timeInput.style.cssText = `
      width: 45px;
      padding: 5px;
      border-radius: 4px;
      border: 1px solid rgba(255, 255, 255, 0.2);
      text-align: center;
      margin: 0 5px;
      color: black;
      background-color: rgba(255, 255, 255, 0.9);
      font-weight: bold;
      box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
    `;


    timeInput.addEventListener('change', function() {
      const newTime = parseInt(this.value, 10);
      if (!isNaN(newTime) && newTime > 0) {
        defaultWaitTime = newTime;

        const countdownDisplay = document.getElementById('countdownDisplay');
        if (countdownDisplay) {
          const originalText = countdownDisplay.textContent;
          const originalColor = countdownDisplay.style.color;

          countdownDisplay.textContent = '已保存';
          countdownDisplay.style.color = '#4CAF50';

          setTimeout(() => {
            if (countdownDisplay) {
              countdownDisplay.textContent = originalText;
              countdownDisplay.style.color = originalColor;
            }
          }, 1000);
        }
      }
    });


    const label = document.createElement('span');
    label.textContent = '刷时长:';
    label.style.cssText = `
      margin-right: 4px;
      font-weight: 500;
      text-shadow: 0 1px 1px rgba(0, 0, 0, 0.3);
    `;


    const secondsLabel = document.createElement('span');
    secondsLabel.textContent = '秒';
    secondsLabel.style.cssText = `
      margin-right: 5px;
      font-weight: 500;
      text-shadow: 0 1px 1px rgba(0, 0, 0, 0.3);
    `;


    const statusDisplay = document.createElement('div');
    statusDisplay.id = 'countdownDisplay';
    statusDisplay.textContent = '未开始';
    statusDisplay.style.cssText = `
      margin-left: auto;
      font-weight: bold;
      color: #00ffcc;
      min-width: 60px;
      text-align: right;
      text-shadow: 0 0 10px rgba(0, 255, 204, 0.5);
    `;

    timerContainer.appendChild(label);
    timerContainer.appendChild(timeInput);
    timerContainer.appendChild(secondsLabel);
    timerContainer.appendChild(statusDisplay);
    content.appendChild(timerContainer);


    const statusContainer = document.createElement('div');
    statusContainer.style.cssText = `
      font-size: 12px;
      color: #ccc;
      text-align: center;
      padding: 5px;
      background-color: rgba(255, 255, 255, 0.05);
      border-radius: 4px;
    `;
    statusContainer.textContent = 'by恶搞之家';
    content.appendChild(statusContainer);


    const loopStatus = document.createElement('div');
    loopStatus.id = 'loopStatusIndicator';
    loopStatus.style.cssText = `
      display: none;
      align-items: center;
      justify-content: center;
      background-color: rgba(220, 20, 60, 0.2);
      padding: 6px;
      border-radius: 5px;
      margin-top: 2px;
      font-weight: bold;
      font-size: 12px;
      border: 1px solid rgba(220, 20, 60, 0.3);
    `;
    content.appendChild(loopStatus);

    return mainPanel;
  }


  async function executeWaitTimer(callback) {
    const timeInput = document.getElementById('waitTimeInput');
    const countdownDisplay = document.getElementById('countdownDisplay');


    let waitTime = parseInt(timeInput?.value || defaultWaitTime);
    if (isNaN(waitTime) || waitTime < 1) {
      waitTime = defaultWaitTime;
      if (timeInput) timeInput.value = defaultWaitTime.toString();
    } else {

      defaultWaitTime = waitTime;
    }


    if (waitTime <= 0) {
      if (typeof callback === 'function') callback();
      return;
    }


    if (countdownDisplay) {
      countdownDisplay.textContent = waitTime + ' 秒';
      countdownDisplay.style.color = '#00ffcc';
      countdownDisplay.style.display = 'block';
    }


    if (waitTimerInterval) {
      clearInterval(waitTimerInterval);
    }


    waitTimerActive = true;
    let remainingTime = waitTime;

    return new Promise(resolve => {
      waitTimerInterval = setInterval(() => {
        remainingTime--;

        if (countdownDisplay) {
          countdownDisplay.textContent = remainingTime + ' 秒';


          if (remainingTime <= 10) {
            countdownDisplay.style.color = '#ff6b6b';
          }
        }


        if (remainingTime <= 0) {
          clearInterval(waitTimerInterval);
          waitTimerInterval = null;
          waitTimerActive = false;

          if (countdownDisplay) {
            countdownDisplay.textContent = '完成!';
            countdownDisplay.style.color = '#4CAF50';


            setTimeout(() => {
              if (countdownDisplay) {
                countdownDisplay.textContent = '未开始';
                countdownDisplay.style.color = '#00ffcc';
              }
            }, 3000);
          }


          if (typeof callback === 'function') callback();
          resolve();
        }
      }, 1000);
    });
  }


  function cancelWaitTimer() {
    if (waitTimerInterval) {
      clearInterval(waitTimerInterval);
      waitTimerInterval = null;
    }

    waitTimerActive = false;

    const countdownDisplay = document.getElementById('countdownDisplay');
    if (countdownDisplay) {
      countdownDisplay.textContent = '已取消';
      countdownDisplay.style.color = '#ff9800';


      setTimeout(() => {
        if (countdownDisplay) countdownDisplay.textContent = '';
      }, 3000);
    }
  }


  function addButton() {

    if (window !== window.top) {
      console.log('当前在iframe中,不添加按钮');
      return;
    }


    removeExistingButtons();



    const uiPanel = createIntegratedUI();
    document.body.appendChild(uiPanel);


    updateButtonsState();
  }


  function updateButtonsState() {
    const loopButton = document.getElementById('autoLoopButton');
    if (loopButton) {
      if (isAutoLoopActive) {
        loopButton.textContent = '停止自动挂机';
        loopButton.className = 'welearn-button welearn-loop-active';
        showLoopStatus(true);
      } else {
        loopButton.textContent = '开始自动挂机';
        loopButton.className = 'welearn-button welearn-loop-button';
        showLoopStatus(false);
      }
    }
  }


  function showLoopStatus(isActive) {
    let statusIndicator = document.getElementById('loopStatusIndicator');
    if (!statusIndicator) return;

    if (isActive) {
      statusIndicator.innerHTML = '<span style="display:inline-block;width:10px;height:10px;background-color:red;border-radius:50%;margin-right:5px;animation:blink 1s infinite;"></span> 自动挂机中';
      statusIndicator.style.display = 'flex';


      const style = document.createElement('style');
      style.id = 'loopStatusStyle';
      style.textContent = `
        @keyframes blink {
          0% { opacity: 1; }
          50% { opacity: 0.3; }
          100% { opacity: 1; }
        }
      `;
      if (!document.getElementById('loopStatusStyle')) {
        document.head.appendChild(style);
      }
    } else {
      statusIndicator.style.display = 'none';
    }
  }


  async function toggleAutoLoop() {
    if (!isAutoLoopActive) {

      isAutoLoopActive = true;


      updateButtonsState();


      showLoopStatus(true);


      await runAutoAnswerProcess(true);
    } else {

      stopAutoLoop();
    }
  }


  function stopAutoLoop() {
    console.log('停止自动挂机');
    isAutoLoopActive = false;


    if (autoLoopTimeout) {
      clearTimeout(autoLoopTimeout);
      autoLoopTimeout = null;
    }


    cancelWaitTimer();


    updateButtonsState();


    showLoopStatus(false);
  }


  async function runAutoAnswerProcess(isLoop) {

    if (!isLoop && isAutoLoopActive) {
      console.log('自动挂机已激活,单次执行被忽略');
      return;
    }

    try {
      const answerButton = document.getElementById('autoAnswerButton');


      if (isLoop) {
        if (answerButton) {
          answerButton.textContent = '等待中...';
          answerButton.style.backgroundColor = 'orange';
        }


        await executeWaitTimer(() => {
          if (answerButton) {
            answerButton.textContent = '开始答题...';
          }
        });


        if (!isAutoLoopActive) return;
      }

      if (answerButton) {
        answerButton.textContent = '检测环境...';
        answerButton.style.backgroundColor = 'orange';
      }

      const iframeFunctions = await ensureCorrectContext();

      const selectAnswersFn = iframeFunctions ? iframeFunctions.autoSelectCorrectAnswers : autoSelectCorrectAnswers;
      const fillAnswersFn = iframeFunctions ? iframeFunctions.autoFillAnswers : autoFillAnswers;
      const selectDropdownsFn = iframeFunctions ? iframeFunctions.autoSelectDropdownAnswers : autoSelectDropdownAnswers;
      const matchLinesFn = iframeFunctions ? iframeFunctions.autoMatchLines : autoMatchLines;
      const submitAnswersFn = iframeFunctions ? iframeFunctions.submitAnswers : submitAnswers;


      if (answerButton) {
        answerButton.textContent = '答题中...';
      }
      await selectAnswersFn();


      if (answerButton) {
        answerButton.textContent = '填写空白...';
      }
      await fillAnswersFn();


      if (answerButton) {
        answerButton.textContent = '处理下拉框...';
      }
      await selectDropdownsFn();


      if (answerButton) {
        answerButton.textContent = '处理连线题...';
      }
      await matchLinesFn();


      if (answerButton) {
        answerButton.textContent = '提交中...';
      }
      const submitResult = await submitAnswersFn();


      if (!submitResult) {
        if (answerButton) {
          answerButton.textContent = '跳转中...';
          answerButton.style.backgroundColor = 'blue';
        }
        await autoNextSection();
      }


      if (isLoop && isAutoLoopActive) {
        if (answerButton) {
          answerButton.textContent = '准备下一轮...';
          answerButton.style.backgroundColor = 'purple';
        }


        console.log('等待页面加载,准备下一轮答题...');
        autoLoopTimeout = setTimeout(async () => {
          console.log('开始下一轮答题');
          if (isAutoLoopActive) {
            await runAutoAnswerProcess(true);
          }
        }, 3000);
      } else {

        if (answerButton) {
          answerButton.textContent = '已完成';
          answerButton.style.backgroundColor = 'green';


          setTimeout(() => {
            if (answerButton && !isAutoLoopActive) {
              answerButton.textContent = '一键全自动';
              answerButton.style.backgroundColor = 'rgb(0, 255, 127)';
            }
          }, 3000);
        }
      }
    } catch (error) {
      console.error('自动化流程出错:', error);

      const answerButton = document.getElementById('autoAnswerButton');
      if (answerButton) {
        answerButton.textContent = '出错了!';
        answerButton.style.backgroundColor = 'red';
      }


      if (isLoop && isAutoLoopActive) {
        console.log('自动挂机出错,10秒后重试...');
        autoLoopTimeout = setTimeout(async () => {
          console.log('重新开始挂机');
          if (isAutoLoopActive) {
            await runAutoAnswerProcess(true);
          }
        }, 10000);
      } else {

        setTimeout(() => {
          if (answerButton && !isAutoLoopActive) {
            answerButton.textContent = '一键全自动';
            answerButton.style.backgroundColor = 'rgb(0, 255, 127)';
          }
        }, 5000);
      }
    }
  }


  function removeExistingButtons() {

    const welearnPanel = document.getElementById('welearnHelperPanel');
    if (welearnPanel && welearnPanel.parentNode) {
      welearnPanel.parentNode.removeChild(welearnPanel);
    }


    const oldElements = [
      document.getElementById('autoAnswerButton'),
      document.getElementById('autoLoopButton'),
      document.getElementById('autoAnswerButtonContainer'),
      document.getElementById('autoAnswerInfoText'),
      document.getElementById('loopStatusIndicator'),
      document.getElementById('waitTimerContainer')
    ];

    oldElements.forEach(element => {
      if (element && element.parentNode) {
        element.parentNode.removeChild(element);
      }
    });


    const allFixedElements = document.querySelectorAll('*[style*="position: fixed"], *[style*="position:fixed"]');
    for (const element of allFixedElements) {

      const computedStyle = window.getComputedStyle(element);
      const top = parseInt(computedStyle.top);
      const left = parseInt(computedStyle.left);


      if (top <= 50 && left <= 300 && !element.closest('#welearnHelperPanel') &&
          (element.tagName === 'BUTTON' ||
           element.tagName === 'DIV' ||
           element.id.includes('auto') ||
           element.id.includes('button') ||
           (element.textContent && (
             element.textContent.includes('一键') ||
             element.textContent.includes('全自动') ||
             element.textContent.includes('自动') ||
             element.textContent.includes('挂机') ||
             element.textContent.includes('答题') ||
             element.textContent.includes('提交')
           ))
          )) {
        console.log('强制移除外部元素:', element.tagName, element.id || element.className, element.textContent?.substring(0, 20));
        if (element.parentNode) {
          element.parentNode.removeChild(element);
        }
      }
    }


    const loopStyle = document.getElementById('loopStatusStyle');
    if (loopStyle && loopStyle.parentNode) {
      loopStyle.parentNode.removeChild(loopStyle);
    }


    cancelWaitTimer();

    console.log('移除已存在的UI元素');
  }


  function clearExternalButtons() {

    const allButtons = document.querySelectorAll('button');
    allButtons.forEach(button => {

      if (button.closest('#welearnHelperPanel')) {
        return;
      }


      if (button.textContent && (
        button.textContent.includes('一键') ||
        button.textContent.includes('全自动') ||
        button.textContent.includes('自动') ||
        button.textContent.includes('挂机') ||
        button.textContent === '一键全自动' ||
        button.textContent === '开始自动挂机' ||
        button.textContent === '停止自动挂机'
      )) {
        console.log('强制移除外部按钮:', button.textContent);
        if (button.parentNode) {
          button.parentNode.removeChild(button);
        }
      }
    });


    const containers = document.querySelectorAll('div[style*="position: fixed"], div[style*="position:fixed"]');
    containers.forEach(container => {

      if (container.id === 'welearnHelperPanel' || container.closest('#welearnHelperPanel')) {
        return;
      }


      const style = window.getComputedStyle(container);
      const top = parseInt(style.top);
      const left = parseInt(style.left);


      if (top <= 50 && left <= 50) {

        const innerButtons = container.querySelectorAll('button');
        if (innerButtons.length > 0) {
          console.log('移除外部按钮容器:', container.id || container.className);
          if (container.parentNode) {
            container.parentNode.removeChild(container);
          }
        }
      }
    });


    const buttonContainer = document.getElementById('autoAnswerButtonContainer');
    if (buttonContainer) {
      console.log('移除autoAnswerButtonContainer');
      buttonContainer.parentNode.removeChild(buttonContainer);
    }
  }


  window.addEventListener('beforeunload', () => {
    stopAutoLoop();
  });


  let observer;

  function setupObserver() {

    if (observer) {
      observer.disconnect();
    }


    observer = new MutationObserver((mutations) => {

      clearExternalButtons();


      const hasPanel = document.getElementById('welearnHelperPanel');
      const hasButton = document.getElementById('autoAnswerButton');


      if ((!hasPanel || !hasButton) && window === window.top) {
        console.log('DOM变化检测到面板或按钮不存在,添加面板');

        removeExistingButtons();

        addButton();
      }


      setTimeout(clearExternalButtons, 100);
    });


    if (window === window.top) {
      observer.observe(document.body, {
        childList: true,
        subtree: true
      });


      clearExternalButtons();
    }
  }


  function setupPageListeners() {

    window.removeEventListener('load', handlePageLoad);


    window.addEventListener('load', handlePageLoad);


    if (window === window.top) {

      let lastUrl = window.location.href;
      const checkURLChange = () => {
        if (lastUrl !== window.location.href) {
          console.log('URL已变化,重新添加按钮');
          lastUrl = window.location.href;


          setTimeout(() => {
            removeExistingButtons();
            addButton();
          }, 1000);
        }
      };


      setInterval(checkURLChange, 1000);
    }
  }


  function handlePageLoad() {
    console.log('页面加载完成,检查按钮');

    if (window === window.top) {
      removeExistingButtons();
      addButton();
    }
  }


  function initialize() {

    if (window.weLearnHelperInitialized) {
      console.log('助手已初始化,跳过');
      return;
    }

    window.weLearnHelperInitialized = true;
    console.log('初始化WeLearn助手');


    if (window === window.top) {
      removeExistingButtons();
      addButton();
      setupObserver();
      setupPageListeners();
    }
  }


  initialize();


  async function simulateHTML5DragDrop(sourceElement, targetElement) {
    if (!sourceElement || !targetElement) return;

    console.log('使用HTML5拖放API模拟拖拽');

    try {

      const dragStartEvent = new DragEvent('dragstart', {
        bubbles: true,
        cancelable: true,
        dataTransfer: new DataTransfer()
      });


      dragStartEvent.dataTransfer.setData('text/plain', 'dragged');


      sourceElement.dispatchEvent(dragStartEvent);
      await new Promise(resolve => setTimeout(resolve, 200));


      const dragOverEvent = new DragEvent('dragover', {
        bubbles: true,
        cancelable: true,
        dataTransfer: dragStartEvent.dataTransfer
      });
      targetElement.dispatchEvent(dragOverEvent);
      await new Promise(resolve => setTimeout(resolve, 200));


      const dropEvent = new DragEvent('drop', {
        bubbles: true,
        cancelable: true,
        dataTransfer: dragStartEvent.dataTransfer
      });
      targetElement.dispatchEvent(dropEvent);


      const dragEndEvent = new DragEvent('dragend', {
        bubbles: true,
        cancelable: true,
        dataTransfer: dragStartEvent.dataTransfer
      });
      sourceElement.dispatchEvent(dragEndEvent);

      console.log('HTML5拖放事件序列完成');
    } catch (e) {
      console.error('HTML5拖放模拟失败:', e);
    }
  }


  async function simulateMouseDrag(sourceElement, targetElement, coords) {
    if (!sourceElement || !targetElement) return;

    console.log('使用鼠标事件模拟拖拽');

    const { fromX, fromY, toX, toY } = coords;

    try {

      const mouseDownEvent = new MouseEvent('mousedown', {
        bubbles: true,
        cancelable: true,
        view: window,
        clientX: fromX,
        clientY: fromY,
        button: 0
      });
      sourceElement.dispatchEvent(mouseDownEvent);
      await new Promise(resolve => setTimeout(resolve, 100));



      const steps = 5;
      for (let i = 1; i <= steps; i++) {
        const moveX = fromX + (toX - fromX) * (i / steps);
        const moveY = fromY + (toY - fromY) * (i / steps);

        const mouseMoveEvent = new MouseEvent('mousemove', {
          bubbles: true,
          cancelable: true,
          view: window,
          clientX: moveX,
          clientY: moveY,
          button: 0
        });
        document.elementFromPoint(moveX, moveY)?.dispatchEvent(mouseMoveEvent);
        await new Promise(resolve => setTimeout(resolve, 50));
      }


      const mouseUpEvent = new MouseEvent('mouseup', {
        bubbles: true,
        cancelable: true,
        view: window,
        clientX: toX,
        clientY: toY,
        button: 0
      });
      targetElement.dispatchEvent(mouseUpEvent);

      console.log('鼠标拖拽事件序列完成');
    } catch (e) {
      console.error('鼠标拖拽模拟失败:', e);
    }
  }


  async function simulateDragDrop(sourceElement, targetElement, coords) {
    if (!sourceElement || !targetElement) return;

    console.log('使用组合事件模拟拖拽');

    const { fromX, fromY, toX, toY } = coords;

    try {

      sourceElement.dispatchEvent(new MouseEvent('mousedown', {
        bubbles: true,
        cancelable: true,
        view: window,
        clientX: fromX,
        clientY: fromY
      }));

      await new Promise(resolve => setTimeout(resolve, 100));


      const dragStartEvent = new Event('dragstart', {bubbles: true, cancelable: true});
      sourceElement.dispatchEvent(dragStartEvent);

      await new Promise(resolve => setTimeout(resolve, 100));


      document.dispatchEvent(new MouseEvent('mousemove', {
        bubbles: true,
        cancelable: true,
        view: window,
        clientX: toX,
        clientY: toY
      }));

      await new Promise(resolve => setTimeout(resolve, 100));


      targetElement.dispatchEvent(new Event('dragover', {bubbles: true, cancelable: true}));

      await new Promise(resolve => setTimeout(resolve, 100));


      targetElement.dispatchEvent(new Event('drop', {bubbles: true, cancelable: true}));


      sourceElement.dispatchEvent(new Event('dragend', {bubbles: true, cancelable: true}));


      targetElement.dispatchEvent(new MouseEvent('mouseup', {
        bubbles: true,
        cancelable: true,
        view: window,
        clientX: toX,
        clientY: toY
      }));

      console.log('组合拖拽事件序列完成');
    } catch (e) {
      console.error('组合拖拽模拟失败:', e);
    }
  }
})();