import { getRepository } from "typeorm";
import { Quote } from "@shared/db/entity/Quote";
import { Command, ICommandData, Plugin } from "src/model/plugin";

const quotePattern = /add quote by "([^"]+)"\s*(.*)/i;

@Plugin
export class QuoteCommand {

    minify(str: string, maxLength: number): string {
        let result = str.replace("\n", "");
        if (result.length > maxLength)
            result = `${result.substring(0, maxLength - 3)}...`;
        return result;
    }

    @Command({
        type: "mention",
        pattern: "add quote", 
        auth: true, 
        documentation: {
            description: "Adds a quote", 
            example: "add quote by \"<NAME>\" <NEWLINE> <QUOTE>"
        }
    })
    async addQuote({ message, contents }: ICommandData): Promise<void> {
        const result = quotePattern.exec(contents as string);

        if (result == null)
            return;

        const author = result[1].trim();
        const msg = result[2].trim();

        const repo = getRepository(Quote);

        const newQuote = await repo.save(repo.create({
            author: author,
            message: msg
        }));

        message.reply(`added quote (ID: ${newQuote.id})!`);
    }

    @Command({
        type: "mention",
        pattern: "random quote", 
        documentation: {
            description: "Shows a random quote by someone special...", 
            example: "random quote"
        }
    })
    async postRandomQuote({ message }: ICommandData): Promise<void> {
        const repo = getRepository(Quote);

        const quotes = await repo.query(`  select *
                                                from quote
                                                order by random()
                                                limit 1`) as Quote[];

        if (quotes.length == 0) {
            message.reply("I have no quotes!");
            return;
        }

        const quote = quotes[0];
        message.channel.send(`Quote #${quote.id}:\n*"${quote.message}"*\n- ${quote.author}`);
    }

    @Command({
        type: "mention",
        pattern: "remove quote",
        auth: true,
        documentation: {
            description: "Removes quote. Use \"quotes\" to get the <quote_index>!", 
            example: "remove quote <quote_index>"
        }
    })
    async removeQuote({ message, contents }: ICommandData): Promise<void> {
        const quoteNum = (contents as string).substring("remove quote".length).trim();
        const val = parseInt(quoteNum);
        if (isNaN(val))
            return;

        const repo = getRepository(Quote);

        const res = await repo.delete({ id: val });
        if (res.affected == 0)
            return;

        message.reply(`removed quote #${val}!`);
    }

    @Command({
        type: "mention",
        pattern: "quotes", 
        documentation: {
            description: "Lists all known quotes.", 
            example: "quotes"
        }, 
        auth: true 
    })
    async listQuotes({ message }: ICommandData): Promise<void> {
        const repo = getRepository(Quote);

        const quotes = await repo.find();

        if (quotes.length == 0) {
            message.reply("I have no quotes!");
            return;
        }

        const quotesListing = quotes.reduce((p, c) => `${p}[${c.id}] "${this.minify(c.message, 10)}" by ${c.author}\n`, "\n");
        message.reply(`I know the following quotes:\n\`\`\`${quotesListing}\`\`\``);
    }
}