import {
	AlarmOffOutlined,
	BurstModeOutlined,
	CameraEnhanceOutlined,
	ContentCopy,
	LayersOutlined,
	PeopleOutline,
} from "@mui/icons-material";
import { Typography } from "@mui/material";
import { HttpStatusCode } from "axios";
import { useTranslation } from "react-i18next";
import { useNavigate, useParams } from "react-router-dom";
import { toast } from "react-toastify";
import { z as zod } from "zod";

import { Card, ErrorContext } from "@/common/components/card/Card";
import { CardField } from "@/common/components/card/CardField";
import { Centroid } from "@/common/components/Centroid";
import { Loader } from "@/common/components/Loader";
import { CardAction } from "@/common/models/card-action";
import { MAX_NAME_LENGTH, MAX_TEXT_LENGTH } from "@/constants";
import { useGetAssetGroupList } from "@/contracts/assets-groups";
import { AssetModel } from "@/contracts/client.schemas";
import { KeyValue } from "@/models/KeyValue";

const createNameValidator = (name: string) => {
	return zod
		.string({
			invalid_type_error: `${name} must be a string`,
		})
		.max(
			MAX_NAME_LENGTH,
			`${name} must be less than ${MAX_NAME_LENGTH} characters`,
		);
};

const validationSchema = zod.object({
	name: zod
		.string({
			required_error: "Name is required",
			invalid_type_error: "Name must be a string",
		})
		.min(3, "Name must be at least 3 characters")
		.max(
			MAX_NAME_LENGTH,
			`Name must be less than ${MAX_NAME_LENGTH} characters`,
		),

	groupIds: zod
		.array(
			zod.string({
				invalid_type_error: "Group ID must be a string",
			}),
		)
		.optional(),

	description: zod
		.string({
			required_error: "Description is required",
			invalid_type_error: "Description must be a string",
		})
		.min(3, "Description must be at least 3 characters")
		.max(
			MAX_TEXT_LENGTH,
			`Description must be less than ${MAX_TEXT_LENGTH} characters`,
		),

	comment: zod
		.string({
			invalid_type_error: "Comment must be a string",
		})
		.max(
			MAX_TEXT_LENGTH,
			`Comment must be less than ${MAX_TEXT_LENGTH} characters`,
		)
		.optional()
		.or(zod.literal("")),

	latitude: zod.preprocess(
		(val) => (val === "" ? null : val), // empty string -> null
		zod
			.number()
			.min(-90, "Latitude must be between -90 and 90")
			.max(90, "Latitude must be between -90 and 90")
			.nullable(),
	),
	longitude: zod.preprocess(
		(val) => (val === "" ? null : val),
		zod
			.number()
			.min(-180, "Longitude must be between -180 and 180")
			.max(180, "Longitude must be between -180 and 180")
			.nullable(),
	),

	// address
	apartment: createNameValidator("Apartment"),
	building: createNameValidator("building"),
	city: createNameValidator("city"),
	country: createNameValidator("country"),
	gateCode: createNameValidator("gateCode"),
	house: createNameValidator("house"),
	intercomCode: createNameValidator("intercomCode"),
	ownerName: createNameValidator("ownerName"),
	ownerPassword: createNameValidator("ownerPassword"),
	ownerPhone1: createNameValidator("ownerPhone1"),
	ownerPhone2: createNameValidator("ownerPhone2"),
	region: createNameValidator("region"),
	street: createNameValidator("street"),
	identificationPassword: createNameValidator("identificationPassword"),
	duressPassword: createNameValidator("duressPassword"),
	imei: zod
		.string()
		.regex(/^\d{15,16}$/, "IMEI должен содержать 15-16 цифр")
		.optional()
		.or(zod.literal("")),
});

export const AssetCardPage = () => {
	const { organizationId } = useParams();
	const navigate = useNavigate();
	const { t } = useTranslation();
	const {
		data: groupTable,
		isLoading,
		isError,
	} = useGetAssetGroupList({
		OrganizationId: organizationId,
	});

	if (!organizationId) {
		throw new Error("organizationId is required");
	}

	if (isLoading) {
		return (
			<Centroid>
				<Loader />
			</Centroid>
		);
	}

	if (isError || !groupTable) {
		toast.error("Failed to loading of asset groups");
		return null;
	}

	const groupOptions = groupTable.items.map(
		(x) =>
			({
				key: x.id,
				value: x.name,
			}) as KeyValue<string, string>,
	);

	const fields: CardField<AssetModel>[] = [
		{
			name: "name",
			title: "Name",
			required: true,
			group: "General",
		},
		{
			name: "description",
			title: "Description",
			type: "multiline",
			required: true,
			group: "General",
		},
		{
			name: "comment",
			title: "Comment",
			type: "multiline",
			required: false,
		},
		{
			name: "groupIds",
			title: "Groups",
			nullable: true,
			type: "multiselect",
			options: groupOptions,
		},
		{
			name: "latitude",
			title: "Latitude",
			nullable: true,
			type: "number",
			required: true,
			group: "Address",
		},
		{
			name: "longitude",
			title: "Longitude",
			nullable: true,
			type: "number",
			required: true,
			group: "Address",
		},
		{
			name: "imei",
			title: "IMEI",
			nullable: true,
			group: "General",
		},
		{
			name: "groupIds",
			title: "Groups",
			nullable: true,
			type: "multiselect",
			options: groupOptions,
			group: "General",
		},
		{
			name: "apartment",
			title: "apartment",
			group: "Address",
		},
		{
			name: "building",
			title: "building",
			group: "Address",
		},
		{
			name: "city",
			title: "city",
			group: "Address",
		},
		{
			name: "country",
			title: "country",
			group: "Address",
		},
		{
			name: "gateCode",
			title: "gateCode",
			group: "Address",
		},
		{
			name: "house",
			title: "house",
			group: "Address",
		},
		{
			name: "intercomCode",
			title: "intercomCode",
			group: "Address",
		},
		{
			name: "ownerName",
			title: "ownerName",
			group: "General",
		},
		{
			name: "ownerPassword",
			title: "ownerPassword",
			group: "General",
		},
		{
			name: "ownerPhone1",
			title: "ownerPhone1",
			group: "General",
		},
		{
			name: "ownerPhone2",
			title: "ownerPhone2",
			group: "General",
		},
		{
			name: "region",
			title: "region",
			group: "Address",
		},
		{
			name: "street",
			title: "street",
			group: "Address",
		},
		{
			name: "identificationPassword",
			title: "identificationPassword",
			group: "General",
		},
		{
			name: "duressPassword",
			title: "duressPassword",
			group: "General",
		},
	];

	const defaultValue: AssetModel = {
		id: "",
		organizationId,
		name: "",
		description: "",
		comment: "",
		groupIds: [],
		// address
		apartment: "",
		building: "",
		city: "",
		country: "",
		gateCode: "",
		house: "",
		intercomCode: "",
		ownerName: "",
		ownerPassword: "",
		ownerPhone1: "",
		ownerPhone2: "",
		region: "",
		street: "",
		identificationPassword: "",
		duressPassword: "",
		isOnline: false,
		imei: "",
		latitude: null,
		longitude: null,
		lastStatusChange: null,
		rowVersion: "",
		serviceOrganizationId: null,
		serviceOrganizationName: null,
	};

	const extraTitle = (model: AssetModel) => {
		return <Typography>{model.name}</Typography>;
	};

	const handleError = (error: ErrorContext) => {
		if (error.status === HttpStatusCode.Conflict) {
			toast.error("The same token is already in the system");
			return true;
		}

		return false;
	};
	//
	// const transformDataForApi = (model: AssetModel) => {
	// 	return {
	// 		...model,
	// 		country: model.country || "",
	// 		region: model.region || "",
	// 		city: model.city || "",
	// 		street: model.street || "",
	// 		house: model.house || "",
	// 		building: model.building || "",
	// 		apartment: model.apartment || "",
	// 		gateCode: model.gateCode || "",
	// 		intercomCode: model.intercomCode || "",
	// 		ownerName: model.ownerName || "",
	// 		ownerPassword: model.ownerPassword || "",
	// 		ownerPhone1: model.ownerPhone1 || "",
	// 		ownerPhone2: model.ownerPhone2 || "",
	// 		identificationPassword: model.identificationPassword || "",
	// 		duressPassword: model.duressPassword || "",
	// 		comment: model.comment || "",
	// 	};
	// };

	const extraActions: CardAction<AssetModel>[] = [
		{
			icon: <ContentCopy />,
			title: "Copy Identifier",
			action: async (model) => {
				navigator.clipboard.writeText(model.id);
				toast.success(t("Identifier copied to clipboard"));

				return model;
			},
		},
		{
			icon: <PeopleOutline />,
			title: "Responsible",
			action: async (model) => {
				navigate("./responsible-persons", { relative: "path" });

				return model;
			},
		},
		{
			icon: <BurstModeOutlined />,
			title: "Photos",
			action: async (model) => {
				navigate("./photos", { relative: "path" });

				return model;
			},
		},
		{
			icon: <LayersOutlined />,
			title: "Areas",
			action: async (model) => {
				navigate("./areas", { relative: "path" });

				return model;
			},
		},
		{
			icon: <AlarmOffOutlined />,
			title: "Locked Event Codes",
			action: async (model) => {
				navigate("./locked-event-codes", { relative: "path" });

				return model;
			},
			color: "error",
		},
		{
			icon: <CameraEnhanceOutlined />,
			title: "Cameras",
			action: async (model) => {
				navigate("./cameras", { relative: "path" });

				return model;
			},
		},
	];

	return (
		<Card
			defaultValue={defaultValue}
			fields={fields}
			baseUrl="/api/assets"
			createTitle="Добавление объекта"
			editTitle="Редактирование объекта"
			viewTitle="Карточка объекта"
			validationSchema={validationSchema}
			extraTitle={extraTitle}
			onError={handleError}
			// onSubmit={transformDataForApi}
			filters={{
				organizationId,
			}}
			extraActions={extraActions}
			getModelTitle={(model) => model.name}
			notificationMethodPrefix="ASSETS"
			canEdit={true}
			canRemove={true}
		/>
	);
};
