import axios from "axios";
import { CacheType, Client, CommandInteraction, Guild, GuildMember, MessageActionRow, MessageButton, TextChannel, User } from "discord.js";
import { Database } from "quickmongo";
import { v5 as uuid } from 'uuid';

export default interface AyaHelper {
    client: Client;
    mongoUrl: string;
    db: Database;
    moderation: AyaModeration;
    economy: AyaEconomy;
    tickets: AyaTickets;
    fun: AyaFun;
    nsfw: AyaNsfw;
    anime: AyaAnime;
    constructor(
        client: Client,
        mongoUrl: string,
        onConnecting: Function,
        onConnect: Function,
        onError: Function,
    );
}


export interface AyaModeration {
    db: Database;
    client: Client;
    constructor(db: Database, client: Client);
    timeout(member: GuildMember, time: number, reason?: string): Promise<boolean>;
    ban(member: GuildMember, reason?: string, soft?: boolean): Promise<boolean>;
    kick(member: GuildMember, reason?: string): Promise<boolean>;
    purge(channel: TextChannel, amount: number): Promise<boolean>;
    infractions(member: GuildMember): Promise<Infraction[]>;
    addInfraction(infraction: Infraction): Promise<void>;
    removeInfraction(user: User, id: string): Promise<Infraction>;
}

export interface Infraction {
    id: string;
    member: GuildMember;
    reason?: string;
    type: 'BAN' | 'KICK' | 'TIMEOUT' | 'UNKNOWN';
    constructor(member: GuildMember, type: 'BAN' | 'KICK' | 'TIMEOUT' | 'UNKNOWN', reason?: string);
}

export interface AyaEconomy {
    db: Database;
    client: Client;
    constructor(db: Database, client: Client);
    balance(member: GuildMember): Promise<Balance>;
    add(member: GuildMember, amount: number, type: 'WALLET' | 'BANK' | 'TOTAL_BANK') : Promise<Balance>;
    remove(member: GuildMember, amount: number, type: 'WALLET' | 'BANK' | 'TOTAL_BANK') : Promise<Balance>;
    getDefaultBalance() : { wallet: number, bank: number, totalBank: number };
    shop() : Promise<Shop>;
    inventory(member: GuildMember) : Promise<Inventory>;
    addItem(member: GuildMember, item: Item) : Promise<Inventory>;
    removeItem(member: GuildMember, name: string, amount: number) : Promise<Inventory>;
}

export interface Inventory {
    member: GuildMember;
    items: Item[];
    constructor(member: GuildMember, items: Item[]);
}

export interface Shop {
    items: Item[];
    constructor(items: Item[]);
}

export interface Item {
    name: string;
    cost: number;
    amount?: number;
    icon?: string;
    owned?: boolean;
    constructor(name: string, cost: number, amount?: number, icon?: string, owned?: boolean);
}

export interface Balance {
    wallet: number;
    bank: number;
    totalBank: number;
    constructor(wallet: number, bank: number, totalBank: number);
}

export interface AyaTickets {
    db: Database;
    client: Client;
    constructor(db: Database, client: Client);
    getAll(guildId?: string) : Promise<Ticket[]>;
    removeAll(guildId?: string) : Promise<boolean>;
    get(member: GuildMember) : Promise<Ticket>;
    find(id: string) : Promise<Ticket>;
    remove(id: string) : Promise<Ticket>;
    create(member: GuildMember) : Promise<Ticket>;
}

export interface Ticket {
    member: GuildMember;
    channel: TextChannel;
    id: string;
    constructor(member: GuildMember, channel: TextChannel);
}

export interface AyaFun {
    client: Client;
    constructor(client: Client);
    eightBall(answers: []) : string;
    rps(user: GuildMember, user2: GuildMember, interaction: CommandInteraction<CacheType>) : Promise<void>;
    coinflip() : 'tails' | 'heads';

    bird() : Promise<FunRequest>;
    cat() : Promise<FunRequest>;
    dog() : Promise<FunRequest>;
    fox() : Promise<FunRequest>;
    panda() : Promise<FunRequest>;

    birdfact() : Promise<string>;
    catfact() : Promise<FunRequest>;
    dogfact() : Promise<string>;
    pandafact() : Promise<string>;
    
    meme() : Promise<MemeRequest>;
    
    gayify(member: GuildMember) : FunRequest;
    jail(member: GuildMember) : FunRequest;
    triggered(member: GuildMember) : FunRequest;
}

export interface MemeRequest {
    title: string;
    image: string;
    constructor(title: string, image: string);
}

export interface FunRequest {
    image: string;
    constructor(image: string);
}

export interface AyaNsfw {
    client: Client;
    constructor(client: Client);
    hentai() : Promise<NsfwRequest>;
    neko() : Promise<NsfwRequest>;
    lesbian() : Promise<NsfwRequest>;
    kuni() : Promise<NsfwRequest>;
    cumsluts() : Promise<NsfwRequest>;
    classic() : Promise<NsfwRequest>;
    boobs() : Promise<NsfwRequest>;
    blowjob() : Promise<NsfwRequest>;
    yuri() : Promise<NsfwRequest>;
    tits() : Promise<NsfwRequest>;
    solo() : Promise<NsfwRequest>;
    feet() : Promise<NsfwRequest>;
    request(type: string) : Promise<NsfwRequest>;
}

export interface NsfwRequest {
    type: string;
    image: string;
    constructor(type: string, image: string);
}

export interface AyaAnime {
    client: Client;
    constructor(client: Client);
    slap(user: GuildMember, user2: GuildMember) : Promise<AnimeRequest>;
    poke(user: GuildMember, user2: GuildMember) : Promise<AnimeRequest>;
    pat(user: GuildMember, user2: GuildMember) : Promise<AnimeRequest>;
    tickle(user: GuildMember, user2: GuildMember) : Promise<AnimeRequest>;
    cuddle(user: GuildMember, user2: GuildMember) : Promise<AnimeRequest>;
    kiss(user: GuildMember, user2: GuildMember) : Promise<AnimeRequest>;
    meow(user: GuildMember, user2: GuildMember) : Promise<AnimeRequest>;
    waifu() : Promise<AnimeRequest>;
    request(type): Promise<AnimeRequest>;
}

export interface AnimeRequest {
    type: string;
    image: string;
    constructor(type: string, image: string);
}

export default class AyaHelper {
    client: Client;
    mongoUrl: string;
    db: Database;
    moderation: AyaModeration;
    economy: AyaEconomy;
    tickets: AyaTickets;
    fun: AyaFun;
    nsfw: AyaNsfw;
    anime: AyaAnime;
    constructor(
        client: Client,
        mongoUrl: string,
        onConnecting: Function,
        onConnect: Function,
        onError: Function,
    ) {
        this.client = client;
        this.mongoUrl = mongoUrl;
        this.db = new Database(mongoUrl);
        this.db.connect();
        this.db.on('connecting', () => onConnecting());
        this.db.on('connected', () => onConnect());
        this.db.on('error', () => onError());
        this.moderation = new AyaModeration(this.db, client);
        this.economy = new AyaEconomy(this.db, client);
        this.tickets = new AyaTickets(this.db, client);
        this.fun = new AyaFun(client);
        this.nsfw = new AyaNsfw(client);
        this.anime = new AyaAnime(client);
    }
}

export class AyaModeration {
    db: Database;
    client: Client;
    constructor(db: Database, client: Client) {
        this.db = db;
        this.client = client;
    }
    async timeout(member: GuildMember, time: number, reason: string = 'No Reason') : Promise<boolean> {
        return member.timeout(time, reason)
            .then(() => true)
            .catch(() => false)
    }
    async ban(member: GuildMember, reason: string = 'No Reason', soft: boolean = false): Promise<boolean> {
        return member.ban({
            reason: reason
        }).then(() => {
            if (soft) {
                return member.guild.bans.remove(member.user.id, reason)
                    .then(() => true)
                    .then(() => false);
            }
            return true;
        }).catch(() => false);
    }
    async kick(member: GuildMember, reason: string = 'No Reason'): Promise<boolean> {
        return member.kick(reason)
            .then(() => true)
            .catch(() => false);
    }
    async purge(channel: TextChannel, amount: number): Promise<boolean> {
        return channel.bulkDelete(amount)
            .then(() => true)
            .catch(() => false);
    }
    async infractions(member: GuildMember): Promise<Infraction[]> {
        let inf: any = await this.db.get(`infractions_${member.user.id}`) ?? [];
        return inf.map(a => new Infraction(
            member,
            a.type,
            a.reason
        ));
    }
    async addInfraction(infraction: Infraction): Promise<void> {
        let inf: any = await this.db.get(`infractions_${infraction.member.user.id}`) ?? [];
        inf.push({
            id: infraction.id,
            member: infraction.member.user.id,
            type: infraction.type,
            reason: infraction.reason
        });
        await this.db.set(`infractions_${infraction.member.user.id}`, inf);
    }
    async removeInfraction(user: User, id: string): Promise<Infraction> {
        let inf: any = await this.db.get(`infractions_${user.id}`) ?? [];
        let infraction = inf.find(a => a.id === id);
        if (!infraction) return null;
        await this.db.set(`infractions_${user.id}`, inf.filter(a => a.id != id));
        return infraction;
    }
}

export class Infraction {
    id: string;
    member: GuildMember;
    reason?: string;
    type: 'BAN' | 'KICK' | 'TIMEOUT' | 'UNKNOWN';
    constructor(member: GuildMember, type: 'BAN' | 'KICK' | 'TIMEOUT' | 'UNKNOWN', reason?: string) {
        this.id = (uuid as any)();
        this.member = member;
        this.type = type ?? 'UNKNOWN';
        this.reason = reason || 'No Reason provided';
    }
}

export class AyaEconomy {
    db: Database;
    client: Client;
    constructor(db: Database, client: Client) {
        this.db = db;
        this.client = client;
    }
    async balance(member: GuildMember): Promise<Balance> {
        let balance: any = await this.db.get(`balance_${member.user.id}`) ?? this.getDefaultBalance();
        return new Balance(
            balance.wallet,
            balance.bank,
            balance.totalBank
        )
    }
    async add(member: GuildMember, amount: number, type: 'WALLET' | 'BANK' | 'TOTAL_BANK'): Promise<Balance> {
        let balance: any = await this.db.get(`balance_${member.user.id}`) ?? this.getDefaultBalance();
        if (type === 'WALLET')
            balance.wallet = (balance.wallet ?? 0) + amount;
        if (type === 'BANK')
            balance.bank = (balance.bank ?? 0) + amount;
        if (type === 'TOTAL_BANK')
            balance.totalBank = (balance.totalBank ?? 0) + amount;
        await this.db.set(`balance_${member.user.id}`, balance);
        return new Balance(
            balance.wallet,
            balance.bank,
            balance.totalBank
        )
    }
    async remove(member: GuildMember, amount: number, type: 'WALLET' | 'BANK' | 'TOTAL_BANK'): Promise<Balance> {
        let balance: any = await this.db.get(`balance_${member.user.id}`) ?? this.getDefaultBalance();
        if (type === 'WALLET')
            balance.wallet = (balance.wallet ?? 0) - amount;
        if (type === 'BANK')
            balance.bank = (balance.bank ?? 0) - amount;
        if (type === 'TOTAL_BANK')
            balance.totalBank = (balance.totalBank ?? 0) - amount;
        await this.db.set(`balance_${member.user.id}`, balance);
        return new Balance(
            balance.wallet,
            balance.bank,
            balance.totalBank
        )
    }
    getDefaultBalance() {
        return { wallet: 0, bank: 0, totalBank: 0 }
    }
    async shop(): Promise<Shop> {
        return new Shop(
            [
                new Item('coming soon', 200)
            ]
        );
    }
    async inventory(member: GuildMember): Promise<Inventory> {
        let inventory: any = await this.db.get(`inventory_${member.user.id}`) ?? {
            member: null,
            items: []
        }
        return new Inventory(
            member,
            inventory.items
        );
    }
    async addItem(member: GuildMember, item: Item): Promise<Inventory> {
        let inventory: any = await this.db.get(`inventory_${member.user.id}`) ?? {
            member: null,
            items: [],
        }
        inventory.items.push(item);
        await this.db.set(`inventory_${member.user.id}`, inventory);
        return new Inventory(
            member,
            inventory.items
        )
    }
    async removeItem(member: GuildMember, name: string, amount: number): Promise<Inventory> {
        let inventory: any = await this.db.get(`inventory_${member.user.id}`) ?? {
            member: null,
            items: []
        }
        inventory.items = inventory.items.map(a => {
            if (a.name === name) {
                a.amount = a.amount - amount;
                if (a.amount <= 0) {
                    return null;
                }
            }
            return a;
        }).filter(a => a != null);
        await this.db.set(`inventory_${member.user.id}`, inventory);
        return new Inventory(
            member,
            inventory.items
        );
    }
}

export class Inventory {
    member: GuildMember;
    items: Item[];
    constructor(member: GuildMember, items: Item[]) {
        this.member = member;
        this.items = items;
    }
}

export class Shop {
    items: Item[];
    constructor(items: Item[]) {
        this.items = items;
    }
}

export class Item {
    icon?: string;
    name: string;
    cost: number;
    amount?: number;
    owned?: boolean;
    constructor(name: string, cost: number, amount?: number, icon?: string, owned?: boolean) {
        this.name = name;
        this.cost = cost;
        this.amount = amount;
        this.icon = icon;
        this.owned = owned;
    }
}

export class Balance {
    wallet: number;
    bank: number;
    totalBank: number;
    constructor(wallet: number, bank: number, totalBank: number) {
        this.wallet = wallet;
        this.bank = bank;
        this.totalBank = totalBank;
    }
}

export class AyaTickets {
    db: Database;
    client: Client;
    constructor(db: Database, client: Client) {
        this.db = db;
        this.client = client;
    }
    async getAll(guildId?: string): Promise<Ticket[]> {
        let all = (await this.db.all()).filter((a: any) => {
            return guildId ? (a.ID.startsWith('ticket-') && a.data.guild === guildId) : a.ID.startsWith('ticket-')
        });
        return all.map((a: any) => {
            let guild = this.client.guilds.cache.get(a.data.guild);
            return new Ticket(
                guild,
                guild.members.cache.get(a.data.user).user,
                (guild.channels.cache.get(a.data.channel) as TextChannel)
            );
        })
    }
    async removeAll(guildId: string): Promise<boolean> {
        let all = (await this.db.all()).filter((a: any) => a.ID.startsWith('ticket-') && a.data.guild === guildId);
        try {
            all.forEach((a: any) => {
                this.db.delete(a.ID);
            });
            return true;
        } catch (err) {
            return false;
        }
    }
    async get(member: GuildMember): Promise<Ticket> {
        let t: any = await this.db.get(`ticket-${member.user.id}`);
        let guild = this.client.guilds.cache.get(t.guild);
        return new Ticket(
            guild,
            member.user,
            (guild.channels.cache.get(t.channel) as TextChannel)
        )
    }
    async find(id: string): Promise<Ticket> {
        let t: any = await this.db.get(`ticket-${id}`);
        let guild = this.client.guilds.cache.get(t.guild);
        return new Ticket(
            guild,
            guild.members.cache.get(id).user,
            (guild.channels.cache.get(t.channel) as TextChannel)
        );
    }
    async remove(id: string): Promise<Ticket> {
        let tickets = await this.getAll();
        let ticket = tickets.find(a => a.id === id);
        if (!ticket) return null;
        await this.db.delete(`ticket-${id}`);
        return ticket;
    }
    async create(member: GuildMember): Promise<Ticket> {
        let g = member.guild;
        return g.channels.create(`ticket-${member.user.id}`, {
            permissionOverwrites: [{
                type: 'role',
                id: g.id,
                deny: ['VIEW_CHANNEL', 'SEND_MESSAGES']
            }, {
                type: 'member',
                id: member.user.id,
                allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'ATTACH_FILES']
            }]
        }).then((c) => {
            let ticket = new Ticket(
                g,
                member.user,
                (c as TextChannel)
            );
            this.db.set(`ticket-${member.user.id}`, {
                guild: g.id,
                user: member.user.id,
                channel: c.id
            }, -1);
            return ticket;
        }).catch(() => null);
    }
}

export class Ticket {
    guild: Guild;
    user: User;
    channel: TextChannel;
    id: string;
    constructor(guild: Guild, user: User, channel: TextChannel) {
        this.guild = guild;
        this.user = user;
        this.channel = channel;
        this.id = user.id;
    }
}

export class AyaFun {
    client: Client;
    constructor(client: Client) {
        this.client = client;
    }
    eightBall(answers: []): string {
        return answers[Math.floor(Math.random() * answers.length)];
    }
    async rps(user: GuildMember, user2: GuildMember, interaction: CommandInteraction<CacheType>): Promise<void> {
        let rps = ['Rock', 'Paper', 'Scissors'];
        let icons = ['🗻', '📰', '✂'];
        await interaction.deferReply();
        let msg = await interaction.editReply({
            embeds: [{
                title: 'Rock Paper Scissors',
                description: `${user.user} vs. ${user2.user}\n??? - ???\nWinner: ???`,
                color: 'BLURPLE',
                timestamp: new Date()
            }]
        });
        let answered = [false, false];
        let chosen = ['???', '???'];
        [user, user2].forEach(async (u, i) => {
            let other: GuildMember = null;
            if (i === 1) other = user;
            other = user2;
            let d = await u.user.send({
                embeds: [{
                    title: 'Choose',
                    description: `Choose between ${icons[0]} (Rock), ${icons[1]} (Paper), ${icons[2]} (Scissors)`,
                    color: 'GREEN',
                    timestamp: new Date(),
                    footer: {
                        text: `You are against ${other.user.tag}`,
                        iconURL: other.user.displayAvatarURL({
                            dynamic: true,
                            format: 'png'
                        })
                    }
                }],
                components: [new MessageActionRow().addComponents([
                    new MessageButton()
                        .setEmoji(icons[0])
                        .setLabel(rps[0])
                        .setStyle('PRIMARY')
                        .setCustomId(rps[0])
                ])]
            });
            d.awaitMessageComponent({
                filter: (m) => rps.includes(m.customId),
                componentType: 'BUTTON'
            }).then(async bt => {
                bt.reply(`Thanks for choosing! Wait for your opponent to choose! <#${interaction.channelId}>`);
                let random = Math.floor(Math.random() * rps.length);
                answered[i] = true;
                chosen[i] = `${icons[random]} ${rps[random]}`;
                if (answered[0] === true && answered[1] === true) {
                    let winner = '???';
                    let c1 = chosen[0];
                    let c2 = chosen[1];
                    if (
                        (c1.includes('Rock') && c2.includes('Paper')) ||
                        (c1.includes('Scissors') && c2.includes('Paper')) ||
                        (c1.includes('Rock') && c2.includes('Scissors'))
                    ) {
                        winner = c1;
                    } else if (
                        (c2.includes('Rock') && c1.includes('Paper')) ||
                        (c2.includes('Scissors') && c1.includes('Paper')) ||
                        (c2.includes('Rock') && c1.includes('Scissors'))
                    ) {
                        winner = c2;
                    } else {
                        winner = 'No one';
                    }
                    await interaction.editReply({
                        embeds: [{
                            title: 'Rock Paper Scissors',
                            description: `${user.user} vs. ${user2.user}\n${chosen[0]} - ${chosen[1]}\nWinner: ${winner === '???' ? 'Couldn\'t find a winner' : (winner === 'No one' ? 'It\'s a tie!' : winner)}`,
                            color: 'BLURPLE',
                            timestamp: new Date()
                        }]
                    });
                }
            });
        })
    }
    coinflip(): 'tails' | 'heads' {
        let sides = ['tails', 'heads'];
        return (sides[Math.floor(Math.random() * sides.length)] as any);
    }

    async bird() {
        return axios('http://shibe.online/api/birds')
            .then((r) => new FunRequest(r.data[0]));
    }
    async birdfact() {
        return axios('https://some-random-api.ml/animal/fox')
            .then((r) => r.data.fact);
    }
    async cat() {
        return axios('http://shibe.online/api/cats')
            .then(r => new FunRequest(r.data[0]));
    }
    async dog() {
        return axios('http://shibe.online/api/shibes')
            .then(r => new FunRequest(r.data[0]));
    }
    async fox() {
        return axios('https://randomfox.ca/floof')
            .then(r => new FunRequest(r.data.image));
    }
    async foxfact() {
        return axios('https://some-random-api.ml/animal/fox')
            .then(r => r.data.fact);
    }
    async panda() {
        return axios('https://some-random-api.ml/animal/panda')
            .then(r => new FunRequest(r.data.image));
    }
    async pandafact() {
        return axios('https://some-random-api.ml/animal/panda')
            .then(r => r.data.fact);
    }
    async catfact() {
        return axios('https://some-random-api.ml/animal/cat')
            .then(r => r.data.fact);
    }
    async dogfact() {
        return axios('https://some-random-api.ml/animal/dog')
            .then(r => r.data.fact);
    }

    async meme() {
        return axios('https://some-random-api.ml/meme')
            .then(r => new MemeRequest(r.data.caption, r.data.image));
    }

    gayify(member: GuildMember): FunRequest {
        let link = 'https://some-random-api.ml/canvas/gay?avatar=' + member.user.displayAvatarURL({
            dynamic: false,
            format: 'png'
        });
        return new FunRequest(link);
    }
    jail(member: GuildMember): FunRequest {
        let link = 'https://some-random-api.ml/canvas/jail?avatar=' + member.user.displayAvatarURL({
            dynamic: false,
            format: 'png'
        });
        return new FunRequest(link);
    }
    triggered(member: GuildMember): FunRequest {
        let link = 'https://some-random-api.ml/canvas/triggered?avatar=' + member.user.displayAvatarURL({
            dynamic: false,
            format: 'png'
        });
        return new FunRequest(link);
    }
}

export class MemeRequest {
    title: string;
    image: string;
    constructor(title, image) {
        this.title = title;
        this.image = image;
    }
}

export class FunRequest {
    image: string;
    constructor(image) { this.image = image }
}

export class AyaNsfw {
    client: Client;
    constructor(client: Client) {
        this.client = client;
    }
    async hentai(): Promise<NsfwRequest> {
        return await this.request('Random_hentai_gif');
    }
    async neko(): Promise<NsfwRequest> {
        return await this.request('nsfw_neko_gif');
    }
    async lesbian(): Promise<NsfwRequest> {
        return await this.request('les');
    }
    async kuni(): Promise<NsfwRequest> {
        return await this.request('les');
    }
    async cumsluts(): Promise<NsfwRequest> {
        return await this.request('cum');
    }
    async classic(): Promise<NsfwRequest> {
        return await this.request('classic');
    }
    async boobs(): Promise<NsfwRequest> {
        return await this.request('boobs');
    }
    async blowjob(): Promise<NsfwRequest> {
        return await this.request('bj');
    }
    async yuri(): Promise<NsfwRequest> {
        return await this.request('yuri');
    }
    async tits(): Promise<NsfwRequest> {
        return await this.request('tits');
    }
    async solo(): Promise<NsfwRequest> {
        return await this.request('solog');
    }
    async feet(): Promise<NsfwRequest> {
        return await this.request('feetg');
    }
    async request(type: string): Promise<NsfwRequest> {
        return await axios({
            url: `https://nekos.life/api/v2/img/` + type,
        }).then(r => {
            return new NsfwRequest(type, r.data.url);
        }).catch(e => {
            console.log(e.isAxiosError ? e.toJSON() : e);
            return new NsfwRequest(type, null);
        });
    }
}
export class NsfwRequest {
    type: string;
    image: string;
    constructor(type, image) {
        this.type = type;
        this.image = image;
    }
}

export class AyaAnime {
    client: Client;
    constructor(client: Client) {
        this.client = client;
    }
    async slap(user: GuildMember, user2: GuildMember): Promise<AnimeRequest> {
        return await this.request('slap');
    }
    async poke(user: GuildMember, user2: GuildMember): Promise<AnimeRequest> {
        return await this.request('poke');
    }
    async pat(user: GuildMember, user2: GuildMember): Promise<AnimeRequest> {
        return await this.request('pat');
    }
    async tickle(user: GuildMember, user2: GuildMember): Promise<AnimeRequest> {
        return await this.request('tickle');
    }
    async cuddle(user: GuildMember, user2: GuildMember): Promise<AnimeRequest> {
        return await this.request('cuddle');
    }
    async kiss(user: GuildMember, user2: GuildMember): Promise<AnimeRequest> {
        return await this.request('kiss');
    }
    async meow(user: GuildMember, user2: GuildMember): Promise<AnimeRequest> {
        return await this.request('meow');
    }
    async waifu(): Promise<AnimeRequest> {
        return await this.request('waifu');
    }

    async request(type: string): Promise<AnimeRequest> {
        return await axios({
            url: `https://nekos.life/api/v2/img/` + type,
        }).then(r => {
            return new AnimeRequest(type, r.data.url);
        }).catch(e => {
            console.log(e.isAxiosError ? e.toJSON() : e);
            return new AnimeRequest(type, null);
        });
    }
}


export class AnimeRequest {
    type: string;
    image: string;
    constructor(type: string, image: string) { this.type = type; this.image = image }
}