/* eslint-disable @typescript-eslint/no-explicit-any */
import { Breadcrumbs, Link, Typography } from "@mui/material";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { Link as RouterLink, useLocation } from "react-router-dom";

import {
	AccessModel,
	AreaModel,
	AssetGroupModel,
	AssetModel,
	MemberModel,
	OrganizationModel,
	UserModel,
	ZoneModel,
} from "@/contracts/client.schemas";

import { Token } from "../models/Token";
import { http } from "../services/http.service";

// async function getModel(type, id) {
// 	const result = await http.get(`/api/${type}/${id}`);
// 	return result.data;
// }

// const getName = {
// 	"tokens": {
// 		getter: (id) => getModel("tokens", id),
// 		property: x => x.name,
// 	},
// }

function LinkRouter(props: any) {
	return <Link {...props} component={RouterLink} />;
}

export const LocatedBreadcrumbs = () => {
	const location = useLocation();
	const [items, setItems] = useState<any[]>([]);
	const { t } = useTranslation();

	const breadcrumbNameMap = {
		"": "Home",
		organizations: "Organizations",
		tokens: "Tokens",
		users: "Users",
		objects: "Objects",
		reports: "Reports",
		new: "New",
		assets: "Assets",
		"asset-groups": "Asset Groups",
		"responsible-persons": "Responsible",
		photos: "Photos",
		zones: "Zones",
		areas: "Areas",
		members: "Members",
		accesses: "Accesses",
	};

	useEffect(() => {
		const getNames = async () => {
			try {
				const locationPathname = location.pathname;
				if (locationPathname === "/") {
					setItems([
						{
							path: "/",
							title: breadcrumbNameMap[""],
						},
					]);
					return;
				}

				const pathnames = locationPathname.split("/");
				const items = [];

				for (let i = 0; i < pathnames.length; i++) {
					const pathname = pathnames[i];

					let name = (breadcrumbNameMap as any)[pathname];
					let path = pathnames.slice(0, i + 1).join("/");
					if (path === "") {
						path = "/";
					}

					if (name === undefined) {
						name = await getName(pathname, i, pathnames);
					}

					items.push({
						title: name,
						path,
					});
				}

				setItems(items);
			} catch (e) {
				console.error(e);
			}
		};
		getNames();
	}, [location]);

	const getName = async (id: string, index: number, pathnames: string[]) => {
		if (index > 0) {
			return getTitle(id, pathnames[index - 1]);
		}

		return id;
	};

	async function fetchEntity<T>(type: string, id: string) {
		return await http.get<T>(`/api/${type}/${id}`);
	}

	const getTitle = async (id: string, type: string) => {
		let entity;
		switch (type) {
			case "organizations":
				entity = await fetchEntity<OrganizationModel>(
					"organizations",
					id,
				);
				return entity.name;
			case "tokens":
				entity = await fetchEntity<Token>("tokens", id);
				return entity.name;
			case "users":
				entity = await fetchEntity<UserModel>("users", id);
				return entity.username;
			case "members":
				entity = await fetchEntity<MemberModel>("members", id);
				return entity.username;
			case "assets":
				entity = await fetchEntity<AssetModel>("assets", id);
				return entity.name;
			case "asset-groups":
				entity = await fetchEntity<AssetGroupModel>("asset-groups", id);
				return entity.name;
			case "areas":
				entity = await fetchEntity<AreaModel>("areas", id);
				return entity.name;
			case "zones":
				entity = await fetchEntity<ZoneModel>("zones", id);
				return entity.name;
			case "accesses":
				entity = await fetchEntity<AccessModel>("accesses", id);
				return entity.assetGroupName;
			default:
				return id;
		}
	};

	return (
		<Breadcrumbs aria-label="breadcrumb">
			{items.map((value, index) => {
				const last = index === items.length - 1;
				const to = value.path;
				const title = t(value.title);

				return last ? (
					<Typography color="text.primary" key={to}>
						{title}
					</Typography>
				) : (
					<LinkRouter
						underline="hover"
						color="inherit"
						to={to}
						key={to}
					>
						{title}
					</LinkRouter>
				);
			})}
		</Breadcrumbs>
	);
};
