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

export default (router, tpl) => {
  router.get(/^\/login(\/)?$/, async (req, res) => {
    if(req.cookies.session) {
      return res.reply({
        body: tpl.render('error', {
          message: "you're already logged in lol",
          tmp: null
        }, req)
      });
    }
    res.reply({
      body: tpl.render("login", { theme: req.cookies.theme ?? "f0ck" })
    });
  });
  
  router.post(/^\/login(\/)?$/, async (req, res) => {
    const user = await db`
      select *
      from "user"
      where "login" = ${req.post.username.toLowerCase()}
      limit 1
    `;
    if(user.length === 0)
      return res.reply({ body: "user doesn't exist or wrong password" });
    if(!(await lib.verify(req.post.password, user[0].password)))
      return res.reply({ body: "user doesn't exist or wrong password" });
    const stamp = ~~(Date.now() / 1e3);

    /*await db`
      delete from user_sessions
      where last_used <= ${(Date.now() - 6048e5)}
      and kmsi = 0
    `;*/
  
    const session = lib.md5(lib.createID());
    const blah = {
      user_id: user[0].id,
      session: lib.md5(session),
      browser: req.headers["user-agent"],
      created_at: stamp,
      last_used: stamp,
      kmsi: typeof req.post.kmsi !== 'undefined' ? 1 : 0
    };

    await db`
      insert into "user_sessions" ${
        db(blah, 'user_id', 'session', 'browser', 'created_at', 'last_used', 'kmsi')
      }
    `;

    return res.writeHead(301, {
      "Cache-Control": "no-cache, public",
      "Set-Cookie": `session=${session}; Path=/; Expires=Fri, 31 Dec 9999 23:59:59 GMT`,
      "Location": "/"
    }).end();
  });
  
  router.get(/^\/logout$/, lib.loggedin, async (req, res) => {
    const usersession = await db`
      select *
      from "user_sessions"
      where id = ${+req.session.sess_id}
    `;
    if(usersession.length === 0)
      return res.reply({ body: "nope 2" });
    
    await db`
      delete from "user_sessions"
      where id = ${+req.session.sess_id}
    `;
    return res.writeHead(301, {
      "Cache-Control": "no-cache, public",
      "Set-Cookie": "session=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT",
      "Location": "/"
    }).end();
  });
  
  router.get(/^\/login\/pwdgen$/, async (req, res) => {
    res.reply({
      body: "<form action=\"/login/pwdgen\" method=\"post\"><input type=\"text\" name=\"pwd\" placeholder=\"pwd\" /><input type=\"submit\" value=\"f0ck it\" /></form>"
    });
  });
  router.post(/^\/login\/pwdgen$/, async (req, res) => {
    res.reply({
      body: await lib.hash(req.post.pwd)
    });
  });

  router.get(/^\/admin(\/)?$/, lib.auth, async (req, res) => { // frontpage

    res.reply({
      body: tpl.render("admin", {
        totals: await lib.countf0cks(),
        session: req.session,
        tmp: null
      }, req)
    });
  });
  
  router.get(/^\/admin\/sessions(\/)?$/, lib.auth, async (req, res) => {
    const rows = await db`
      select "user_sessions".*, "user".user
      from "user_sessions"
      left join "user" on "user".id = "user_sessions".user_id
      order by "user_sessions".last_used desc
    `;
  
    res.reply({
      body: tpl.render("admin/sessions", {
        session: req.session,
        sessions: rows,
        totals: await lib.countf0cks(),
        tmp: null
      }, req)
    });
  });

  router.get(/^\/admin\/log(\/)?$/, lib.auth, async (req, res) => {
    exec("journalctl -qeu f0ck --no-pager", (err, stdout) => {
      res.reply({
        body: tpl.render("admin/log", {
          log: stdout.split("\n").slice(0, -1),
          tmp: null
        }, req)
      });
    });
  });

  router.get(/^\/admin\/recover\/?/, lib.auth, async (req, res) => {
    if(req.url.qs?.id) {
      const id = +req.url.qs.id;
      const f0ck = await db`
        select dest, mime
        from "items"
        where
          id = ${id} and
          active = 'false'
        limit 1
      `;
      if(f0ck.length === 0) {
        return res.reply({
          body: `f0ck ${id}: f0ck not found`
        });
      }

      await db`update "items" set active = 'true' where id = ${id}`;

      await fs.copyFile(`./deleted/b/${f0ck[0].dest}`, `./public/b/${f0ck[0].dest}`).catch(_=>{});
      await fs.copyFile(`./deleted/t/${id}.webp`, `./public/t/${id}.webp`).catch(_=>{});
      await fs.unlink(`./deleted/b/${f0ck[0].dest}`).catch(_=>{});
      await fs.unlink(`./deleted/t/${id}.webp`).catch(_=>{});

      if(f0ck[0].mime.startsWith('audio')) {
        await fs.copyFile(`./deleted/ca/${id}.webp`, `./public/ca/${id}.webp`).catch(_=>{});
        await fs.unlink(`./deleted/ca/${id}.webp`).catch(_=>{});
      }

      return res.reply({
        body: `f0ck ${id} recovered. <a href="/admin/recover">back</a>`
      });
    }

    const _posts = await db`
      select id, mime, username
      from "items"
      where
        active = 'false'
      order by id desc
    `;

    if(_posts.length === 0) {
      return res.reply({
        body: 'blah'
      });
    }

    const posts = await Promise.all(_posts.map(async p => ({
      ...p,
      thumbnail: (await fs.readFile(`./deleted/t/${p.id}.webp`)).toString('base64')
    })));

    res.reply({
      body: tpl.render('admin/recover', {
        posts,
        tmp: null
      }, req)
    });
  });

  return router;
};
