import db from '../../sql.mjs';
import lib from '../../lib.mjs';

export default router => {
  router.group(/^\/api\/v2\/admin\/(?<postid>\d+)\/tags/, group => {
    group.get(/$/, lib.loggedin, async (req, res) => {
      // get tags
      if(!req.params.postid) {
        return res.json({
          success: false,
          msg: 'missing postid'
        });
      }

      return res.json({
        success: true,
        tags: await lib.getTags(+req.params.postid)
      });
    });

    group.post(/$/, lib.loggedin, async (req, res) => {
      // assign and/or create tag
      if(!req.params.postid || !req.post.tagname) {
        return res.json({
          success: false,
          msg: 'missing postid or tag'
        });
      }

      const postid = +req.params.postid;
      const tagname = req.post.tagname?.trim();
  
      if(tagname.length > 70) {
        return res.json({
          success: false,
          msg: 'tag is too long!'
        });
      }
  
      try {
        let tagid = (await db`
          select id
          from "tags"
          where normalized = slugify(${tagname})
        `)?.[0]?.id;

        if(!tagid) { // create new tag
          tagid = (await db`
            insert into "tags" ${
              db({
                tag: tagname
              })
            }
            returning id
          `)[0].id;
        }

        await db`
          insert into "tags_assign" ${
            db({
              tag_id: +tagid,
              item_id: +postid,
              user_id: +req.session.id
            })
          }
        `;
      } catch(err) {
        return res.json({
          success: false,
          msg: err.message,
          tags: await lib.getTags(postid)
        });
      }

      return res.json({
        success: true,
        postid: postid,
        tag: tagname,
        tags: await lib.getTags(postid)
      });
    });

    group.put(/\/toggle$/, lib.loggedin, async (req, res) => {
      // xD
      if(!req.params.postid) {
        return res.json({
          success: false,
          msg: 'missing postid'
        });
      }

      const postid = +req.params.postid;

      if(!(await lib.getTags(postid)).filter(tag => [1,2].includes(tag.id)).length) {
        // insert
        await db`
          insert into "tags_assign" ${
            db({
              item_id: +postid,
              tag_id: 1,
              user_id: +req.session.id
            })
          }
        `;
      }
      else {
        // update
        await db`
          update "tags_assign"
          set tag_id = (array[2,1])[tag_id]
          where tag_id = any(array[1,2])
          and item_id = ${+postid}
        `;
      }

      return res.json({
        success: true,
        tags: await lib.getTags(postid)
      });
    });

    group.delete(/\/(?<tagname>.*)/, lib.auth, async (req, res) => {
      // delete tag
      if(!req.params.postid || !req.params.tagname) {
        return res.json({
          success: false,
          msg: 'missing postid or tagname'
        });
      }

      const postid = +req.params.postid;
      const tagname = decodeURIComponent(req.params.tagname);

      if(tagname == 'sfw' || tagname == 'nsfw' || tagname == 'hentai' || tagname == 'audio') {
        return res.json({
          success: false,
          msg: 'blacklisted',
          tags: await lib.getTags(postid)
        });
      }

      const tags = await lib.getTags(postid);

      const tagid = tags.filter(t => t.tag === tagname)[0]?.id ?? null;
      
      if(!tagid) {
        return res.json({
          success: false,
          msg: 'tag is not assigned',
          tags: await lib.getTags(postid)
        });
      }

      let q = await db`
        delete from "tags_assign"
        where tag_id = ${+tagid}
        and item_id = ${+postid}
        ${ req.session.level < 50
          ? db`and user_id = ${+req.session.id}`
          : db``
        }
      `;
      const reply = !!q;

      return res.json({
        success: reply,
        tagid,
        tags: await lib.getTags(postid)
      })
    });

  });

  return router;
};