import { template } from "./config";
import { IServiceConfig, sendRequest, sendInitialRequest } from "./utils";
import { ICategoryGroupParams, IExportDataParams, IGetStructuredDataParams, IOrderCategoryParams } from "@ax/types";
import { AxiosResponse } from "axios";

const SERVICES: { [key: string]: IServiceConfig } = {
	GET_DATA: {
		...template,
		endpoint: "/structured_data",
		method: "GET",
	},
	GET_DATA_CONTENTS: {
		...template,
		endpoint: "/structured_data_contents/",
		method: "GET",
	},
	GET_DATA_CONTENT: {
		...template,
		endpoint: "/structured_data_content/",
		method: "GET",
	},
	CREATE_DATA_CONTENT: {
		...template,
		endpoint: "/structured_data_content",
		method: "POST",
	},
	UPDATE_DATA_CONTENT: {
		...template,
		endpoint: "/structured_data_content/",
		method: "PUT",
	},
	DELETE_DATA_CONTENT: {
		...template,
		endpoint: "/structured_data_content/",
		method: "DELETE",
	},
	GET_DATA_CONTENT_BULK: {
		...template,
		endpoint: "/structured_data_content/bulk/",
		method: "GET",
	},
	DELETE_DATA_CONTENT_BULK: {
		...template,
		endpoint: "/structured_data_content/bulk",
		method: "DELETE",
	},
	RESTORE_DATA_CONTENT: {
		...template,
		endpoint: ["/structured_data_content/", "/restore"],
		method: "PUT",
	},
	RESTORE_DATA_CONTENT_BULK: {
		...template,
		endpoint: "/structured_data_content/restore/bulk",
		method: "PUT",
	},
	GET_DISTRIBUTOR_CONTENT: {
		...template,
		endpoint: ["/site/", "/distributor"],
		method: "POST",
	},
	GET_DATA_TITLES: {
		...template,
		endpoint: "/structured_data/titles/",
		method: "GET",
	},
	SET_DATA_STATUS: {
		...template,
		endpoint: "/structured_data_content/",
		method: "PUT",
	},
	SET_DATA_STATUS_BULK: {
		...template,
		endpoint: ["/structured_data_content/", "/bulk"],
		method: "PUT",
	},
	GET_CONTENT_TYPES: {
		...template,
		endpoint: ["/site/", "/structured_data"],
		method: "GET",
	},
	CONTENT_AI_TRANSLATION: {
		...template,
		endpoint: "/translations/structured_data_content/",
		method: "POST",
	},
	CREATE_GROUP: {
		...template,
		endpoint: "/categories/group",
		method: "POST",
	},
	GET_GROUP: {
		...template,
		endpoint: "/categories/group/",
		method: "GET",
	},
	EDIT_GROUP: {
		...template,
		endpoint: "/categories/group/",
		method: "PUT",
	},
	DELETE_GROUP: {
		...template,
		endpoint: ["/categories/", "/site/", "/group/"],
		method: "DELETE",
	},
	DELETE_GROUP_BULK: {
		...template,
		endpoint: ["/categories/", "/site/", "/group/bulk"],
		method: "DELETE",
	},
	ORDER_CATEGORY: {
		...template,
		endpoint: "/categories/order/",
		method: "PUT",
	},
	EXPORT_DATA_CONTENT: {
		...template,
		endpoint: ["/structured_data_content/", "/site/", "/export"],
		method: "POST",
		responseType: "blob",
	},
	GET_AI_SEARCH_DATA: {
		...template,
		endpoint: "/ai/search/content-types",
		method: "GET",
	},
};

const getData = (token: string | null, siteID?: number | null): Promise<AxiosResponse> => {
	const { host, endpoint } = SERVICES.GET_DATA;

	if (siteID) {
		SERVICES.GET_DATA.dynamicUrl = `${host}/site/${siteID}${endpoint}`;
	} else {
		SERVICES.GET_DATA.dynamicUrl = "";
	}

	if (token) {
		return sendInitialRequest(SERVICES.GET_DATA, token);
	} else {
		return sendRequest(SERVICES.GET_DATA, {});
	}
};

const getDataContent = (dataContentId: number, langID: number | null): Promise<AxiosResponse> => {
	const { host, endpoint } = SERVICES.GET_DATA_CONTENT;

	const config = langID ? { lang: langID } : {};

	SERVICES.GET_DATA_CONTENT.dynamicUrl = `${host}${endpoint}${dataContentId}`;

	return sendRequest(SERVICES.GET_DATA_CONTENT, {}, config);
};

const getDataContents = (params: IGetStructuredDataParams, siteID?: number | null): Promise<AxiosResponse> => {
	const { host, endpoint } = SERVICES.GET_DATA_CONTENTS;
	const {
		dataID,
		page,
		itemsPerPage,
		pagination,
		deleted,
		include_draft,
		query,
		filterQuery,
		relatedFields = false,
		order,
		lang,
		groupingCategories,
	} = params;

	const url = siteID ? `${host}/site/${siteID}${endpoint}` : `${host}${endpoint}`;

	SERVICES.GET_DATA_CONTENTS.dynamicUrl = `${url}${dataID}?page=${page}&itemsPerPage=${itemsPerPage}&pagination=${pagination}&deleted=${deleted}&includeDraft=${include_draft}`;
	if (groupingCategories) SERVICES.GET_DATA_CONTENTS.dynamicUrl += `&groupingCategories=on`;
	if (relatedFields) SERVICES.GET_DATA_CONTENTS.dynamicUrl += `&relatedFields=true`;
	if (query && query.trim() !== "") SERVICES.GET_DATA_CONTENTS.dynamicUrl += `&query=${query}`;
	if (order) SERVICES.GET_DATA_CONTENTS.dynamicUrl += `&order=${order}`;
	if (filterQuery) SERVICES.GET_DATA_CONTENTS.dynamicUrl += filterQuery;

	const dataHeader = {
		...(lang && { lang }),
	};

	return sendRequest(SERVICES.GET_DATA_CONTENTS, null, dataHeader);
};

const createDataContent = (data: any): Promise<AxiosResponse> => {
	return sendRequest(SERVICES.CREATE_DATA_CONTENT, { ...data });
};

const updateDataContent = (dataContentId: number, data: any): Promise<AxiosResponse> => {
	const { host, endpoint } = SERVICES.UPDATE_DATA_CONTENT;

	SERVICES.UPDATE_DATA_CONTENT.dynamicUrl = `${host}${endpoint}${dataContentId}`;

	return sendRequest(SERVICES.UPDATE_DATA_CONTENT, { ...data });
};

const deleteDataContent = async (dataContentId: number): Promise<AxiosResponse> => {
	const { host, endpoint } = SERVICES.DELETE_DATA_CONTENT;

	SERVICES.DELETE_DATA_CONTENT.dynamicUrl = `${host}${endpoint}${dataContentId}`;
	return sendRequest(SERVICES.DELETE_DATA_CONTENT);
};

const getDataContentBulk = (dataContentIDs: number[], siteID?: number): Promise<AxiosResponse> => {
	const { host, endpoint } = SERVICES.GET_DATA_CONTENT_BULK;
	const url = siteID ? `${host}/site/${siteID}${endpoint}` : `${host}${endpoint}`;
	const ids = dataContentIDs.join(",");
	SERVICES.GET_DATA_CONTENT_BULK.dynamicUrl = `${url}${ids}`;
	return sendRequest(SERVICES.GET_DATA_CONTENT_BULK);
};

const deleteDataContentBulk = (dataContentID: number[]): Promise<AxiosResponse> => {
	return sendRequest(SERVICES.DELETE_DATA_CONTENT_BULK, { ids: dataContentID });
};

const restoreDataContent = (dataContentId: number): Promise<AxiosResponse> => {
	const {
		host,
		endpoint: [prefix, suffix],
	} = SERVICES.RESTORE_DATA_CONTENT;

	SERVICES.RESTORE_DATA_CONTENT.dynamicUrl = `${host}${prefix}${dataContentId}${suffix}`;

	return sendRequest(SERVICES.RESTORE_DATA_CONTENT);
};

const restoreDataContentBulk = (dataContentId: number[]): Promise<AxiosResponse> => {
	return sendRequest(SERVICES.RESTORE_DATA_CONTENT_BULK, { ids: dataContentId });
};

const getDistributorContent = async (siteID: number | string, data: any): Promise<AxiosResponse> => {
	const { host, endpoint } = SERVICES.GET_DISTRIBUTOR_CONTENT;
	const [prefix, suffix] = endpoint;

	SERVICES.GET_DISTRIBUTOR_CONTENT.dynamicUrl = `${host}${prefix}${siteID}${suffix}`;

	return sendRequest(SERVICES.GET_DISTRIBUTOR_CONTENT, { ...data });
};

const getDataTitles = async (data: string[]): Promise<AxiosResponse> => {
	const { host, endpoint } = SERVICES.GET_DATA_TITLES;

	const dataString = data.join(",");

	SERVICES.GET_DATA_TITLES.dynamicUrl = `${host}${endpoint}${dataString}`;
	return sendRequest(SERVICES.GET_DATA_TITLES);
};

const setDataStatus = (dataContentId: number, status: string): Promise<AxiosResponse> => {
	const { host, endpoint } = SERVICES.SET_DATA_STATUS;

	SERVICES.SET_DATA_STATUS.dynamicUrl = `${host}${endpoint}${dataContentId}/${status}`;

	return sendRequest(SERVICES.SET_DATA_STATUS);
};

const setDataStatusBulk = (dataContentID: number[], status: string): Promise<AxiosResponse> => {
	const { host, endpoint } = SERVICES.SET_DATA_STATUS_BULK;
	const [prefix, suffix] = endpoint;

	SERVICES.SET_DATA_STATUS_BULK.dynamicUrl = `${host}${prefix}${status}${suffix}`;

	return sendRequest(SERVICES.SET_DATA_STATUS_BULK, { ids: dataContentID });
};

const getContentTypes = (siteID: number | null, lang?: number): Promise<AxiosResponse> => {
	const { host, endpoint } = SERVICES.GET_CONTENT_TYPES;
	const [prefix, suffix] = endpoint;

	SERVICES.GET_CONTENT_TYPES.dynamicUrl = `${host}${prefix}${siteID}${suffix}`;

	const dataHeader = {} as { lang: number };
	if (lang) dataHeader.lang = lang;

	return sendRequest(SERVICES.GET_CONTENT_TYPES, null, dataHeader);
};

const getDataContentTranslation = async (data: any, langID: number): Promise<AxiosResponse> => {
	const { host, endpoint } = SERVICES.CONTENT_AI_TRANSLATION;
	SERVICES.CONTENT_AI_TRANSLATION.dynamicUrl = `${host}${endpoint}${langID}`;

	return sendRequest(SERVICES.CONTENT_AI_TRANSLATION, { ...data });
};

const createGroup = (data: ICategoryGroupParams): Promise<AxiosResponse> => {
	return sendRequest(SERVICES.CREATE_GROUP, { ...data });
};

const getGroup = (groupId: number): Promise<AxiosResponse> => {
	const { host, endpoint } = SERVICES.GET_GROUP;
	SERVICES.GET_GROUP.dynamicUrl = `${host}${endpoint}${groupId}`;
	return sendRequest(SERVICES.GET_GROUP);
};

const updateGroup = (groupID: number, data: ICategoryGroupParams): Promise<AxiosResponse> => {
	const { host, endpoint } = SERVICES.EDIT_GROUP;
	SERVICES.EDIT_GROUP.dynamicUrl = `${host}${endpoint}${groupID}`;

	return sendRequest(SERVICES.EDIT_GROUP, { ...data });
};

const deleteGroup = (
	structuredDataID: string,
	siteID: number | "global",
	groupID: number,
	deleteChildren: boolean,
): Promise<AxiosResponse> => {
	const { host, endpoint } = SERVICES.DELETE_GROUP;
	const [prefix, infix, suffix] = endpoint;

	const children = deleteChildren === false ? "?deleteChildren=off" : "";

	SERVICES.DELETE_GROUP.dynamicUrl = `${host}${prefix}${structuredDataID}${infix}${siteID}${suffix}${groupID}${children}`;

	return sendRequest(SERVICES.DELETE_GROUP);
};

const deleteGroupBulk = (
	structuredDataID: string,
	siteID: number | "global",
	groupID: number[],
	deleteChildren: boolean,
): Promise<AxiosResponse> => {
	const { host, endpoint } = SERVICES.DELETE_GROUP_BULK;
	const [prefix, infix, suffix] = endpoint;

	const children = deleteChildren === false ? "?deleteChildren=off" : "";

	SERVICES.DELETE_GROUP_BULK.dynamicUrl = `${host}${prefix}${structuredDataID}${infix}${siteID}${suffix}${children}`;

	return sendRequest(SERVICES.DELETE_GROUP_BULK, { groups: groupID });
};

const orderCategory = (data: IOrderCategoryParams): Promise<AxiosResponse> => {
	return sendRequest(SERVICES.ORDER_CATEGORY, { ...data });
};

const exportDataContent = (
	structuredDataID: string,
	siteID: number | "global",
	data: IExportDataParams,
): Promise<AxiosResponse> => {
	const { host, endpoint } = SERVICES.EXPORT_DATA_CONTENT;
	const [prefix, infix, suffix] = endpoint;

	SERVICES.EXPORT_DATA_CONTENT.dynamicUrl = `${host}${prefix}${structuredDataID}${infix}${siteID}${suffix}`;

	return sendRequest(SERVICES.EXPORT_DATA_CONTENT, { ...data });
};

const getAISearchData = (): Promise<AxiosResponse> => sendRequest(SERVICES.GET_AI_SEARCH_DATA);

export default {
	getData,
	getDataContent,
	getDataContents,
	createDataContent,
	updateDataContent,
	deleteDataContent,
	deleteDataContentBulk,
	getDistributorContent,
	getDataTitles,
	restoreDataContent,
	restoreDataContentBulk,
	setDataStatus,
	setDataStatusBulk,
	getContentTypes,
	getDataContentBulk,
	getDataContentTranslation,
	createGroup,
	updateGroup,
	deleteGroup,
	deleteGroupBulk,
	orderCategory,
	getGroup,
	exportDataContent,
	getAISearchData,
};
