import sql from "../sql.mjs";
import cfg from "../config.mjs";
import { getLevel } from "../admin.mjs";

const getTags = async itemid => await sql("tags_assign")
  .leftJoin("tags", "tags.id", "tags_assign.tag_id")
  .where("tags_assign.item_id", itemid)
  .select("tags.id", "tags.tag");

export default async bot => {
  return [{
    name: "tags show",
    call: /^\!tags show \d+$/i,
    active: true,
    level: 100,
    f: async e => {
      const id = +e.args[1];
      if(!id)
        return e.reply("lol no");
      const tags = (await getTags(id)).map(t => t.tag);
      if(tags.length === 0)
        return e.reply(`item ${cfg.main.url}/${id} has no tags!`);
      return e.reply(`item ${cfg.main.url}/${id} is tagged as: ${tags.join(', ')}`);
    }
  }, {
    name: "tags add",
    call: /^\!tags add \d+ .*/i,
    active: false,
    level: 100,
    f: async e => {
      const id = +e.args[1];
      if(!id)
        return e.reply("lol no");

      const tags = (await getTags(id)).map(t => t.tag);
      
      const newtags = (e.message.includes(",")
        ? e.args.splice(2).join(" ").trim().split(",")
        : e.args.splice(2)).filter(t => !tags.includes(t) && t.length > 0);

      if(newtags.length === 0)
        return e.reply("no (new) tags provided");

      await Promise.all(newtags.map(async ntag => {
        try {
          let tagid;
          const tag_exists = await sql("tags").select("id", "tag").where("tag", ntag);
          if(tag_exists.length === 0) { // create new tag
            tagid = (await sql("tags").insert({
              tag: ntag
            }))[0];
          }
          else {
            tagid = tag_exists[0].id;
          }
          return await sql("tags_assign").insert({
            tag_id: tagid,
            item_id: id,
            prefix: `${e.user.prefix}${e.channel}`
          });
        } catch(err) {
          console.error(err);
        }
      }));

      const ntags = (await getTags(id)).map(t => t.tag);
      if(ntags.length === 0)
        return e.reply(`item ${cfg.main.url}/${id} has no tags!`);
      return e.reply(`item ${cfg.main.url}/${id} is now tagged as: ${ntags.join(', ')}`);
    }
  }, {
    name: "tags remove",
    call: /^\!tags remove \d+ .*/i,
    active: false,
    level: 100,
    f: async e => {
      const id = +e.args[1];
      if(!id)
        return e.reply("lol no");
      
      const tags = await getTags(id);

      const removetags = (e.message.includes(",")
        ? e.args.splice(2).join(" ").trim().split(",")
        : e.args.splice(2)).filter(t => t.length > 0);
      
      if(removetags.length === 0)
        return e.reply("no tags provided");

      const res = await Promise.all(removetags.map(async rtag => {
        const tagid = tags.filter(t => t.tag === rtag)[0]?.id ?? null;
        if(!tagid || tagid?.length === 0) {
          return {
            success: false,
            tag: rtag,
            msg: "tag is not assigned"
          };
        }
        
        let q = sql("tags_assign").where("tag_id", tagid).andWhere("item_id", id).del();
        if(getLevel(e.user).level < 50)
          q = q.andWhere("prefix", `${e.user.prefix}${e.channel}`);

        return {
          success: !!(await q),
          tag: rtag,
          tagid: tagid
        };
      }));

      e.reply(JSON.stringify(res));

      const ntags = (await getTags(id)).map(t => t.tag);
      if(ntags.length === 0)
        return e.reply(`item ${cfg.main.url}/${id} has no tags!`);
      return e.reply(`item ${cfg.main.url}/${id} is now tagged as: ${ntags.join(', ')}`);
    }
  }]
};
