import * as MastodonAPI from "/JS/MastodonAPI.js";
import * as BlueskyAPI from "/JS/BlueskyAPI.js";
import * as TumblrAPI from "/JS/TumblrAPI.js";
import * as Variables from "/JS/Variables.js";

// GLOBAL VARS
// fuck you. I see why website developers use divs so fucking often.
let Warning = document.getElementsByClassName("WarningMessage")[0];
let Main = document.getElementsByClassName("MainBefore")[0];
let ContainerContainer = document.getElementsByClassName("PostContainerContainer")[0];
let ClickableContainers = ContainerContainer.getElementsByClassName("PostContainer")[2].children;

let BrowserWidth = window.innerWidth;
let BrowserHeight = window.innerHeight;

let ArrowsButton = document.getElementsByClassName("Arrow");

let SettingButton = document.getElementsByClassName("Setting")[0];
let MailButton = document.getElementsByClassName("Mail")[0];
let PostingButton = document.getElementsByClassName("Posting")[0];
let FeedButton = document.getElementsByClassName("Feed")[0];
let TimeAccountButton = document.getElementsByClassName("Time")[0];

// Sounds
const ButtonSound = new Audio("Audio/button-305770.mp3");
const WarningClick = new Audio("Audio/button-pressed-38129.mp3");

// Discoverability
let Discover = false;

// Update a timer
function UpdateTime() {
	let TimeNow = new Date();
	let Hour = TimeNow.getHours();
	let Minute = TimeNow.getMinutes();
	
	let WebsiteTime = document.getElementsByClassName("Time")[0]
	WebsiteTime.innerHTML = "";
	if (Hour < 10) {
		WebsiteTime.innerHTML = WebsiteTime.innerHTML + "0" + Hour;
	} else {
		WebsiteTime.innerHTML = WebsiteTime.innerHTML + Hour;
	}
	WebsiteTime.innerHTML = WebsiteTime.innerHTML + ":";
	if (Minute < 10) {
		WebsiteTime.innerHTML = WebsiteTime.innerHTML + "0" + Minute;
	} else {
		WebsiteTime.innerHTML = WebsiteTime.innerHTML + Minute;
	}
}

setInterval(UpdateTime, 1000);

// When the window is resized
onresize = (event) => {
	BrowserWidth = window.innerWidth;
	BrowserHeight = window.innerHeight;
	window.dispatchEvent(new Event("load"));
}

// When the window finally reloads
onload = (event) => {
	Warning.setAttribute("style", "height: " + BrowserHeight + "px; width: " + BrowserWidth + "px;");
	Main.setAttribute("style", "height: " + BrowserHeight + "px; width: " + BrowserWidth + "px;");
	ArrowsButton[1].setAttribute("style", "left: " + (BrowserWidth - 100) + "px;");
}

// On clicking the warning message
Warning.onclick = (event) => {
	Warning.classList.add("WarningFadeOutAnimation");
	// fixes a damn stupid bug
	document.getElementsByClassName("BlinkAnimation")[0].classList.remove("BlinkAnimation");
	Main.classList.add("MainFadeInAnimation");
	Main.classList.remove("MainBefore");
	WarningClick.play();
	setTimeout(() => {
		Main.classList.remove("MainFadeInAnimation");
		Main.classList.add("MainAfter");
	}, 5000);
	Main = document.getElementsByClassName("MainFadeInAnimation")[0];
	PosterContainerUpdate();
}

let ArrowRunning = false;

// Clicking the next button
ArrowsButton[1].onclick = (event) => {
	if (!ContainerContainer.classList.contains("NextAnimation") && ArrowRunning == false) {
		ArrowRunning = true;
		UpdateOtherContainers(1);
		ContainerContainer.classList.add("NextAnimation");
		ButtonSound.play();
		setTimeout(() => {
			ContainerContainer.classList.remove("NextAnimation");
		}, 1000);
		PosterContainerUpdate("Forward");
		ArrowRunning = false;
	}
}

// Clicking the back button
ArrowsButton[0].onclick = (event) => {
	if (!ContainerContainer.classList.contains("BackAnimation") && ArrowRunning == false) {
		ArrowRunning = true;
		UpdateOtherContainers(3);
		ContainerContainer.classList.add("BackAnimation");
		ButtonSound.play();
		setTimeout(() => {
			ContainerContainer.classList.remove("BackAnimation");
		}, 1000);
		PosterContainerUpdate("Backward");
		ArrowRunning = false;
	}
}

function UpdateOtherContainers(Num) {
	let Posts = ContainerContainer.getElementsByClassName("PostContainer")[Num].children;
	for (let i = 0; i < ClickableContainers.length; i++) {
		Posts[i].getElementsByClassName("Username")[0].innerHTML = ClickableContainers[i].getElementsByClassName("Username")[0].innerHTML;
		Posts[i].getElementsByClassName("PostContent")[0].innerHTML = ClickableContainers[i].getElementsByClassName("PostContent")[0].innerHTML;
	}
}

// These numbers are here so you don't go back.
let MastodonLoadedFeed = [];
let BlueskyLoadedFeed = [];
let CurrentThing = 0;
let WebsiteAPIType = [];

let Mastodon = true;
let Bluesky = true;

// This will allow you to click on a post and get an "expended" version of that post.
for (let i of ClickableContainers) {
	i.onclick = (event) => {
		let number = parseInt(i.getAttribute("number"));
		let post;
		let website;
		// Roundabout way of doing things. Very funny.
		website = WebsiteAPIType[number];
		if (WebsiteAPIType[number] == "Mastodon") {
			post = MastodonLoadedFeed[CurrentThing + number];
		} else if (WebsiteAPIType[number] == "Bluesky") {
			if (Mastodon == true) {
				// *hardcoded bullshit*
				number = number - 6;
			}
			post = BlueskyLoadedFeed[CurrentThing + number];
		} else {
			return;
		}
		// Save some info
		localStorage.setItem("post", JSON.stringify(post));
		document.location.href = "/expanded?website=" + website;
	}
}

// Call this to update the things :)
async function PosterContainerUpdate(Direction) {
	let Lim = 6;
	let Website = localStorage.getItem(Variables.MastodonWebsite);
	
	// Mastodon gaining of timeline.
	if (localStorage.getItem(Variables.MastodonWebsite) == null) {
		console.log("No Mastodon instance. multiplying posts by 2...");
		Lim = Lim * 2;
		Mastodon = false;
	} else if (MastodonLoadedFeed == 0) {
		// If discover is turned on...
		if (Discover == true) {
			if (localStorage.getItem("Remote") != null) {
				MastodonLoadedFeed = await MastodonAPI.GetPublicTimeline(true, true, localStorage.getItem(Variables.MastodonWebsite), "");
			} else {
				MastodonLoadedFeed = await MastodonAPI.GetPublicTimeline(true, false, localStorage.getItem(Variables.MastodonWebsite), "");
			}
		} else {
			MastodonLoadedFeed = await MastodonAPI.GetTimeline("");
		}
	}
	// Bluesky gaining of timeline.
	if (localStorage.getItem(Variables.BlueskyPDS) == null) {
		console.log("No Bluesky instance. multiplying posts by 2...");
		Lim = Lim * 2;
		Bluesky = false;
	} else if (BlueskyLoadedFeed.length == 0) {
		if (Discover == true) {
			BlueskyLoadedFeed = await BlueskyAPI.GetPublicTimeline("").then((response) => response.feed);
		} else {
			BlueskyLoadedFeed = await BlueskyAPI.GetTimeline("").then((response) => response.feed);
		}
	}
	if (Direction == "Forward") {
		CurrentThing = CurrentThing + Lim;
	} else if (Direction == "Backward") {
		if (CurrentThing - Lim >= 0) {
			CurrentThing = CurrentThing - Lim;
		}
	}
	// The first one is for counting.
	// The countergroup increments to another timeline once posts hit the "limit".
	let counter = 0;
	let countergroup = 0;
	if (Mastodon == false) {
		countergroup = countergroup + 1;
	}
	// This var is meant to stop "already seen" posts.
	let BlueskyPostsDup = [];
	WebsiteAPIType = [];
	for (let i of ClickableContainers) {
		switch(countergroup) {
			// Mastodon
			case 0:
				// Begin by having the website we are using get pushed to the expanded view array and clean out the HTML.
				WebsiteAPIType.push("Mastodon");
				i.getElementsByClassName("PostContent")[0].innerHTML = "";
				i.getElementsByClassName("Username")[0].innerHTML = "";
				// Public stuff
				if (MastodonLoadedFeed[CurrentThing + counter + 1] == undefined) {
					let TempFeed;
					if (Discover == true) {
						if (localStorage.getItem("Remote") != null) {
							TempFeed = await MastodonAPI.GetPublicTimeline(true, true, localStorage.getItem(Variables.MastodonWebsite), MastodonLoadedFeed[CurrentThing + counter].id);
						} else {
							TempFeed = await MastodonAPI.GetPublicTimeline(true, false, localStorage.getItem(Variables.MastodonWebsite), MastodonLoadedFeed[CurrentThing + counter].id);
						}
					} else {
						TempFeed = await MastodonAPI.GetTimeline(MastodonLoadedFeed[CurrentThing + counter].id);
					}
					MastodonLoadedFeed = await MastodonLoadedFeed.concat(TempFeed);
				}
				// Put the reblog into the regular post; Make changes as necessary.
				if (MastodonLoadedFeed[CurrentThing + counter].reblog != null && typeof MastodonLoadedFeed[CurrentThing + counter].reblog != "string") {
					// Fix a reblog issue.
					i.getElementsByClassName("Username")[0].innerHTML = MastodonLoadedFeed[CurrentThing + counter].reblog.account.acct + " ( R: " + MastodonLoadedFeed[CurrentThing + counter].account.acct + " )";
					let ReblogFix = MastodonLoadedFeed[CurrentThing + counter].account.acct;
					MastodonLoadedFeed[CurrentThing + counter] = MastodonLoadedFeed[CurrentThing + counter].reblog;
					MastodonLoadedFeed[CurrentThing + counter].reblog = ReblogFix;
				} else if (MastodonLoadedFeed[CurrentThing + counter].reblog != null && typeof MastodonLoadedFeed[CurrentThing + counter].reblog == "string") {
					// this function is if the changes are already made.
					i.getElementsByClassName("Username")[0].innerHTML = MastodonLoadedFeed[CurrentThing + counter].account.acct + " ( R: " + MastodonLoadedFeed[CurrentThing + counter].reblog + " )";
				} else {
					i.getElementsByClassName("Username")[0].innerHTML = MastodonLoadedFeed[CurrentThing + counter].account.acct;
				}
				// Check for images.
				if (MastodonLoadedFeed[CurrentThing + counter].media_attachments.length != 0) {
					if (MastodonLoadedFeed[CurrentThing + counter].media_attachments[0].type == "image") {
						i.getElementsByClassName("PostContent")[0].innerHTML += "This post has an image!<br/>";
					} else if (MastodonLoadedFeed[CurrentThing + counter].media_attachments[0].type == "video" || MastodonLoadedFeed[CurrentThing + counter].media_attachments[0].type == "gifv") {
						i.getElementsByClassName("PostContent")[0].innerHTML += "This post has a video!<br/>";
					}
				}
				// Check for a thread.
				if (MastodonLoadedFeed[CurrentThing + counter].in_reply_to_id != null) {
					i.getElementsByClassName("PostContent")[0].innerHTML += "This post is a thread!<br/>";
				}
				// Content warning. Don't show the content unless clicked!!!
				if (MastodonLoadedFeed[CurrentThing + counter].spoiler_text != "") {
					i.getElementsByClassName("PostContent")[0].innerHTML += "<b>WARNING: " + MastodonLoadedFeed[CurrentThing + counter].spoiler_text + "</b>";
					break;
				}
				i.getElementsByClassName("PostContent")[0].innerHTML += MastodonLoadedFeed[CurrentThing + counter].content;
				break;
			// Bsky
			case 1:
				// Begin by having the website we are using get pushed to the expanded view array and clean out the HTML.
				WebsiteAPIType.push("Bluesky");
				i.getElementsByClassName("PostContent")[0].innerHTML = "";
				if (BlueskyLoadedFeed[CurrentThing + counter + 1] == undefined) {
					let TempFeed;
					if (Discover == true) {
						BlueskyLoadedFeed = await BlueskyAPI.GetPublicTimeline(BlueskyLoadedFeed[CurrentThing + counter].post.indexedAt).then((response) => response.feed);
					} else {
						TempFeed = await BlueskyAPI.GetTimeline(BlueskyLoadedFeed[CurrentThing + counter].post.indexedAt).then((response) => response.feed);
					}
					BlueskyLoadedFeed = await BlueskyLoadedFeed.concat(TempFeed);
				}
				// Check for a reblog.
				if (BlueskyLoadedFeed[CurrentThing + counter].hasOwnProperty("reason") && BlueskyLoadedFeed[CurrentThing + counter].reason.$type == "app.bsky.feed.defs#reasonRepost") {
					i.getElementsByClassName("Username")[0].innerHTML = BlueskyLoadedFeed[CurrentThing + counter].post.author.handle + " ( R: " + BlueskyLoadedFeed[CurrentThing + counter].reason.by.handle + " )";
				} else {
					i.getElementsByClassName("Username")[0].innerHTML = BlueskyLoadedFeed[CurrentThing + counter].post.author.handle;
				}
				// check for "already seen" posts, then put it as a seen post.
				BlueskyLoadedFeed = CheckForDups(BlueskyLoadedFeed, BlueskyPostsDup, counter);
				BlueskyPostsDup.push(BlueskyLoadedFeed[counter].post.uri);
				// Check for an image.
				if (BlueskyLoadedFeed[CurrentThing + counter].post.record.hasOwnProperty("embed")) {
					if (BlueskyLoadedFeed[CurrentThing + counter].post.record.embed.$type == "app.bsky.embed.images") {
						i.getElementsByClassName("PostContent")[0].innerHTML += "This post has an image!<br/>";
					} else if (BlueskyLoadedFeed[CurrentThing + counter].post.record.embed.$type == "app.bsky.embed.video") {
						i.getElementsByClassName("PostContent")[0].innerHTML += "This post has a video!<br/>";
					} else if (BlueskyLoadedFeed[CurrentThing + counter].post.record.embed.$type == "app.bsky.embed.record") {
						i.getElementsByClassName("PostContent")[0].innerHTML += "This post has an embeded record!<br/>";
					} else if (BlueskyLoadedFeed[CurrentThing + counter].post.record.embed.$type == "app.bsky.embed.recordWithMedia") {
						i.getElementsByClassName("PostContent")[0].innerHTML += "This post has an image and an embeded record!<br/>";
					}
				}
				// Check for a thread.
				if (BlueskyLoadedFeed[CurrentThing + counter].hasOwnProperty("reply")) {
					i.getElementsByClassName("PostContent")[0].innerHTML += "This post is a thread!<br/>";
				}
				// Labels
				if (BlueskyLoadedFeed[CurrentThing + counter].post.labels.length != 0) {
					i.getElementsByClassName("PostContent")[0].innerHTML += "<b>LABELS APPLIED: ";
					for (let lab of BlueskyLoadedFeed[CurrentThing + counter].post.labels) {
						i.getElementsByClassName("PostContent")[0].innerHTML += lab.val + " ";
					}
					i.getElementsByClassName("PostContent")[0].innerHTML += "</b>";
					break;
				}
				// Apply correct facets.
				let TempText = await BlueskyAPI.ApplyFacets(BlueskyLoadedFeed[CurrentThing + counter].post.record, BlueskyLoadedFeed[CurrentThing + counter].post.record.text);
				TempText = TempText.replace(/\r?\n|\r/g, "<br/>");
				i.getElementsByClassName("PostContent")[0].innerHTML += TempText;
				break;
			case 2:
				WebsiteAPIType.push("Nothing");
				console.log("The number you are trying to reach is unavailable. Try signing in dumbass.");
				break;
		}
		counter = counter + 1;
		if (counter >= Lim) {
			counter = 0;
			countergroup = countergroup + 1;
		}
	}
}

// Assistant function to help with checking for duplicates.
function CheckForDups(Timeline, DupeArray, counter) {
	for (let j of DupeArray) {
		if (j == Timeline[counter].post.uri) {
			Timeline.splice(counter, 1);
			console.log("Culled a duplicate post.");
			Timeline = CheckForDups(Timeline, DupeArray, counter);
		}
	}
	return Timeline;
}

// Open the settings.
SettingButton.onclick = (event) => {
	window.location.href = "/setting";
}

// Open the notifs, private message, favorites, ... anything mail related!
MailButton.onclick = (event) => {
	window.location.href = "/mail";
}

// A quick way of opening the account.
// In theory, this should be in another "channel" or the mail area, but those areas are crowded.
TimeAccountButton.onclick = (event) => {
	window.location.href = "/account";
}

// Open the posting area.
PostingButton.onclick = (event) => {
	window.location.href = "/post";
}

// Change the feed to a "public" feed.
FeedButton.onclick = (event) => {
	if (Discover == false) {
		let Footer = document.getElementsByClassName("MainFooter")[0];
		Main.classList.add("MainBlacked");
		Main.classList.remove("MainAfter");
		Footer.classList.add("MainBlackedFooter");
		Footer.classList.remove("MainFooter");
	} else {
		let Footer = document.getElementsByClassName("MainBlackedFooter")[0];
		Main.classList.add("MainAfter");
		Main.classList.remove("MainBlacked");
		Footer.classList.add("MainFooter");
		Footer.classList.remove("MainBlackedFooter");
	}
	Discover = !(Discover);
	MastodonLoadedFeed = [];
	BlueskyLoadedFeed = [];
	CurrentThing = 0;
	PosterContainerUpdate();
}
