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

export const Scopes = "read write follow push";

let TokenType = localStorage.getItem(Variables.MastodonTokenType);
let Token = localStorage.getItem(Variables.MastodonAccessToken);
if (Token == null || TokenType == null) {
	console.error("No Mastodon access token!");
}

// Getters
// Gets the public timeline.
export async function GetPublicTimeline(Local = false, Remote = false, Website, Cursor) {
	// Variables can be found in `setting.js`
	let Timeline;
	if (Cursor == "") {
		if (Remote == true && Local == false) {
			Timeline = fetch(Website + "/api/v1/timelines/public?remote=true");
		} else if (Local == true && Remote == false) {
			Timeline = fetch(Website + "/api/v1/timelines/public?local=true");
		} else {
			Timeline = fetch(Website + "/api/v1/timelines/public");
		}
	} else {
		if (Remote == true && Local == false) {
			Timeline = fetch(Website + "/api/v1/timelines/public?remote=true&max_id=" + Cursor);
		} else if (Local == true && Remote == false) {
			Timeline = fetch(Website + "/api/v1/timelines/public?local=true&max_id=" + Cursor);
		} else {
			Timeline = fetch(Website + "/api/v1/timelines/public?max_id=" + Cursor);
		}
	}
	let request = await Timeline.then((response) => response.json());
	return request;
}

// Get the personal timeline.
export async function GetTimeline(Cursor = "") {
	if (Token == null || TokenType == null) {
		return "";
	}
	// If there is a timestamp, GET with the timestamp.
	let request = localStorage.getItem(Variables.MastodonWebsite) + "/api/v1/timelines/home";
	if (Cursor != "") {
		request += "?max_id=" + Cursor;
	}
	return await fetch(request, {method: "GET", headers: {"Authorization": TokenType + " " + Token}})
	.then((response) => response.json());
}

// Get the relationship. The token houses the person you are getting a relationship for.
export async function GetRelationship(ID) {
	if (Token == null || TokenType == null) {
		return "";
	}
	return await fetch(localStorage.getItem(Variables.MastodonWebsite) + "/api/v1/accounts/relationships?id[]=" + ID, {method: "GET", headers: {"Authorization": TokenType + " " + Token}})
	.then((response) => response.json());
}

// Gets the notifications of a user that you have access to.
export async function GetNotifications() {
	if (Token == null || TokenType == null) {
		return "";
	}
	return await fetch(localStorage.getItem(Variables.MastodonWebsite) + "/api/v1/notifications", {method: "GET", headers: {"Authorization": TokenType + " " + Token}})
	.then((response) => response.json());
}

// A status is just a post. It gets it.
export async function GetStatus(ID) {
	if (Token == null || TokenType == null) {
		return "";
	}
	return await fetch(localStorage.getItem(Variables.MastodonWebsite) + "/api/v1/statuses/" + ID, {method: "GET", headers: {"Authorization": TokenType + " " + Token}})
	.then((response) => response.json());
}

export async function GetContexts(ID) {
	if (Token == null || TokenType == null) {
		return "";
	}
	return await fetch(localStorage.getItem(Variables.MastodonWebsite) + "/api/v1/statuses/" + ID + "/context", {method: "GET", headers: {"Authorization": TokenType + " " + Token}})
	.then((response) => response.json());
}

// Get your own account by verifying your credentials.
export async function GetOwnAccount() {
	if (Token == null || TokenType == null) {
		return "";
	}
	return await fetch(localStorage.getItem(Variables.MastodonWebsite) + "/api/v1/accounts/verify_credentials", {method: "GET", headers: {"Authorization": TokenType + " " + Token}})
	.then((response) => response.json());
}

// Get your own account blocks.
export async function GetAccountFollows(ID) {
	if (Token == null || TokenType == null) {
		return "";
	}
	return await fetch(localStorage.getItem(Variables.MastodonWebsite) + "/api/v1/accounts/" + ID + "/following", {method: "GET", headers: {"Authorization": TokenType + " " + Token}})
	.then((response) => response.json());
}

// Get another account's statuses.
export async function GetAccountStatuses(ID) {
	if (Token == null || TokenType == null) {
		return "";
	}
	return await fetch(localStorage.getItem(Variables.MastodonWebsite) + "/api/v1/accounts/" + ID + "/statuses", {method: "GET", headers: {"Authorization": TokenType + " " + Token}})
	.then((response) => response.json());
}

// Get another account.
export async function GetAccount(ID) {
	if (Token == null || TokenType == null) {
		return "";
	}
	return await fetch(localStorage.getItem(Variables.MastodonWebsite) + "/api/v1/accounts/" + ID, {method: "GET", headers: {"Authorization": TokenType + " " + Token}})
	.then((response) => response.json());
}

// Creators
// Make a status
export async function CreateStatus(Text, Visibility = "public", SpoilerText = undefined, ReplyID = undefined) {
	if (Token == null || TokenType == null) {
		return "";
	}
	// Stolen from StackOverflow.
	Text = Text.replace(/(?:\r|\n|\r\n)/g, '<br>');
	// Get the correct fetch body.
	let FetchThing = localStorage.getItem(Variables.MastodonWebsite) + "/api/v1/statuses?status=" + encodeURIComponent(Text) + "&visibility=" + Visibility;
	// Content warning stuff.
	if (SpoilerText != undefined) {
		FetchThing += "&spoiler_text=" + SpoilerText;
	}
	if (ReplyID != undefined) {
		FetchThing += "&in_reply_to_id=" + ReplyID;
	}
	// Send the request.
	let request = fetch(FetchThing, {method: "POST", headers: {"Authorization": TokenType + " " + Token}});
	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+)/);
		// Get the correct fetch body.
		FetchThing = localStorage.getItem(Variables.MastodonWebsite) + "/api/v1/statuses?status=" + encodeURIComponent(Text.slice(0, matches[0] - 1)) + "&visibility=" + Visibility
		if (SpoilerText != undefined) {
			FetchThing += "&spoiler_text=" + SpoilerText;
		}
		// Send the request.
		request = fetch(enFetchThing, {method: "POST", headers: {"Authorization": TokenType + " " + Token}});
		body = await request.then((response) => response.json());
		if (ReplyID != undefined) {
			await CreateReplyStatus(Text.slice(matches[0] - 1, Text.length), Visibility, SpoilerText, body.id);
		}
	}
	return body;
}

export async function CreateFavorite(ID, IsFavorited) {
	if (Token == null || TokenType == null) {
		return "";
	}
	let request = localStorage.getItem(Variables.MastodonWebsite) + "/api/v1/statuses/" + ID;
	if (IsFavorited == false) {
		request += "/favourite";
	} else {
		request += "/unfavourite";
	}
	return await fetch(request, {method: "POST", headers: {"Authorization": TokenType + " " + Token}})
	.then((response) => response.json());
}

export async function CreateReblog(ID, IsReblogged) {
	if (Token == null || TokenType == null) {
		return "";
	}
	let request = localStorage.getItem(Variables.MastodonWebsite) + "/api/v1/statuses/" + ID;
	if (IsReblogged == false) {
		request += "/reblog";
	} else {
		request += "/unreblog";
	}
	return await fetch(request, {method: "POST", headers: {"Authorization": TokenType + " " + Token}})
	.then((response) => response.json());
}

export async function CreateFollow(ID, IsFollowed) {
	if (localStorage.getItem(Variables.MastodonAccessToken) == null) {
		console.log("No access token!");
		return "";
	}
	let request = localStorage.getItem(Variables.MastodonWebsite) + "/api/v1/accounts/" + ID;
	if (IsFollowed == false) {
		request += "/follow";
	} else {
		request += "/unfollow";
	}
	return await fetch(request, {method: "POST", headers: {"Authorization": TokenType + " " + Token}})
	.then((response) => response.json());
}

export async function CreateBlock(ID, IsBlocked) {
	if (Token == null || TokenType == null) {
		return "";
	}
	let request = localStorage.getItem(Variables.MastodonWebsite) + "/api/v1/accounts/" + ID;
	if (IsBlocked == false) {
		request += "/block";
	} else {
		request += "/unblock";
	}
	return await fetch(request, {method: "POST", headers: {"Authorization": TokenType + " " + Token}})
	.then((response) => response.json());
}

// Things to make this work
// 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);
	}
}
