#[macro_use]
extern crate serenity;
extern crate rand;
//extern crate select;
extern crate sys_info;

use rand::Rng;
use serenity::client::Client;
use serenity::framework::standard::StandardFramework;
use serenity::model::gateway::Ready;
use serenity::prelude::*;
use std::{env, process};

struct Handler;

impl EventHandler for Handler {
	fn ready(&self, ctx: Context, ready: Ready) {
		if let Some(shard) = ready.shard {
			println!(
				"{} is connected on shard {}/{}!",
				ready.user.name, shard[0], shard[1]
			);
			println!("--------------------------------------------");

			use serenity::model::gateway::Game;
			use serenity::model::user::OnlineStatus;
			let game = Game::playing("with knives");
			let status = OnlineStatus::Online;

			ctx.set_presence(Some(game), status);
		}
	}
}

fn main() {
	// Login with a bot token from the environment
		let mut client = Client::new(&env::var("DISCORD_TOKEN").expect("token"), Handler)
		.expect("Error creating client");
	client.with_framework(
		StandardFramework::new()
			.configure(|c| c.prefix("OwO ").case_insensitivity(true))
			.cmd("init", init)
			.cmd("gayculator", gayculator)
			.command("ad", |c| {
				c.cmd(ad).check(|_, msg, _, _| {
					msg.guild_id == Some(serenity::model::id::GuildId(255386835964919810))
				})
			}).cmd("waffle", waffle)
			.cmd("sausage", sausage)
			.cmd("halt", halt)
			.cmd("help", help)
			.cmd("info", info)
			.cmd("ping", ping)
			.cmd("list_srv", list_srv)
			.command("compare_bot", |c| {
				c.cmd(compare_bot).known_as("compare bot")
			})
			.cmd("ship", ship)
			.cmd("uwu", uwu)
		/*	.cmd("lyrics", lyrics) */
			.cmd("host", host),
	);

	// start listening for events by starting a single shard
	if let Err(why) = client.start() {
		println!("An error occurred while running the client: {:?}", why);
	}
}

command!(init(_ctx, message) {
    let num = rand::thread_rng().gen_range(0, 2);
	match num {
	0 => {
		let _ = message.channel_id.say("The Discordinator9000 is ready to kick yer butts!");
	}
	1 => {
		let _ = message.channel_id.say("The Discordinator9000 is ready to take over the world!");
	}
	_ => {
		let _ = message.channel_id.say("Oopsie woopsie! UwU");
	}
}
});

command!(ping(_ctx, message) {
	let _ = message.reply("Pong!");
});

command!(halt(ctx, message) {
	if message.author.id == 254310746450690048 {
		use serenity::model::user::OnlineStatus;
		let status = OnlineStatus::Offline;
		ctx.set_presence(None, status);
		ctx.quit();

		use std::{thread, time};
		let one_s = time::Duration::new(2, 0);
		thread::sleep(one_s);

		process::exit(0);
	} else {
		let _ = message.channel_id.say("no");
	}
});

command!(list_srv(_ctx, message) {
	if message.author.id == 254310746450690048 {
		use serenity::CACHE;
		let cache = CACHE.read();
		let mut list = String::new();
		for (index, guild_lock) in cache.guilds.values().enumerate() {
		    let guild = guild_lock.read();
		    list.push_str(&format!("{}: {}\n", index, guild.name));
		}
		let _ = message.channel_id.say(format!("{}", list));
	}
});

command!(host(_ctx, message) {
	if message.author.id == 254310746450690048 {
		let _ = message.channel_id.say(format!("Debug\nOS: {:?}\nHost: {:?}", sys_info::os_type().unwrap(), sys_info::hostname().unwrap()));
	}
});

command!(ship(_ctx, message, args) {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};

	let first = calculate_hash(&args.single::<String>().unwrap());
	let second = calculate_hash(&args.single::<String>().unwrap());
	let mut slider = String::new();
	let res = (first % second) / 100000000000000000;

	let mut num = 0;
	while num < res / 10 {
		slider.push('▬');
		num += 1;
	}
		slider.push_str(":heart:");
	num = 0;
	while num < (10 - res / 10) {
		slider.push('▬');
		num += 1;
	}
	let _ = message.channel_id.send_message(|m| m
		.embed(|e| e
			.title(format!("{}%", res))
			.description(slider)
			.color(0xff00ce)
		));

	fn calculate_hash<T: Hash>(t: &T) -> u64 {
	    let mut s = DefaultHasher::new();
	    t.hash(&mut s);
	    s.finish()
	}
});

command!(uwu(_ctx, message) {
	let num = rand::thread_rng().gen_range(0, 4);
	match num {
	0 => {
		let _ = message.channel_id.send_message(|m| m
		.embed(|e| e
		.image("https://i.redditmedia.com/qDD9W7NJqTAk31y061TuRW9R8qOcCuEmmCWyOsUEavE.png?fit=crop&crop=faces%2Centropy&arh=2&w=640&s=ebdd3f1970b4fe70ccd24a1958e7fc32")
	)); }
	1 => {
		let _ = message.channel_id.send_message(|m| m
		.embed(|e| e
		.image("https://www.shitpostbot.com/img/sourceimages/smash-that-mfuckn-uwu-button-57b5aa1de9fe4.jpeg")
	)); }
	2 => {
		let _ = message.channel_id.send_message(|m| m
		.embed(|e| e
		.image("https://www.shitpostbot.com/img/sourceimages/fallout-nv-owo-57e586ae15322.jpeg")
	)); }
	3 => {
		let _ = message.channel_id.send_message(|m| m
			.embed(|e| e
			.image("https://i.redditmedia.com/-JaK9YW7mPz2S2xBJmXvW4fZ58uGMa4l6GIgYt3dqZg.jpg?fit=crop&crop=faces%2Centropy&arh=2&w=640&s=ebab29a577346b4d18ec914538b69bb4")
		)); }
	_ => {
	 	let _ = message.channel_id.say("UwU");
	 }
	}
});

command!(gayculator(_ctx, message, args) {
if message.author.id != 191948420141809665 {
	let number_32: i32 = args.trim().parse()
	.expect("ERR!");
	let mut result;
	if number_32 % 2 == 0 {
		result = "You are straight as heck!".to_string();
	} else {
		result = "You are hella gay!".to_string();
	}
	let _ = message.channel_id.send_message(|m| m
		.embed(|e| e
		.title("Gayness level:")
		.description(result)
		.color(0xff00f9)
	));
 }
});

command!(waffle(_ctx, message) {
	let _ = message.channel_id.say("Dongle!");
});

command!(sausage(_ctx, message) {
	let _ = message.channel_id.send_message(|m| m
		.embed(|e| e
		.title("Dongle!")
		.image("https://cdn.discordapp.com/attachments/379673147764506624/431546724637736971/image.png"))
		);
});

command!(ad(_ctx, message) {
		let _ = message.channel_id.send_message(|m| m
			.embed(|e| e
			.title(":b:ottom text")
			***REMOVED***
			.thumbnail("https://i.imgur.com/8MU0gqD.png")
			.color(0x00f3ff))
		);
});

command!(help(_ctx, message) {
	let _ = message.channel_id.send_message(|m| m
		.embed(|e| e
			.title("Availble commands:")
			.description("All commands are case-insensitive")
			.fields(vec![
				("OwO init", "Introduce me", false),
				("OwO ping", "Pong", false),
				("OwO waffle", "Join the **waffle dongle** cult!", false),
				("OwO sausage", "Join the **sausage dongle** cult!", false),
				("OwO help", "Help the fellow humanz!", false),
				("OwO info", "Show information about me!", false),
				("OwO compare_bot ``bot's name``", "Compare me to other robots!", false),
				("OwO ship ``name 1`` ``name 2``", "*shipping intensifies*", false),
				("Admin commands:", "\u{200B}", true),
				("OwO halt", "shut me down", false),
				("OwO list_srv", "list my servers", false),
				("OwO host", "Display host info", false)
			])
			.color(0x000000)
			));
});

command!(info(_ctx, message) {
use serenity::CACHE;
let num = CACHE.read().guilds.len();
	let _ = message.channel_id.send_message(|m| m
		.embed(|e| e
			.title("Discordinator9000's info:")
			.description(":gear: I can do stuff :cucumber:")
			.field("Author:", "#1337", false)
			.field("Server count:", num  , false)
			.field("Invite:", "[Invite link](https://discordapp.com/api/oauth2/authorize?client_id=470350233419907129&permissions=2048&scope=bot)", false )
			.footer(|f| f
			.text("Written in Rust using Serenity library"))
			.color(0xee657)
			));
});

command!(compare_bot(_ctx, message, args) {
if message.author.id != 191948420141809665 {
let text: String = args.trim().parse()
	.expect("ERR!");
	if text.to_lowercase().contains("nib") {
		let _ = message.channel_id.say("I am superior to NibBot");
	} else if text.to_lowercase().contains("amit") {
		let _ = message.channel_id.say("Amiter is big dumb");
	} else if text.to_lowercase().contains("discordinator") {
		let _ = message.channel_id.say("Metaaaa, dude");
	} else {
		let _ = message.channel_id.say(format!("Me and {} are friends!", text));
	}
}
});

/*command!(lyrics(_ctx, _message, _args) {
	use select::document::Document;
	use select::predicate::{Predicate, Attr, Class, Name};

}); */

/*command!(embed_test(_ctx, message) {
	let _ = message.channel_id.send_message(|m| m
		.content("Hello, World!")
		.embed(|e| e
		.title("This is a title")
		.description("This is a description")
		.fields(vec![
			("This is the first field", "This is a field body", true),
			("This is the second field", "Both of these fields are inline", true),
		])
		.field("This is the third field", "This is not an inline field", false)
		.footer(|f| f
		.text("This is a footer"))));
}); */
