// Modul na komand "anketa"

import { ActionRowBuilder, APIEmbed, APIEmbedField, ButtonBuilder, ButtonStyle, ChatInputCommandInteraction, ComponentType, Message, MessageComponentInteraction } from "discord.js";
import { Modul, SRecord } from "../utils/types";
import { formatter } from "../utils/utils";

function lookup<T>(opt: ChatInputCommandInteraction["options"], item: string) {
  return opt.get(item)?.value as T | undefined;
}

const exp: Modul = {
  more_komandy: {

    anketa: {
      DMUnsafe: true,
      slashRun: async int => {

        const opt = int.options;
        const settings = {
          time: lookup<number>(opt, "cas") || 60,
          immediateShow: !lookup<boolean>(opt, "neprubezny"),
          listNames: lookup<boolean>(opt, "jmena")
        };

        const str = lookup<string>(opt, "moznosti")!;
        const moznosti = str.split(str.includes("|") ? "|" : ",").reduce<string[]>((acc, c) => {
          if (c.length) acc.push(c.trim());
          return acc;
        }, []);

        if (moznosti.length < 2) return "zadej alespo%n dve moznosti";
        if (moznosti.length > 25) return "toje moc";

        const konec = new Date();
        konec.setSeconds(konec.getSeconds() + settings.time);

        const embed: APIEmbed = {
          title: "Hlasování",
          description: settings.immediateShow ? `Končí ${formatter(konec)}` : `Výsledky se zobrazí ${formatter(konec)}`
        };
        const fildy: APIEmbedField[] = [];
        const radky: ActionRowBuilder<ButtonBuilder>[] = [];
        const odpovedi: SRecord<number> = {};

        function prepocitat(interaction?: MessageComponentInteraction) {
          const celkem = Object.keys(odpovedi).length;
          fildy.forEach((f, i) => {
            const hovn = Object.values(odpovedi).filter(n => n == i);
            const dylka = hovn.length;
            const p = Math.floor(dylka / celkem * 10) || 0;
            const people = Object.keys(odpovedi).reduce<string[]>((pr, cur) => {
              if (odpovedi[cur] == i) pr.push(cur);
              return pr;
            }, []);
            const kindo = people.map(w => int.guild?.members.cache.get(w)?.displayName);
            f.value = `${"█".repeat(p)}${"░".repeat(10 - p)} ${Math.round(dylka / celkem * 100) || 0}% (${dylka}) ${settings.listNames ? " (" + kindo.join(", ") + ")" : ""}`;
          });
          interaction?.update({ embeds: [embed] });
        }

        moznosti.forEach((h, i) => {
          const mnam = (i - (i % 5)) / 5;
          if (i % 5 == 0) radky[mnam] = new ActionRowBuilder<ButtonBuilder>;
          fildy.push({ name: h, value: "" });
          radky[mnam].addComponents(new ButtonBuilder({ customId: `${i}`, label: h, style: ButtonStyle.Primary }));
        });
        prepocitat();
        if (settings.immediateShow) embed.fields = fildy;
        const zprava = await int.reply({ embeds: [embed], components: radky });
        const collector = zprava.createMessageComponentCollector<ComponentType.Button>({ time: settings.time * 1000 });

        collector.on("collect", d => {
          if (!(d.message instanceof Message)) return;
          const i = Number(d.customId);
          const prev = odpovedi[d.user.id];
          if (prev == i) return void d.deferUpdate();
          odpovedi[d.user.id] = i;
          if (!settings.immediateShow) return void d.deferUpdate();
          prepocitat();
          d.update({ embeds: [embed] });
        });

        collector.on("end", () => {
          embed.description = `Skončilo ${formatter(konec)}`;
          prepocitat();
          embed.fields = fildy;
          int.editReply({ components: [], embeds: [embed] });
        });
      }
    }
  }
};

module.exports = exp;
