import * as fs from "fs";
import config from "../../config.js";
import type { ueuse } from "types/types";

const initialFile: Array<string> = [];

// コマンド読み込み
import Info from "./info.js";
import Help from "./help.js";
import Follow from "./follow.js";
import UnFollow from "./unfollow.js";
import Weather from "./weather.js";
import Report from "./report.js";
import Terms from "./legal/terms.js"
import PrivacyPolicy from "./legal/privacy.js";
import Delete from "./delete.js";
import MakeItAQuote from "./miq/main.js";
import MiQPermission from "./miq/permission.js";
import MiQAllow from "./miq/allow.js";

// 初期化
if (!fs.existsSync("data/alreadyCommands.json")) {
  fs.writeFileSync(
    "data/alreadyCommands.json",
    JSON.stringify(initialFile),
    "utf-8",
  );
}

// 対応済みユーズ一覧
const alreadyCommands: Array<string> = JSON.parse(fs.readFileSync("data/alreadyCommands.json", "utf-8"));

function cutAfterChar(str: string, char: string) {
  const index = str.indexOf(char);

  if (index === -1) {
    return "";
  }

  return str.substring(index + 1);
}

async function commandSearch(text: string) {
  // /のある行を特定
  const lines = text.split(/\n/);
  let slashLine: number = -1;
  for (let i = 0; i < lines.length; i++) {
    if (lines[i].indexOf("/") !== -1) {
      slashLine = i;
    }
  }

  // /がない場合は無を返答
  if (slashLine === -1) {
    return "";
  }

  // BOTのユーザーIDを取得
  const userid: string = (await (await fetch(`${config.uwuzu.host}/api/me/`, {
    method: "POST",
    cache: "no-store",
    body: JSON.stringify({
      token: config.uwuzu.apiToken,
    }),
  })).json()).userid;

  // BOTへのメンションを削除
  let slashLineText = lines[slashLine];
  slashLineText = slashLineText.replace(`@${userid}`, "");

  // /以降の文字を取得
  slashLineText = cutAfterChar(slashLineText, "/");

  // 前後の空白を削除
  slashLineText = slashLineText.trimStart().trimEnd();

  return slashLineText;
}

export async function Reply(text: string, reply: string) {
  const req = await fetch(`${config.uwuzu.host}/api/ueuse/create`, {
    method: "POST",
    body: JSON.stringify({
      token: config.uwuzu.apiToken,
      text: text,
      replyid: reply,
    }),
    cache: "no-store",
  });

  const res = await req.json();

  return res;
}

function alreadyAdd(data: string) {
  alreadyCommands[alreadyCommands.length] = data;

  fs.writeFileSync(
    "data/alreadyCommands.json",
    JSON.stringify(alreadyCommands),
    "utf-8",
  );
}

export default async function Commands() {
  const mentionsReq = await fetch(
    `${config.uwuzu.host}/api/ueuse/mentions`, {
      method: "POST",
      body: JSON.stringify({
        token: config.uwuzu.apiToken,
      }),
      cache: "no-store",
    }
  );

  const mentions: { [key: string]: ueuse } = await mentionsReq.json();

  console.log("----------------");
  console.log("コマンド処理");

  for (const key in mentions) {
    if (mentions.hasOwnProperty(key)) {
      const data = mentions[key];

      // 除外ユーズ
      if (data.text === undefined) {
        break;
      }

      if (alreadyCommands.indexOf(data.uniqid) !== -1) {
        break;
      }

      if (
        data.text.charAt(0) === "!" ||
        data.text.charAt(0) === "！" ||
        data.abi === "ignore"
      ) {
        break;
      }

      if (data.text.indexOf("/") === -1) {
        break;
      }

      // コマンド処理
      console.log("--------");

      const commandName = await commandSearch(data.text);

      alreadyAdd(data.uniqid);

      switch (commandName) {
        case "info":
          Info(data);
          break;
        case "help":
          Help(data);
          break;
        case "legal terms":
          Terms(data);
          break;
        case "legal privacy":
          PrivacyPolicy(data);
          break;
        case "report":
          Report(data);
          break;
        case "follow":
          Follow(data);
          break;
        case "unfollow":
          UnFollow(data);
          break;
        case "weather":
          Weather(data);
          break;
        case "miq":
          MakeItAQuote(data);
          break;
        case "miq permission":
          MiQPermission(data);
          break;
        case "miq allow":
          MiQAllow(data);
          break;
        case "delete":
          Delete(data);
          break;
        default:
          const reply = await Reply(`
          不明なコマンドです。
          コマンド実行を除外する場合は1文字目に\`!\`を入れてください。
          `, data.uniqid);

          console.log("未対応コマンド: ", reply);
          break;
      }
    }
  }
}
