import * as Variables from "./Variables.js";

export const Scopes = "read write follow push";

// Gets the public timeline.
export async function GetPublicTimeline(Local = false, Remote = false, Website) {
	// Variables can be found in `setting.js`
	let Timeline;
	if (Local == true && Remote == true) {
		console.error("Don't set both Local and Remote timelines to true.");
		return Timeline;
	}
	
	if (Local == true) {
		Timeline = await fetch(Website + "/api/v1/timelines/public?local=true")
		.then((response) => response.json());
	} else if (Remote == true) {
		Timeline = await fetch(Website + "/api/v1/timelines/public?remote=true")
		.then((response) => response.json());
	} else {
		Timeline = await fetch(Website + "/api/v1/timelines/public")
		.then((response) => response.json());
	}
	return Timeline;
}

// Get the personal timeline.
export async function GetTimeline(Cursor) {
	if (localStorage.getItem(Variables.MastodonAccessToken) == null) {
		console.log("No access token!");
		return "";
	}
	let Website = localStorage.getItem(Variables.MastodonWebsite);
	// Get the varaibles that are stored in localStorage.
	if (Cursor == "") {
		return await fetch(Website + "/api/v1/timelines/home", {method: "GET", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}})
		.then((response) => response.json());
	} else {
		return await fetch(Website + "/api/v1/timelines/home?max_id=" + Cursor, {method: "GET", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}})
		.then((response) => response.json());
	}
}

// Gets the favorites of a user that you have access to.
export async function GetFavorites() {
	if (localStorage.getItem(Variables.MastodonAccessToken) == null) {
		console.log("No access token!");
		return "";
	}
	let Website = localStorage.getItem(Variables.MastodonWebsite);
	// Get the varaibles that are stored in localStorage.
	return await fetch(Website + "/api/v1/favourites", {method: "GET", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}})
	.then((response) => response.json());
}

// Gets the bookmarks of a user that you have access to.
export async function GetBookmarks() {
	if (localStorage.getItem(Variables.MastodonAccessToken) == null) {
		console.log("No access token!");
		return "";
	}
	let Website = localStorage.getItem(Variables.MastodonWebsite);
	// Get the varaibles that are stored in Variables.
	return await fetch(Website + "/api/v1/bookmarks", {method: "GET", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}})
	.then((response) => response.json());
}

// Gets the notifications of a user that you have access to.
export async function GetNotifications() {
	if (localStorage.getItem(Variables.MastodonAccessToken) == null) {
		console.log("No access token!");
		return "";
	}
	let Website = localStorage.getItem(Variables.MastodonWebsite);
	// Get the varaibles that are stored in Variables and then input it.
	return await fetch(Website + "/api/v1/notifications", {method: "GET", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}})
	.then((response) => response.json());
}

// Make a status
export async function CreateStatus(Text, Visibility = "public") {
	if (localStorage.getItem(Variables.MastodonAccessToken) == null) {
		console.log("No access token!");
		return "";
	}
	// Stolen from StackOverflow
	Text = Text.replace(/(?:\r|\n|\r\n)/g, '<br>');
	// Check for a token
	let Website = localStorage.getItem(Variables.MastodonWebsite);
	let request = fetch(Website + "/api/v1/statuses?status=" + Text + "&visibility=" + Visibility, {method: "POST", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}});
	let body = await request.then((response) => response.json());
	let status = await request.then((response) => response.status);
	// This is in case you went over the characters.
	if (status == 422) {
		let matches = body.error.match(/(\d+)/);
		console.log(matches);
		request = fetch(Website + "/api/v1/statuses?status=" + Text.slice(0, matches[0] - 1) + "&visibility=" + Visibility, {method: "POST", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}});
		body = await request.then((response) => response.json());
		await CreateReplyStatus(Text.slice(matches[0] - 1, Text.length - 1), Visibility, body.id);
	}
	return body;
}

export async function CreateReplyStatus(Text, Visibility = "public", ReplyID) {
	if (localStorage.getItem(Variables.MastodonAccessToken) == null) {
		console.log("No access token!");
		return "";
	}
	// Stolen from StackOverflow
	Text = Text.replace(/(?:\r|\n|\r\n)/g, '<br>');
	// Check for a token
	let Website = localStorage.getItem(Variables.MastodonWebsite);
	let request = fetch(Website + "/api/v1/statuses?status=" + Text + "&visibility=" + Visibility + "&in_reply_to_id=" + ReplyID, {method: "POST", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}});
	let body = await request.then((response) => response.json());
	let status = await request.then((response) => response.status);
	// This is in case you went over the characters.
	if (status == 422) {
		let matches = body.error.match(/(\d+)/);
		request = fetch(Website + "/api/v1/statuses?status=" + Text.slice(0, matches[0] - 1) + "&visibility=" + Visibility + "&in_reply_to_id=" + ReplyID, {method: "POST", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}});
		body = await request.then((response) => response.json());
		await CreateReplyStatus(Text.slice(matches[0] - 1, Text.length - 1), Visibility, body.id);
	}
	return body;
}

// The first step to using the app.
export async function HandleAuthentication(Website) {
	// See if the user is smart enough to put https.
	let InstanceData = "";
	// Quickly check to see if it has something before :// so it doesn't screw the link.
	if (Website.toLowerCase().split("://").length > 1) {
		Website = "https://" + Website.split("://")[1];
	} else {
		Website = "https://" + Website;
	}
	// Save the website
	localStorage.setItem(Variables.MastodonWebsite, Website);
	// Registering the app.
	InstanceData = await fetch(Website + "/api/v1/apps?client_name=Channel Viewer&redirect_uris=" + document.location.href + "&scopes=" + Scopes, {method: "POST"})
	.then((response) => response.json());
	// Save the client stuff as Variables.
	localStorage.setItem(Variables.MastodonClientID, InstanceData.client_id);
	localStorage.setItem(Variables.MastodonClientSecret, InstanceData.client_secret);
	// Now authenticate the app.
	document.location.href = Website + "/oauth/authorize?client_id=" + InstanceData.client_id + "&redirect_uri=" + document.location.href + "&response_type=code&scope=" + Scopes;
}

// This specific functino goes after HandleAuthentication for when login happens.
export async function GainToken() {
	// check if you both have a code and have a current authentication.
	if (document.location.href.split("code=").length > 1 && localStorage.getItem(Variables.MastodonClientID) != null && localStorage.getItem(Variables.MastodonAccessToken) == null) {
		// Get some vars.
		let code = document.location.href.split("code=")[1];
		let Website = localStorage.getItem(Variables.MastodonWebsite);
		// Authenticate.
		let AuthenticationToken = await fetch(Website + "/oauth/token?client_id=" + localStorage.getItem(Variables.MastodonClientID) + "&client_secret=" + localStorage.getItem(Variables.MastodonClientSecret) + "&redirect_uri=" + document.location.href + "&grant_type=authorization_code&code=" + code, {method: "POST"})
		.then((response) => response.json());
		// Cookify These.
		localStorage.setItem(Variables.MastodonAccessToken, AuthenticationToken.access_token);
		localStorage.setItem(Variables.MastodonTokenType, AuthenticationToken.token_type);
	}
}