import { promises as fs } from "fs";
import { exec } from "child_process";
import cfg from "../config.mjs";
import sql from "../sql.mjs";
import lib from "../lib.mjs";

const cleanTags = async () => {
  const tags = await sql("tags").leftJoin("tags_assign", "tags_assign.tag_id", "tags.id").whereNull("tags_assign.item_id");
  if(tags.length === 0)
    return 0;
  
  let deleteTag = sql("tags");
  let dtags = 0;
  tags.forEach(tag => {
    if(["sfw", "nsfw"].includes(tag.tag.toLowerCase()))
      return dtags;
    deleteTag = deleteTag.orWhere("id", tag.id);
    dtags++;
  });
  await deleteTag.del();
  return dtags;
};

const countf0cks = async () => {
  const tagged = (await sql("items").whereRaw("id in (select item_id from tags_assign group by item_id)").count("* as total"))[0].total;
  const untagged = (await sql("items").whereRaw("id not in (select item_id from tags_assign group by item_id)").count("* as total"))[0].total;
  const sfw = (await sql("items").whereRaw("id in (select item_id from tags_assign where tag_id = 1 group by item_id)").count("* as total"))[0].total;
  const nsfw = (await sql("items").whereRaw("id in (select item_id from tags_assign where tag_id = 2 group by item_id)").count("* as total"))[0].total;
  return {
    tagged,
    untagged,
    total: tagged + untagged,
    sfw,
    nsfw
  };
};

export default async bot => {

  return [{
    name: "f0ck",
    call: /^\!f0ck .*/i,
    active: true,
    level: 100,
    f: async e => {
      switch(e.args[0]) {
        case "stats":
          const dirs = {
            b: await fs.readdir("./public/b"),
            t: await fs.readdir("./public/t")
          };
          const sizes = {
            b: lib.formatSize((await Promise.all(dirs.b.map(async file => (await fs.stat(`./public/b/${file}`)).size))).reduce((a, b) => b + a)),
            t: lib.formatSize((await Promise.all(dirs.t.map(async file => (await fs.stat(`./public/t/${file}`)).size))).reduce((a, b) => b + a)),
          };
          return e.reply(`${dirs.b.length} f0cks: ${sizes.b}, ${dirs.t.length} thumbnails: ${sizes.t}`);
        case "limit":
          return e.reply(`up to ${lib.formatSize(cfg.main.maxfilesize)} (${lib.formatSize(cfg.main.maxfilesize * 2.5)} for admins)`);
        case "thumb":
          const rows = await sql("items").select("id");
          const dir = (await fs.readdir("./public/t")).filter(d => d.endsWith(".png")).map(e => +e.split(".")[0]);
          const tmp = [];
          for(let row of rows)
            !dir.includes(row.id) ? tmp.push(row.id) : null;
          e.reply(`${tmp.length}, ${rows.length}, ${dir.length}`);
        break;
        case "cache":
          cfg.websrv.cache = !cfg.websrv.cache;
          return e.reply(`Cache is ${cfg.websrv.cache ? "enabled" : "disabled"}`);
        break;
        case "uptime":
          exec('sudo systemctl status f0ck', (err, stdout) => {
            if(!err)
              return e.reply(stdout.split('\n')[2].trim().replace("Active: active (running)", "i'm active"));
          });
        break;
        case "restart":
          e.reply("hay hay patron, hemen!");
          exec("sudo systemctl restart f0ck");
        break;
        case "cleanTags":
          const tags = await cleanTags();
          e.reply(tags + " tags removed");
        break;
        case "status":
          const tmpc = await countf0cks();
          e.reply(`tagged: ${tmpc.tagged}; untagged: ${tmpc.untagged}; sfw: ${tmpc.sfw}; nsfw: ${tmpc.nsfw}; total: ${tmpc.total}`);
        break;
        default:
          return;
      }
    }
  }]
};
