/* eslint-disable no-await-in-loop */
/* eslint-disable no-continue */
/* eslint-disable default-case */
import moment from 'moment';
import { median, mode, mean } from 'mathjs';
import { createPaginationEmbed } from 'eris-pagination';
import { Message } from 'eris';
import { Client, Command, RichEmbed } from '../class';
import { getTotalMessageCount } from '../intervals/score';
import { InquiryInterface } from '../models';

export default class Score_Hist extends Command {
  constructor(client: Client) {
    super(client);
    this.name = 'hist';
    this.description = 'Pulls a Community Report history for a user.';
    this.usage = `${this.client.config.prefix}score hist <member>`;
    this.permissions = 4;
    this.guildOnly = false;
    this.enabled = true;
  }

  public async run(message: Message, args: string[]) {
    try {
      if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
      let user = this.client.util.resolveMember(args[0], this.mainGuild)?.user;
      if (!user) {
        const sc = await this.client.db.Score.findOne({ pin: [Number(args[0].split('-')[0]), Number(args[0].split('-')[1]), Number(args[0].split('-')[2])] });
        user = this.client.util.resolveMember(sc.userID, this.mainGuild)?.user;
      }
      if (!user) return this.error(message.channel, 'Member not found.');
      const hists = await this.client.db.ScoreHistorical.find({ userID: user.id }).limit(31).lean().exec();
      if (!hists) return this.error(message.channel, 'No history found.');
      if (hists.length < 1) return this.error(message.channel, 'No history found.');
      const histArray: [{ name: string, value: string }?] = [];
      const totalArray: number[] = [];
      const activityArray: number[] = [];
      const moderationArray: number[] = [];
      const roleArray: number[] = [];
      const cloudServicesArray: number[] = [];
      const otherArray: number[] = [];
      const miscArray: number[] = [];
      for (const hist of hists.reverse()) {
        totalArray.push(hist.report.total);
        activityArray.push(hist.report.activity);
        moderationArray.push(hist.report.moderation);
        roleArray.push(hist.report.roles);
        cloudServicesArray.push(hist.report.cloudServices);
        otherArray.push(hist.report.other);
        miscArray.push(hist.report.staff);
        let totalScore = '0';
        let activityScore = '0';
        let moderationScore = '0';
        let roleScore = '0';
        let cloudServicesScore = '0';
        let otherScore = '0';
        let miscScore = '0';

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

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

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

        moderationScore = `${hist.report.moderation}`;

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

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

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

        let data = '';
        let hardInquiries = 0;
        const inquiries: InquiryInterface[] = [];
        if (hist.inquiries?.length > 0) {
          for (const h of hist.inquiries) {
            const inq = await this.client.db.Inquiry.findOne({ _id: h });
            inquiries.push(inq);
          }
        }
        if (inquiries?.length > 0) {
          inquiries.forEach((inq) => {
            const testDate = (new Date(new Date(inq.date).setHours(1460)));
            // eslint-disable-next-line no-plusplus
            if (testDate > new Date()) hardInquiries++;
          });
          data += `__CommScore™:__ ${totalScore}\n__Activity:__ ${activityScore}\n__Roles:__ ${roleScore}\n__Moderation:__ ${moderationScore}\n__Cloud Services:__ ${cloudServicesScore}\n__Other:__ ${otherScore}\n__Misc:__ ${miscScore}\n\n__Hard Inquiries:__ ${hardInquiries}\n__Soft Inquiries:__ ${hist.report.softInquiries?.length ?? '0'}`;
          histArray.push({ name: moment(hist.date).calendar(), value: data });
        }
      }

      const stat = {
        totalMean: mean(totalArray),
        totalMode: mode(totalArray),
        totalMedian: median(totalArray),
        activityMean: mean(activityArray),
        rolesMean: mean(roleArray),
        moderationMean: mean(moderationArray),
        cloudServicesMean: mean(cloudServicesArray),
        otherMean: mean(otherArray),
        miscMean: mean(miscArray),
      };
      const splitHist = this.client.util.splitFields(histArray);
      const cmdPages: RichEmbed[] = [];
      splitHist.forEach((split) => {
        const embed = new RichEmbed();
        embed.setTitle('Historical Community Report');
        let totalMean = '0';
        let totalMedian = '0';
        let totalMode = '0';
        let activityMean = '0';
        let moderationMean = '0';
        let roleMean = '0';
        let cloudServicesMean = '0';
        let otherMean = '0';
        let miscMean = '0';

        if (stat.totalMean < 200) totalMean = '---';
        else if (stat.totalMean > 800) totalMean = '800';
        else totalMean = `${stat.totalMean}`;

        if (stat.totalMedian < 200) totalMedian = '---';
        else if (stat.totalMedian > 800) totalMedian = '800';
        else totalMedian = `${stat.totalMedian}`;

        if (stat.totalMode < 200) totalMode = '---';
        else if (stat.totalMode > 800) totalMode = '800';
        else totalMode = `${stat.totalMode}`;

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

        if (stat.rolesMean <= 0) roleMean = '---';
        else if (stat.rolesMean > 54) roleMean = '54';
        else roleMean = `${stat.rolesMean}`;

        moderationMean = `${stat.moderationMean}`;

        if (stat.otherMean === 0) otherMean = '---';
        else otherMean = `${stat.otherMean}`;

        if (stat.miscMean <= 0) miscMean = '---';
        else miscMean = `${stat.miscMean}`;

        if (stat.cloudServicesMean === 0) cloudServicesMean = '---';
        else if (stat.cloudServicesMean > 10) cloudServicesMean = '10';
        else cloudServicesMean = `${stat.cloudServicesMean}`;

        embed.setDescription(`__**Statistical Averages**__\n**CommScore™ Mean:** ${totalMean} | **CommScore™ Mode:** ${totalMode} | **CommScore™ Median:** ${totalMedian}\n\n**Activity Mean:** ${activityMean}\n**Roles Mean:** ${roleMean}\n**Moderation Mean:** ${moderationMean}\n**Cloud Services Mean:** ${cloudServicesMean}\n**Other Mean:** ${otherMean}\n**Misc Mean:** ${miscMean}`);
        embed.setAuthor(user.username, user.avatarURL);
        embed.setThumbnail(user.avatarURL);
        embed.setTimestamp();
        embed.setFooter(this.client.user.username, this.client.user.avatarURL);
        split.forEach((c) => embed.addField(c.name, c.value));
        return cmdPages.push(embed);
      });

      let name = '';
      for (const role of this.client.util.resolveMember(message.author.id, this.mainGuild).roles.map((r) => this.mainGuild.roles.get(r)).sort((a, b) => b.position - a.position)) {
        name = `Library of Code sp-us | ${role.name} - [HISTORICAL]`;
        break;
      }
      await this.client.report.createInquiry(user.id, name, 1);


      if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] });
      return createPaginationEmbed(message, cmdPages);
    } catch (err) {
      return this.client.util.handleError(err, message, this);
    }
  }
}
