import { Plugin, BotEventData, Event } from "src/model/plugin";
import { GuildMember, PartialGuildMember, TextChannel } from "discord.js";
import { getRepository } from "typeorm";
import { logger } from "src/logging";
import { GuildGreeting } from "@shared/db/entity/GuildGreeting";
import { client } from "src/client";
import { formatString } from "src/util";

@Plugin
export class GreetPlugin {
    @Event("guildMemberAdd")
    async showGreetMessage(data: BotEventData, member: GuildMember | PartialGuildMember): Promise<void> {
        await this.displayGreet(member, g => g.onJoinMessage);
    }

    @Event("guildMemberRemove")
    async showGoodbyeMessage(data: BotEventData, member: GuildMember | PartialGuildMember): Promise<void> {
        await this.displayGreet(member, g => g.onLeaveMessage);
    }

    private async displayGreet(member: GuildMember | PartialGuildMember, select: (greeting: GuildGreeting) => string) {
        const result = await this.getGreeting(member);
        if (!result)
            return;
        const { guildGreeting, greetingChannel } = result;

        await greetingChannel.send(formatString(select(guildGreeting), {
            memberID: member.id,
            memberTag: member.user?.tag ?? member.displayName,
            guildName: member.guild.name
        }));
    }
    
    private async getGreeting(member: GuildMember | PartialGuildMember) {
        const repo = getRepository(GuildGreeting);

        const guildGreeting = await repo.findOne(member.guild.id);
        if (!guildGreeting) {
            logger.debug("Tried to greet user %s in guild %s but no greeting is defined!", member.id, member.guild.id);
            return undefined;
        }

        const greetingChannel = client.bot.channels.resolve(guildGreeting.greetingChannelId);
        if (!greetingChannel) {
            logger.warn("No channel %s in guild %s, can't greet!", guildGreeting.greetingChannelId, guildGreeting.guildId);
            return undefined;
        }

        if (!(greetingChannel instanceof TextChannel)) {
            logger.warn("Channel %s is of not a text channel (got type: %s)", greetingChannel.id, greetingChannel.type);
            return undefined;
        }

        return { guildGreeting, greetingChannel };
    }
}