import type { Models } from "@nontara/server/models";

type OnboardStorage =
	| {
			currentStep: 0;
	  }
	| {
			currentStep: 1;
			account: Models.AccountData;
	  }
	| {
			currentStep: 2;
			account: Models.AccountData;
			libraries: Models.LibraryData[];
	  }
	| {
			currentStep: 3;
			account: Models.AccountData;
			libraries: Models.LibraryData[];
			languages: Models.MetadataLanguage;
	  };

export class OnboardSessionService {
	// private account: Models.AccountData | null = null;
	// private libraries: Models.LibraryData[] = [];
	// private languages: Models.MetadataLanguage | null = null;
	private readonly ONBOARD_STORAGE_KEY = "onboard-session";
	private onboardStorage: OnboardStorage = {
		currentStep: 0,
	};
	constructor() {
		try {
			const onboardStorage = sessionStorage.getItem(this.ONBOARD_STORAGE_KEY);
			if (!onboardStorage) return;
			this.onboardStorage = JSON.parse(onboardStorage) as OnboardStorage;
		} catch (error) {
			console.error("Failed to parse onboard session storage. ", error);
		}
	}

	public getAccount() {
		if (this.onboardStorage.currentStep === 1) {
			return this.onboardStorage.account;
		}
	}

	public updateAccount(account: Models.AccountData) {
		this.onboardStorage = {
			currentStep: 1,
			account,
		};
		this.updateStorage();
	}

	public updateLibraries(libraries: Models.LibraryData[]) {
		if (this.onboardStorage.currentStep === 1) {
			this.onboardStorage = {
				currentStep: 2,
				account: this.onboardStorage.account,
				libraries,
			};
		}
		this.updateStorage();
	}

	public getLibraries(): Models.LibraryData[] {
		if (this.onboardStorage.currentStep === 2) {
			return this.onboardStorage.libraries.map((library) => ({ ...library }));
		}
		return [];
	}

	public getLanguage() {
		if (this.onboardStorage.currentStep === 3) {
			return this.onboardStorage.languages ?? ({} as Models.MetadataLanguage);
		}
	}

	public updateLanguage(languages: Models.MetadataLanguage) {
		if (this.onboardStorage.currentStep === 2) {
			this.onboardStorage = {
				currentStep: 3,
				account: this.onboardStorage.account,
				libraries: this.onboardStorage.libraries,
				languages,
			};
		}
		this.updateStorage();
	}

	public dump(): Models.OnboardConfigurationData {
		if (this.onboardStorage.currentStep === 3) {
			return {
				account: this.onboardStorage.account,
				languages: this.onboardStorage.languages,
				libraries: this.onboardStorage.libraries,
			};
		}
		throw new Error(
			"Cannot dump onboard session because steps is not completed.",
		);
	}

	public getCurrentStep() {
		return this.onboardStorage.currentStep;
	}

	private updateStorage() {
		sessionStorage.setItem(
			this.ONBOARD_STORAGE_KEY,
			JSON.stringify(this.onboardStorage),
		);
	}
}
