import { NewRedirectModal} from "./Modals/NewRedirectModal";
import { EditRedirectForm } from "./Forms/EditRedirectForm";
import { SearchRedirectsForm } from "./Forms/SearchRedirectsForm";
import { Redirect } from "./Components/Redirect";
import { EndpointsProvider } from "../EndpointsProvider";
import { Scheduler } from "../Utils/Scheduler";
import { Paginator } from "../Utils/Paginator";
import { IRedirect } from "../Interfaces/ManageRedirects/IRedirect";
import { NewRedirectForm } from "./Forms/NewRedirectForm";
import { EditRedirectModal } from "./Modals/EditRedirectModal";

export class ManageRedirects{
    private Loader = document.querySelector<HTMLElement>("#redirects-loader");
    private NoResultsMessageContainer = document.querySelector("#no-redirects-message-container") as HTMLElement;
    private IsProcessing: boolean = false;
    private Paginators: Paginator [] = [];
	public NewRedirectModal: NewRedirectModal = new NewRedirectModal(this);
	public NewRedirectForm: NewRedirectForm = new NewRedirectForm(this);
	public SearchRedirectsForm: SearchRedirectsForm = new SearchRedirectsForm(this);
	public EditRedirectForm: EditRedirectForm = new EditRedirectForm(this);
	public EditRedirectModal: EditRedirectModal = new EditRedirectModal();
    public CurrentPage: number = 1;
    public CurrentLimit: number = 25;
    public CurrentQuery: string = "";
	public RedirectsComponentContainer = document.querySelector<HTMLElement>("#redirects-rows-container")

    public constructor(){
        this.Paginators = [];

        for (const paginator of Array.from(document.querySelectorAll<HTMLElement>("pagination"))){
			const newPaginator = new Paginator(paginator);
			this.HookPaginatorEvents(newPaginator);
			this.Paginators.push(newPaginator);
		}

		this.LoadRedirects(
			this.CurrentPage,
			this.CurrentLimit,
			this.CurrentQuery
		);
    }
	/**
	 * Connects the pagination buttons (previous, next, manually entered)
	 * @param paginator 
	 */
    public HookPaginatorEvents(paginator: Paginator){
        paginator.OnPagePrev(pageNumber => {
			this.CurrentPage = pageNumber;
			this.LoadRedirects(
				pageNumber,
				this.CurrentLimit,
				this.CurrentQuery
			)
		});

		paginator.OnPageNext(pageNumber => {
			this.CurrentPage = pageNumber;
			this.LoadRedirects(
				pageNumber,
				this.CurrentLimit,
				this.CurrentQuery
			)
		});

		paginator.OnPageManuallyEntered(pageNumber => {
			this.CurrentPage = pageNumber;
			this.LoadRedirects(
				pageNumber,
				this.CurrentLimit,
				this.CurrentQuery
			)
		});
    }
	/**
	 * Fetches redirect data from the server
	 * @param page 
	 * @param limit 
	 * @param query 
	 * @returns 
	 */
    public async LoadRedirects(
        page: number = undefined,
        limit: number = undefined,
        query: string = undefined,
    ){
        if (this.IsProcessing){
			return;
		}

        this.NoResultsMessageContainer.style.display = "none";
		this.RedirectsComponentContainer.innerHTML = "";

		this.IsProcessing = true;
		this.Loader.style.display = "block";
		this.CurrentPage = page;
		this.CurrentLimit = limit;
		this.CurrentQuery = query;

		const urlParams = new URLSearchParams();
		urlParams.set("limit", String(limit));
		urlParams.set("page", String(page));
		urlParams.set("query", query);

		const response = await fetch(`${EndpointsProvider.EndPoints.Redirects.GetRedirects}?${urlParams.toString()}`, {
		    cache:"no-cache",
		    credentials:"same-origin"
		});

		await Scheduler.Wait(350);

		let data: {status: number, error?: string, redirects: IRedirect[], totalRedirects: number, totalPages: number};
		try{
		    data = await response.json();
		}catch(jsonSyntaxError){
		    alert("The server responded with invalid JSON.");
		    return;
		}

		this.Loader.style.display = "none";

		if (data.status === 1){

			// Set paginator stuff
			for (const paginator of this.Paginators){
				// paginator.setCurrentPage(this.currentPage);
				paginator.SetMaxPages(data.totalPages);
			}

			if (data.redirects.length > 0) {
				for (const redirect of data.redirects) {
					new Redirect(
						this,
						redirect.id,
						redirect.isRegEx,
						redirect.fromURI,
						redirect.to,
						redirect.statusCode,
						redirect.addedTimestamp,
						redirect.preserveQueryString
					);
				}
			}else{
				this.NoResultsMessageContainer.style.display = null;
			}
		}else if (data.status === -1){
			alert(data.error);
		}

		this.IsProcessing = false;
    }
}

new ManageRedirects();