/* eslint-disable no-bitwise */
/* eslint-disable no-continue */
import jwt from 'jsonwebtoken';
import { TextChannel } from 'eris';
import { LocalStorage, Route, Server } from '../../../class';
import { ScoreHistoricalInterface, ScoreHistoricalRaw } from '../../../models/ScoreHistorical';
import { getTotalMessageCount } from '../../../intervals/score';

export default class Report extends Route {
  public timeout: Map<string, number>;

  public acceptedOffers: LocalStorage;

  constructor(server: Server) {
    super(server);
    this.timeout = new Map();
    this.acceptedOffers = new LocalStorage('accepted-offers');
    this.conf = {
      path: '/report',
    };
  }

  protected check(userID: string) {
    if (this.timeout.has(userID)) {
      if (this.timeout.get(userID) >= 3) {
        return true;
      }
      this.timeout.set(userID, this.timeout.get(userID) + 1);
    } else {
      this.timeout.set(userID, 1);
    }
    setTimeout(() => {
      if (this.timeout.has(userID)) {
        this.timeout.set(userID, this.timeout.get(userID) - 1);
      } else {
        this.timeout.delete(userID);
      }
    }, 30000);
    return false;
  }

  public bind() {
    this.router.all('*', (_req, res, next) => {
      res.setHeader('Access-Control-Allow-Origin', '*');
      res.setHeader('Access-Control-Allow-Methods', '*');
      res.setHeader('Access-Control-Allow-Headers', '*');
      next();
    });

    this.router.post('/hard', async (req, res) => {
      try {
        if (!req.headers.authorization) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });
        if (!req.body.pin || !req.body.userID || !req.body.reason) return res.status(400).json({ code: this.constants.codes.CLIENT_ERROR, message: this.constants.messages.CLIENT_ERROR });
        if (req.body.reason?.length < 1) return res.status(400).json({ code: this.constants.codes.CLIENT_ERROR, message: this.constants.codes.CLIENT_ERROR });

        const merchant = await this.server.client.db.Merchant.findOne({ key: req.headers.authorization }).lean().exec();
        if (!merchant) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });

        const member = await this.server.client.db.Score.findOne({ userID: req.body.userID, 'pin.2': req.body.pin }).lean().exec();
        if (!member) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });

        const mem = this.server.client.util.resolveMember(member.userID, this.server.client.guilds.get(this.server.client.config.guildID));
        if (!mem) return res.status(404).json({ code: this.constants.codes.NOT_FOUND, message: this.constants.codes.NOT_FOUND });

        if (member.locked) return res.status(403).json({ code: this.constants.codes.PERMISSION_DENIED, message: this.constants.messages.PERMISSION_DENIED });
        if (merchant?.type !== 1) return res.status(403).json({ code: this.constants.codes.PERMISSION_DENIED, message: this.constants.messages.PERMISSION_DENIED });

        if (this.check(member.userID)) {
          await this.server.client.db.Score.updateOne({ userID: member.userID }, { $set: { locked: true } });
          const chan = await this.server.client.getDMChannel(member.userID);
          try {
            await chan.createMessage(`__**Community Report Locked**__\nWe've detected suspicious activity on your Community Report, for the integrity of your report we have automatically locked it. To unlock your report, please run \`${this.server.client.config.prefix}score pref unlock\` in <#468759629334183956>.`);
          } catch (err) {
            this.server.client.util.signale.error(`Unable to DM user: ${member.userID} | ${err}`);
          }
          return res.status(403).json({ code: this.constants.codes.PERMISSION_DENIED, message: this.constants.messages.PERMISSION_DENIED });
        }

        const flags = [];
        if (mem.user.publicFlags) {
          if ((mem.user.publicFlags & (1 << 0)) === 1 << 0) flags.push('DISCORD_EMPLOYEE');
          if ((mem.user.publicFlags & (1 << 1)) === 1 << 1) flags.push('PARTNERED_SERVER_OWNER');
          if ((mem.user.publicFlags & (1 << 2)) === 1 << 2) flags.push('HYPESQUAD_EVENTS');
          if ((mem.user.publicFlags & (1 << 3)) === 1 << 3) flags.push('BUG_HUNTER_1');
          if ((mem.user.publicFlags & (1 << 6)) === 1 << 6) flags.push('HOUSE_BRAVERY');
          if ((mem.user.publicFlags & (1 << 7)) === 1 << 7) flags.push('HOUSE_BRILLIANCE');
          if ((mem.user.publicFlags & (1 << 8)) === 1 << 8) flags.push('HOUSE_BALANCE');
          if ((mem.user.publicFlags & (1 << 9)) === 1 << 9) flags.push('EARLY_SUPPORTER');
          if ((mem.user.publicFlags & (1 << 10)) === 1 << 10) flags.push('TEAM_USER');
          if ((mem.user.publicFlags & (1 << 12)) === 1 << 12) flags.push('SYSTEM');
          if ((mem.user.publicFlags & (1 << 14)) === 1 << 14) flags.push('BUG_HUNTER_2');
          if ((mem.user.publicFlags & (1 << 16)) === 1 << 16) flags.push('VERIFIED_BOT');
          if ((mem.user.publicFlags & (1 << 17)) === 1 << 17) flags.push('EARLY_VERIFIED_BOT_DEVELOPER');
        }
        const set = [];
        const accounts = await this.server.client.db.Score.find().lean().exec();
        for (const sc of accounts) {
          if (sc.total < 200) { continue; }
          if (sc.total > 800) { set.push(800); continue; }
          set.push(sc.total);
        }

        let totalScore: number;
        let activityScore: number;
        const moderationScore = Math.round(member.moderation);
        let roleScore: number;
        let cloudServicesScore: number;
        const otherScore = Math.round(member.other);
        let miscScore: number;

        if (member.total < 200) totalScore = 0;
        else if (member.total > 800) totalScore = 800;
        else totalScore = Math.round(member.total);

        if (member.activity < 10) activityScore = 0;
        else if (member.activity > Math.floor((Math.log1p(getTotalMessageCount(this.server.client)) * 12))) activityScore = Math.floor((Math.log1p(getTotalMessageCount(this.server.client)) * 12));
        else activityScore = Math.round(member.activity);

        if (member.roles <= 0) roleScore = 0;
        else if (member.roles > 54) roleScore = 54;
        else roleScore = Math.round(member.roles);

        if (member.staff <= 0) miscScore = 0;
        else miscScore = Math.round(member.staff);

        if (member.cloudServices === 0) cloudServicesScore = 0;
        else if (member.cloudServices > 10) cloudServicesScore = 10;
        else cloudServicesScore = Math.round(member.cloudServices);

        const inqs = await this.server.client.db.Inquiry.find({ userID: member.userID }).lean().exec();
        const inquiries: [{ id?: string, name: string, date: Date }?] = [];
        if (inqs?.length > 0) {
          for (const inq of inqs) {
            const testDate = (new Date(new Date(inq.date).setHours(1460)));
            if (testDate > new Date()) inquiries.push({ id: inq.iid, name: inq.name, date: inq.date });
          }
        }

        const judgements = await this.server.client.db.Judgement.find({ userID: member.userID }).lean().exec();

        const historicalData = await this.server.client.db.ScoreHistorical.find({ userID: member.userID }).lean().exec();
        const array: ScoreHistoricalRaw[] | ScoreHistoricalInterface[] = [];
        for (const data of historicalData) {
          delete data.report?.softInquiries;

          let total: number;
          let activity: number;
          const moderation = Math.round(data.report.moderation);
          let role: number;
          let cloud: number;
          const other = Math.round(data.report.other);
          let misc: number;

          if (data.report.total < 200) total = 0;
          else if (data.report.total > 800) total = 800;
          else total = Math.round(data.report.total);

          if (data.report.activity < 10) activity = 0;
          else if (data.report.activity > Math.floor((Math.log1p(getTotalMessageCount(this.server.client)) * 12))) activity = Math.floor((Math.log1p(getTotalMessageCount(this.server.client)) * 12));
          else activity = Math.round(data.report.activity);

          if (data.report.roles <= 0) role = 0;
          else if (data.report.roles > 54) role = 54;
          else role = Math.round(data.report.roles);

          if (data.report.staff <= 0) role = 0;
          else misc = Math.round(data.report.staff);

          if (data.report.cloudServices === 0) cloud = 0;
          else if (data.report.cloudServices > 10) cloud = 10;
          else cloud = Math.round(data.report.cloudServices);

          data.report.total = total; data.report.activity = activity; data.report.moderation = moderation; data.report.roles = role; data.report.cloudServices = cloud; data.report.other = other; data.report.staff = misc;

          array.push(data);
        }

        const inq = await this.server.client.report.createInquiry(member.userID, merchant.name, 0, req.body.reason);

        await this.server.client.db.Merchant.updateOne({ key: req.headers.authorization }, { $addToSet: { pulls: { type: 0, reason: req.body.reason, date: new Date() } } });

        return res.status(200).json({
          code: this.constants.codes.SUCCESS,
          message: {
            id: inq.id,
            userID: member.userID,
            memberInformation: {
              username: mem.user.username,
              discriminator: mem.user.discriminator,
              joinedServerAt: new Date(mem.joinedAt),
              createdAt: new Date(mem.createdAt),
              avatarURL: mem.avatarURL,
              flags,
              nitroBoost: mem.premiumSince === null,
            },
            percentile: Math.round(this.server.client.util.percentile(set, member.total)),
            totalScore,
            activityScore,
            roleScore,
            moderationScore,
            cloudServicesScore,
            miscScore,
            otherScore,
            inquiries,
            judgements,
            historical: array ?? [],
          },
        });
      } catch (err) {
        return this.handleError(err, res);
      }
    });

    this.router.post('/v2/soft', async (req, res) => {
      try {
        if (!req.headers.authorization) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });
        if (!req.body.userID) return res.status(400).json({ code: this.constants.codes.CLIENT_ERROR, message: this.constants.messages.CLIENT_ERROR });

        const merchant = await this.server.client.db.Merchant.findOne({ key: req.headers.authorization }).lean().exec();
        if (!merchant) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });

        const report = await this.server.client.db.Score.findOne({ userID: req.body.userID }).lean().exec();
        if (!report) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });

        let totalScore: number;

        if (report.total < 200) totalScore = 0;
        else if (report.total > 800) totalScore = 800;
        else totalScore = Math.round(report.total);

        await this.server.client.db.Merchant.updateOne({ key: req.headers.authorization }, { $addToSet: { pulls: { type: 1, reason: 'N/A', date: new Date() } } });
        const mem = this.server.client.util.resolveMember(report.userID, this.server.client.guilds.get(this.server.client.config.guildID));
        await this.server.client.report.createInquiry(report.userID, merchant.name.toUpperCase(), 1);

        if (!merchant.privileged) {
          return res.status(200).json({
            code: this.constants.codes.SUCCESS,
            message: {
              userID: report.userID,
              totalScore,
            },
          });
        }
        const flags = [];
        if (mem.user.publicFlags) {
          if ((mem.user.publicFlags & (1 << 0)) === 1 << 0) flags.push('DISCORD_EMPLOYEE');
          if ((mem.user.publicFlags & (1 << 1)) === 1 << 1) flags.push('PARTNERED_SERVER_OWNER');
          if ((mem.user.publicFlags & (1 << 2)) === 1 << 2) flags.push('HYPESQUAD_EVENTS');
          if ((mem.user.publicFlags & (1 << 3)) === 1 << 3) flags.push('BUG_HUNTER_1');
          if ((mem.user.publicFlags & (1 << 6)) === 1 << 6) flags.push('HOUSE_BRAVERY');
          if ((mem.user.publicFlags & (1 << 7)) === 1 << 7) flags.push('HOUSE_BRILLIANCE');
          if ((mem.user.publicFlags & (1 << 8)) === 1 << 8) flags.push('HOUSE_BALANCE');
          if ((mem.user.publicFlags & (1 << 9)) === 1 << 9) flags.push('EARLY_SUPPORTER');
          if ((mem.user.publicFlags & (1 << 10)) === 1 << 10) flags.push('TEAM_USER');
          if ((mem.user.publicFlags & (1 << 12)) === 1 << 12) flags.push('SYSTEM');
          if ((mem.user.publicFlags & (1 << 14)) === 1 << 14) flags.push('BUG_HUNTER_2');
          if ((mem.user.publicFlags & (1 << 16)) === 1 << 16) flags.push('VERIFIED_BOT');
          if ((mem.user.publicFlags & (1 << 17)) === 1 << 17) flags.push('EARLY_VERIFIED_BOT_DEVELOPER');
        }
        const set = [];
        if (req.query.p?.toString() === 'true') {
          const accounts = await this.server.client.db.Score.find().lean().exec();
          for (const sc of accounts) {
            if (sc.total < 200) { continue; }
            if (sc.total > 800) { set.push(800); continue; }
            set.push(sc.total);
          }
        }

        const judgements = await this.server.client.db.Judgement.find({ userID: report.userID }).lean().exec();

        let activityScore: number;
        const moderationScore = Math.round(report.moderation);
        let roleScore: number;
        let cloudServicesScore: number;
        const otherScore = Math.round(report.other);
        let miscScore: number;

        if (report.activity < 10) activityScore = 0;
        else if (report.activity > Math.floor((Math.log1p(getTotalMessageCount(this.server.client)) * 12))) activityScore = Math.floor((Math.log1p(getTotalMessageCount(this.server.client)) * 12));
        else activityScore = Math.round(report.activity);

        if (report.roles <= 0) roleScore = 0;
        else if (report.roles > 54) roleScore = 54;
        else roleScore = Math.round(report.roles);

        if (report.staff <= 0) miscScore = 0;
        else miscScore = Math.round(report.staff);

        if (report.cloudServices === 0) cloudServicesScore = 0;
        else if (report.cloudServices > 10) cloudServicesScore = 10;
        else cloudServicesScore = Math.round(report.cloudServices);

        const historicalData = await this.server.client.db.ScoreHistorical.find({ userID: report.userID }).lean().exec();
        const array: ScoreHistoricalRaw[] = [];
        for (const data of historicalData) {
          delete data.report?.softInquiries;
          delete data.report?.inquiries;

          let total: number;
          let activity: number;
          const moderation = Math.round(data.report.moderation);
          let role: number;
          let cloud: number;
          const other = Math.round(data.report.other);
          let misc: number;

          if (data.report.total < 200) total = 0;
          else if (data.report.total > 800) total = 800;
          else total = Math.round(data.report.total);

          if (data.report.activity < 10) activity = 0;
          else if (data.report.activity > Math.floor((Math.log1p(getTotalMessageCount(this.server.client)) * 12))) activity = Math.floor((Math.log1p(getTotalMessageCount(this.server.client)) * 12));
          else activity = Math.round(data.report.activity);

          if (data.report.roles <= 0) role = 0;
          else if (data.report.roles > 54) role = 54;
          else role = Math.round(data.report.roles);

          if (data.report.staff <= 0) role = 0;
          else misc = Math.round(data.report.staff);

          if (data.report.cloudServices === 0) cloud = 0;
          else if (data.report.cloudServices > 10) cloud = 10;
          else cloud = Math.round(data.report.cloudServices);

          data.report.total = total; data.report.activity = activity; data.report.moderation = moderation; data.report.roles = role; data.report.cloudServices = cloud; data.report.other = other; data.report.staff = misc;

          array.push(data);
        }

        return res.status(200).json({
          code: this.constants.codes.SUCCESS,
          message: {
            userID: report.userID,
            memberInformation: {
              username: mem.user.username,
              discriminator: mem.user.discriminator,
              joinedServerAt: new Date(mem.joinedAt),
              createdAt: new Date(mem.createdAt),
              avatarURL: mem.avatarURL,
              flags,
              nitroBoost: mem.premiumSince === null,
            },
            totalScore,
            percentile: Math.round(this.server.client.util.percentile(set, report.total)),
            activityScore,
            moderationScore,
            roleScore,
            cloudServicesScore,
            otherScore,
            miscScore,
            judgements,
            historical: array ?? [],
          },
        });
      } catch (err) {
        return this.handleError(err, res);
      }
    });

    this.router.post('/soft', async (req, res) => {
      try {
        if (!req.headers.authorization) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });
        if (!req.body.pin || !req.body.userID) return res.status(400).json({ code: this.constants.codes.CLIENT_ERROR, message: this.constants.messages.CLIENT_ERROR });

        const merchant = await this.server.client.db.Merchant.findOne({ key: req.headers.authorization }).lean().exec();
        if (!merchant) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });

        const member = await this.server.client.db.Score.findOne({ userID: req.body.userID, 'pin.2': req.body.pin }).lean().exec();
        if (!member) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });
        const mem = this.server.client.util.resolveMember(member.userID, this.server.client.guilds.get(this.server.client.config.guildID));
        if (!mem) return res.status(404).json({ code: this.constants.codes.NOT_FOUND, message: this.constants.codes.NOT_FOUND });

        let totalScore: number;

        if (member.total < 200) totalScore = 0;
        else if (member.total > 800) totalScore = 800;
        else totalScore = Math.round(member.total);

        await this.server.client.db.Merchant.updateOne({ key: req.headers.authorization }, { $addToSet: { pulls: { type: 1, reason: 'N/A', date: new Date() } } });
        await this.server.client.report.createInquiry(member.userID, merchant.name.toUpperCase(), 1);

        if (!merchant.privileged) {
          return res.status(200).json({
            code: this.constants.codes.SUCCESS,
            message: {
              userID: member.userID,
              totalScore,
            },
          });
        }
        let activityScore: number;
        const moderationScore = Math.round(member.moderation);
        let roleScore: number;
        let cloudServicesScore: number;
        const otherScore = Math.round(member.other);
        let miscScore: number;

        if (member.activity < 10) activityScore = 0;
        else if (member.activity > Math.floor((Math.log1p(getTotalMessageCount(this.server.client)) * 12))) activityScore = Math.floor((Math.log1p(getTotalMessageCount(this.server.client)) * 12));
        else activityScore = Math.round(member.activity);

        if (member.roles <= 0) roleScore = 0;
        else if (member.roles > 54) roleScore = 54;
        else roleScore = Math.round(member.roles);

        if (member.staff <= 0) miscScore = 0;
        else miscScore = Math.round(member.staff);

        if (member.cloudServices === 0) cloudServicesScore = 0;
        else if (member.cloudServices > 10) cloudServicesScore = 10;
        else cloudServicesScore = Math.round(member.cloudServices);

        return res.status(200).json({
          code: this.constants.codes.SUCCESS,
          message: {
            userID: member.userID,
            totalScore,
            activityScore,
            moderationScore,
            roleScore,
            cloudServicesScore,
            otherScore,
            miscScore,
          },
        });
      } catch (err) {
        return this.handleError(err, res);
      }
    });

    this.router.get('/web', async (req, res) => {
      try {
        res.setHeader('Access-Control-Allow-Origin', '*');
        if (this.timeout.has(req.ip)) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });
        if (!req.query.pin) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });
        const args = req.query.pin.toString();
        this.timeout.set(req.ip, 1);
        setTimeout(() => this.timeout.delete(req.ip), 1800000);
        let score = await this.server.client.db.Score.findOne({ pin: [Number(args.split('-')[0]), Number(args.split('-')[1]), Number(args.split('-')[2])] }).lean().exec();
        if (!score) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });
        const member = await this.server.client.getRESTGuildMember(this.constants.discord.SERVER_ID, score.userID);
        if (!member) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });
        let updated = false;
        if (req.query.staff) {
          // eslint-disable-next-line no-shadow
          const args = req.query.staff.toString();
          const staffScore = await this.server.client.db.Score.findOne({ pin: [Number(args.split('-')[0]), Number(args.split('-')[1]), Number(args.split('-')[2])] }).lean().exec();
          if (!staffScore) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });
          if (!staffScore.staff) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });
          this.timeout.delete(req.ip);
          if (staffScore.userID === score.userID) {
            updated = true;
            await this.server.client.report.createInquiry(member.user.id, `${member.username} via report.libraryofcode.org @ IP ${req.ip}`, 1);
          } else {
            await this.server.client.report.createInquiry(member.user.id, 'Library of Code sp-us | Staff Team via report.libraryofcode.org', 1);
          }
        } else if (!updated) {
          await this.server.client.report.createInquiry(member.user.id, `${member.username} via report.libraryofcode.org @ IP ${req.ip}`, 1);
        }
        score = await this.server.client.db.Score.findOne({ pin: [Number(args.split('-')[0]), Number(args.split('-')[1]), Number(args.split('-')[2])] }).lean().exec();

        let totalScore = '0';
        let activityScore = '0';
        let moderationScore = '0';
        let roleScore = '0';
        let cloudServicesScore = '0';
        let otherScore = '0';
        let miscScore = '0';

        if (score.total < 200) totalScore = '---';
        else if (score.total > 800) totalScore = '800';
        else totalScore = `${score.total}`;

        if (score.activity < 10) activityScore = '---';
        else if (score.activity > Math.floor((Math.log1p(getTotalMessageCount(this.server.client)) * 12))) activityScore = String(Math.floor((Math.log1p(getTotalMessageCount(this.server.client)) * 12)));
        else activityScore = `${score.activity}`;

        if (score.roles <= 0) roleScore = '---';
        else if (score.roles > 54) roleScore = '54';
        else roleScore = `${score.roles}`;

        moderationScore = `${score.moderation}`;

        if (score.other === 0) otherScore = '---';
        else otherScore = `${score.other}`;

        if (score.staff <= 0) miscScore = '---';
        else miscScore = `${score.staff}`;

        if (score.cloudServices === 0) cloudServicesScore = '---';
        else if (score.cloudServices > 10) cloudServicesScore = '10';
        else cloudServicesScore = `${score.cloudServices}`;

        const moderations = await this.server.client.db.Moderation.find({ userID: score.userID }).lean().exec();

        const historical = await this.server.client.db.ScoreHistorical.find({ userID: score.userID }).lean().exec();

        for (const data of historical) {
          let total: number;
          let activity: number;
          const moderation = Math.round(data.report.moderation);
          let role: number;
          let cloud: number;
          const other = Math.round(data.report.other);
          let misc: number;

          if (data.report.total < 200) total = 0;
          else if (data.report.total > 800) total = 800;
          else total = Math.round(data.report.total);

          if (data.report.activity < 10) activity = 0;
          else if (data.report.activity > Math.floor((Math.log1p(getTotalMessageCount(this.server.client)) * 12))) activity = Math.floor((Math.log1p(getTotalMessageCount(this.server.client)) * 12));
          else activity = Math.round(data.report.activity);

          if (data.report.roles <= 0) role = 0;
          else if (data.report.roles > 54) role = 54;
          else role = Math.round(data.report.roles);

          if (data.report.staff <= 0) role = 0;
          else misc = Math.round(data.report.staff);

          if (data.report.cloudServices === 0) cloud = 0;
          else if (data.report.cloudServices > 10) cloud = 10;
          else cloud = Math.round(data.report.cloudServices);

          data.report.total = total; data.report.activity = activity; data.report.moderation = moderation; data.report.roles = role; data.report.cloudServices = cloud; data.report.other = other; data.report.staff = misc;
        }

        const inqs = await this.server.client.db.Inquiry.find({ userID: score.userID }).lean().exec();
        const hardInquiries: [{ id?: string, name: string, reason: string, date: Date }?] = [];
        const softInquiries: [{ id?: string, name: string, date: Date }?] = [];
        for (const inq of inqs) {
          if (inq.type === 0) {
            hardInquiries.push({ id: inq.iid, name: inq.name, reason: inq.reason, date: inq.date });
          } else if (inq.type === 1) {
            softInquiries.push({ name: inq.name, date: inq.date });
          }
        }

        return res.status(200).json({
          name: `${member.username}#${member.discriminator}`,
          avatarURL: member.avatarURL,
          userID: score.userID,
          pin: score.pin?.join('-'),
          score: totalScore,
          activityScore,
          cloudServicesScore,
          moderationScore,
          roleScore,
          otherScore,
          miscScore,
          notify: score.notify,
          locked: !!score.locked,
          totalModerations: moderations?.length > 0 ? moderations.length : 0,
          inquiries: hardInquiries?.length > 0 ? hardInquiries.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()) : [],
          softInquiries: softInquiries?.length > 0 ? softInquiries.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()) : [],
          historical: historical ?? [],
          lastUpdated: score.lastUpdate,
        });
      } catch (err) {
        return this.handleError(err, res);
      }
    });

    this.router.get('/offer', async (req, res) => {
      try {
        res.setHeader('Access-Control-Allow-Origin', '*');
        if (!req.query.code) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });
        if (await this.acceptedOffers.get(req.query.code.toString())) return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });
        let offer: {
          userID?: string,
          staffID?: string,
          channelID?: string,
          messageID?: string,
          pin?: string,
          name?: string,
          department?: string,
          date?: Date,
        };

        try {
          offer = <{
            userID?: string,
            staffID?: string,
            channelID?: string,
            messageID?: string,
            pin?: string,
            name?: string,
            department?: string,
            date?: Date,
          }>jwt.verify(req.query.code.toString(), this.server.client.config.internalKey);
        } catch {
          return res.status(401).json({ code: this.constants.codes.UNAUTHORIZED, message: this.constants.messages.UNAUTHORIZED });
        }
        const chan = <TextChannel>this.server.client.guilds.get(this.constants.discord.SERVER_ID).channels.get(offer.channelID);
        await chan.createMessage(`__**PRE-APPROVED OFFER ACCEPTED**__\n<@${offer.staffID}>`);
        const message = await chan.getMessage(offer.messageID);
        const args = [];
        args.push(offer.userID, 'hard');
        `${offer.department}:${offer.name}`.split(' ').forEach((item) => args.push(item));
        await this.server.client.commands.get('score').run(message, args);
        await this.acceptedOffers.set(req.query.code.toString(), true);
        return res.sendStatus(200);
      } catch (err) {
        return this.handleError(err, res);
      }
    });
  }
}
