import { Request } from 'express';
import * as fs from 'fs';
import { resolve } from 'path';
import { v4 as uuidv4 } from 'uuid';
import * as puppeteer from 'puppeteer';
import { execa } from './async_import';
/**
 * 构建数据文件
 */
export function buildDataFile(
  data: string,
  businessType: string,
  dataPath: string,
  fileName?: string,
) {
  if (!fileName) {
    fileName = uuidv4().replaceAll('-', '');
  }
  if (fileName.indexOf('.json') == -1) {
    fileName += '.json';
  }
  if (!fs.existsSync(`${dataPath}/${businessType}`)) {
    fs.mkdirSync(`${dataPath}/${businessType}`);
  }
  fs.writeFileSync(`${dataPath}/${businessType}/${fileName}`, data);
}

/**
 * 从request中获取userId
 * @param req
 * @returns
 */
export function getUid(req: Request) {
  const user = req['user'] || {};
  const id = user.sub;
  return id;
}

/**
 * git提交commit
 */
export async function gitSubCommit(
  cwd: string,
  msg: string = '"feat: 增加数据"',
) {
  // 全部提交到暂存区
  await execa.execa('git add -A', {
    cwd,
    shell: true,
  });
  // 生成commit
  const args = ['-m', msg];
  await execa
    .execa('git commit', args, {
      cwd,
      shell: true,
    })
    .catch(() => {});
}

/**
 * git pull push
 */
export async function gitPullPush(cwd: string) {
  // 拉一下代码,采用pull --rebase
  await execa.execa('git pull --rebase origin master', {
    cwd,
    shell: true,
  });
  // 推代码
  await execa.execa('git push origin master', {
    cwd,
    shell: true,
  });
}

/**
 * gitee热更新
 */
export async function giteeHotUpdate(projectName: string) {
  const browser = await puppeteer.launch({
    // 此处可以使用 false 有头模式进行调试, 调试完注释即可
    // headless: false,
    args: ['--no-sandbox'],
  });
  const page = await browser.newPage();
  await page.goto('https://gitee.com/login');

  // 1. 获取账号input，自动输入
  const accountElements = await page.$x('//*[@id="user_login"]');
  //  🚨需要设置为自己的gitee账户🚨
  await accountElements[0].type('13554468370');

  // 2. 获取密码input，自动输入
  const pwdElements = await page.$x('//*[@id="user_password"]');
  // 🚨需要设置自己的gitee密码🚨
  await pwdElements[0].type('lzh001520258');

  // 3. 获取登录按钮，触发点击事件
  const loginButtons = await page.$x(
    '//*[@class="git-login-form-fields"]/div[4]/input',
  );
  await (loginButtons[0] as any).click();

  // 4. 等待登录成功
  await page.waitForTimeout(1000);
  // 🚨需要设置自己的gitee pages页面🚨
  await page.goto(`https://gitee.com/ctxzl/${projectName}/pages`, {
    waitUntil: 'domcontentloaded',
  });

  // 5. 监听触发的确认弹框，并点击确认
  await page.on('dialog', async (dialog) => {
    dialog.accept();
  });

  await page.waitForXPath('//*[@id="pages-branch"]/div[6]');
  // 6. 点击更新按钮，并弹出确认弹窗
  const updateButtons = await page.$x('//*[@id="pages-branch"]/div[6]');
  await (updateButtons[0] as any).click();
  await page.waitForTimeout(2000);

  // 8.更新完毕，关闭浏览器
  browser.close();
}

const taskMap = {};

export function queueTask(interval, callback) {
  let lastTime = 0;
  let timer = null;
  return (force, ...params) => {
    if (force) {
      callback(...params);
      return;
    }
    const now = Date.now();
    if (now - lastTime > interval) {
      // 如果当前时间减去上次间隔的时间已经大于间隔的时间则立即执行
      if (timer) {
        // 如果有定时器或者定时器正在执行则直接返回
        return;
      }
      lastTime = now;
      callback(...params);
    } else {
      // 否则设置定时器到下一个节点执行，如果前面已经有过定时器则不用在继续
      if (timer) {
        return;
      }
      timer = setTimeout(
        () => {
          callback(...params);
          lastTime = Date.now();
          timer = null;
        },
        interval - now + lastTime,
      );
    }
  };
}

export const giteeHotUpdateTask = queueTask(300000, giteeHotUpdate);

/**
 * 任务定制器缓存
 * @param interval
 * @param callback
 * @param params
 * @returns
 */
export function queueTaskRun(interval, callback) {
  if (!taskMap[callback]) {
    taskMap[callback] = queueTask(interval, callback);
  }
  return taskMap[callback];
}

export function getDate(date = new Date()) {
  date.getMilliseconds();
  return {
    year: date.getFullYear(),
    month: date.getMonth() + 1,
    date: date.getDate(),
    hour: date.getHours(),
    minutes: date.getMinutes(),
    seconds: date.getSeconds(),
    milliseconds: date.getMilliseconds(),
  };
}

export function frontDay(n) {
  const timeStamp = Date.now();
  const frontTimeStamp = timeStamp - n * 86400000;
  return frontTimeStamp;
}

export function backDay(n) {
  const timeStamp = Date.now();
  const backTimeStamp = timeStamp + n * 86400000;
  return backTimeStamp;
}

export function removeStaticFile(fileDir: 'screenshot', fileName: string) {
  fs.rmSync(resolve(__dirname, `../../${fileDir}`, fileName));
}

/**
 * 从脚本中获取
 * @param scriptText
 * @param varName
 * @returns
 */
export function getVarFromScript(scriptText, varName) {
  let value = null;
  try {
    value = eval(`(function anonymous() {${scriptText} return ${varName};})()`);
  } catch {
    return value;
  }
  return value;
}
