// Cokoliv co má něco společnýho s vojsem

import { getVoiceConnection, VoiceConnection, VoiceConnectionStatus } from "@discordjs/voice";
import { ChannelType, GuildMember, VoiceChannel } from "discord.js";
import { emouty } from "../utils/emotes";
import { Modul, MuzikaFace, SRecord } from "../utils/types";
import { canAnounceTime, handlePrevVoice, joinVoice, log, play } from "../utils/utils";

const timeouty: SRecord<NodeJS.Timeout> = {};

const vypocitatCas = (guild: string, conn: VoiceConnection) => {
  const c = new Date();
  const d = new Date();
  let hod = d.getHours();
  let min = d.getMinutes();
  if (min >= 30) {
    min = 0;
    if (hod == 23) {
      hod = 0;
      d.setDate(c.getDate() + 1);
    } else {
      hod++;
    }
  } else {
    min = 30;
  }
  d.setHours(hod);
  d.setMinutes(min);
  d.setSeconds(0);

  timeouty[conn.joinConfig.guildId] = setTimeout(() => rekniCas(guild, conn, `${nula(hod)}${nula(min)}`), Number(d) - Number(c));
};

const nula = (a: number) => a < 10 ? `0${a}` : a;

const rekniCas = (guild: string, conn: VoiceConnection, cas: string) => {
  if (canAnounceTime(guild))
    play(conn, [{ name: "zvuky/intro.mp3", volume: 0.8 }, { name: `zvuky/${cas}.mp3`, volume: 2 }, { name: "zvuky/grg.mp3", volume: 0.5 }])
      .then(() => {
        vypocitatCas(guild, conn);
      })
      .catch(err => { log("cas error:", err); });
  else vypocitatCas(guild, conn);
};

const vytahnout = (member: GuildMember, patro: number) => {
  const vojs = member.voice.channel;
  if (!vojs) return;

  const aktPatro = Number(vojs.name) || 0;
  let dalsiPatro: number | string = aktPatro;
  if (patro < aktPatro) dalsiPatro--; else if (patro > aktPatro) dalsiPatro++; else return;
  if (dalsiPatro === 0) dalsiPatro = "P";

  const dalsiVojs = member.guild.channels.cache.filter(channel => channel.type == ChannelType.GuildVoice && channel.name === String(dalsiPatro)).first() as VoiceChannel | undefined;
  if (!dalsiVojs) return;

  member.voice.setChannel(dalsiVojs);
  setTimeout(() => vytahnout(member, patro), 1e3);
};

const exp: Modul = {
  more_komandy: {

    wojs: mes => `vojs se pise s normalnim v ti kriple ${mes.author}`,

    vojs: {
      cd: 1800,
      arg: "potichu (nepovinné)",
      DMUnsafe: true,
      run: (mes, arg) => {
        const channel = mes.member?.voice.channel;
        if (!channel) return `di si tam sam ne ty gadzo ${mes.author}`;

        const nahlas = !arg.startsWith("potichu");
        if (nahlas) mes.channel.send("<@&591306633196339261> vojs");

        joinVoice(channel)
          .then(obj => {
            const { prev, conn } = obj;
            if (!timeouty[mes.guildId!]) {
              vypocitatCas(mes.guildId!, conn);
              conn.on("stateChange", (_, now) => {
                if (now.status !== VoiceConnectionStatus.Disconnected && now.status !== VoiceConnectionStatus.Destroyed) return;
                clearTimeout(timeouty[mes.guildId!]);
                delete timeouty[mes.guildId!];
              });
            }
            if (prev !== true && nahlas) play(conn, "zvuky/nazdar.ogg");
          });
      }
    },

    vypadni: {
      als: ["odejdi", "disconnect", "leave", "odpoj", "votpoj", "vodpoj", "vodprejskni", "tahni"],
      DMUnsafe: true,
      run: mes => {
        const vojs = getVoiceConnection(mes.guildId!);
        if (!vojs) return 'nejsem ve vojsu';

        vojs.destroy();
        mes.react(emouty.purfieRIP);
      }
    },

    vytah: {
      als: ["vitah"],
      DMUnsafe: true,
      run: (mes, parto) => {
        if (!mes.member?.voice.channel) return `nejsi ve vojsu ty gadzo ${mes.author}`;
        if (!parto) return `napis do jakiho patra ${mes.author}`;

        vytahnout(mes.member, Number(parto) || 0);
      }
    },

    krkacek: {
      als: ["krk", "grg", "grgnisi", "krknisi", "grgacek"],
      run: async mes => {
        const channel = mes.member?.voice.channel;
        if (!channel) return "***grrrrrrrrg***";

        const { conn, prev } = await joinVoice(channel);
        await play(conn, "zvuky/grg.mp3");
        handlePrevVoice(mes.guild!, prev);
      }
    },

    cas: {
      cd: 5,
      run: async mes => {
        const date = new Date();
        const h = date.getHours();
        const m = date.getMinutes();
        const pre = "zvuky/cas/";

        const addSuffix = (prefix: string, hodnota: number) => {
          const koncovka = hodnota == 1 ? "a" : hodnota > 1 && hodnota < 5 ? "y" : "";
          return `${prefix}${koncovka}`;
        };
        const rozdelAPridej = (cislo: number) => {
          if (cislo == 2) return zvuky.push({ name: `${pre}dvě.mp3`, volume: 2.5 });
          if (cislo < 20) return zvuky.push({ name: `${pre}${cislo}.mp3`, volume: 2.5 });
          const text = String(cislo);
          zvuky.push({ name: `${pre}${text[0]}0.mp3`, volume: 2.5 });
          if (text[1] != "0") zvuky.push({ name: `${pre}${text[1]}.mp3`, volume: 2.5 });
        };

        const hod = addSuffix("hodin", h);
        const min = addSuffix("minut", m);
        const je = h > 1 && h < 5 ? "jsou" : "je";

        const channel = mes.member?.voice.channel;
        if (!channel) return `${je} ${h} ${hod} ${m} ${min}`;

        const zvuky: MuzikaFace[] = [{ name: `${pre}${je}.mp3`, volume: 2.5 }];

        rozdelAPridej(h);
        zvuky.push({ name: `${pre}${hod}.mp3`, volume: 2.5 });
        if (m > 0) {
          rozdelAPridej(m);
          zvuky.push({ name: `${pre}${min}.mp3`, volume: 2.5 });
        }

        const { conn, prev } = await joinVoice(channel);
        await play(conn, zvuky);
        handlePrevVoice(mes.guild!, prev);
      }
    },

    outro: {
      hidden: true,
      run: async mes => {
        const channel = mes.member?.voice.channel;
        if (!channel) return "co to znamena ti gadzovko";

        const { conn, prev } = await joinVoice(channel);
        await play(conn, { name: "zvuky/pocasi/outro.mp3", volume: 30 });
        handlePrevVoice(mes.guild!, prev);
      }
    }
  }
};

module.exports = exp;
