constructor(filename, options) {
		const { addFile, getFile } = editorManager;
		let doesExists = null;

		this.hideQuickTools = options?.hideQuickTools || false;

		// if options are passed
		if (options) {
			// if options doesn't contains id, and provide a new id
			if (!options.id) {
				if (options.uri) this.#id = options.uri.hashCode();
				else this.#id = helpers.uuid();
			} else this.#id = options.id;
		} else if (!options) {
			// if options aren't passed, that means default file is being created
			this.#id = constants.DEFAULT_FILE_SESSION;
		}

		if (options?.type) {
			this.#type = options.type;
			if (this.#type !== "editor") {
				const container = tag("div", {
					className: "tab-page-container",
				});

				// shadow dom
				const shadow = container.attachShadow({ mode: "open" });

				// main app styles
				const mainStyle = tag("link", {
					rel: "stylesheet",
					href: "./css/build/main.css",
				});
				// icon styles
				const iconStyle = tag("link", {
					rel: "stylesheet",
					href: "./res/icons/style.css",
				});
				// file icon styles
				const fileIconStyle = tag("link", {
					rel: "stylesheet",
					href: "./res/file-icons/style.css",
				});

				// Add base styles to shadow DOM first
				shadow.appendChild(mainStyle);
				shadow.appendChild(iconStyle);
				shadow.appendChild(fileIconStyle);

				// Handle custom stylesheets if provided
				if (options.stylesheets) {
					this.#addCustomStyles(options.stylesheets, shadow);
				}

				const content = tag("div", {
					className: "tab-page-content",
				});

				if (typeof options.content === "string") {
					content.innerHTML = DOMPurify.sanitize(options.content);
				} else {
					content.appendChild(options.content);
				}

				// Append content container to shadow DOM
				shadow.appendChild(content);

				this.#content = container;
			} else {
				this.#content = options.content;
			}
			if (options.tabIcon) {
				this.#tabIcon = options.tabIcon;
			}
		}

		this.#uri = options?.uri;

		if (this.#id) doesExists = getFile(this.#id, "id");
		else if (this.#uri) doesExists = getFile(this.#uri, "uri");

		if (doesExists) {
			doesExists.makeActive();
			return;
		}

		if (filename) this.#name = filename;

		this.#tab = tile({
			text: this.#name,
			...(this.#type !== "editor" && {
				lead: (
					<span className={this.icon} style={{ paddingRight: "5px" }}></span>
				),
			}),
			tail: tag("span", {
				className: "icon cancel",
				dataset: {
					action: "close-file",
				},
			}),
		});

		const editable = options?.editable ?? true;

		this.#SAFMode = options?.SAFMode;
		this.isUnsaved = options?.isUnsaved ?? false;

		if (options?.encoding) {
			this.encoding = options.encoding;
		}

		// if options contains text property then there is no need to load
		// set loaded true

		if (this.#id !== constants.DEFAULT_FILE_SESSION) {
			this.loaded = options?.text !== undefined;
		}

		// if not loaded then create load options
		if (!this.loaded) {
			this.#loadOptions = {
				cursorPos: options?.cursorPos,
				scrollLeft: options?.scrollLeft,
				scrollTop: options?.scrollTop,
				folds: options?.folds,
				editable,
			};
		} else {
			this.editable = editable;
		}

		this.#onFilePosChange = () => {
			const { openFileListPos } = appSettings.value;
			if (
				openFileListPos === appSettings.OPEN_FILE_LIST_POS_HEADER ||
				openFileListPos === appSettings.OPEN_FILE_LIST_POS_BOTTOM
			) {
				this.#tab.oncontextmenu = startDrag;
			} else {
				this.#tab.oncontextmenu = null;
			}
		};

		this.#onFilePosChange();
		this.#tab.addEventListener("click", tabOnclick.bind(this));
		appSettings.on("update:openFileListPos", this.#onFilePosChange);

		addFile(this);
		editorManager.emit("new-file", this);

		if (this.#type === "editor") {
			this.session = ace.createEditSession(options?.text || "");
			this.setMode();
			this.#setupSession();
		}

		if (options?.render ?? true) this.render();
	}
@param {string} [filename] name of file.
@param {FileOptions} [options]  file create options