import { Dispatch } from "redux";
import { format } from "date-fns";

import {
	LogActivityExportRequest,
	LogActivityGroupedDayDTO,
	LogActivityGroupedUserDTO,
	LogActivityPaginationRequest,
	LogContentDTO,
	LogContentTypeDTO,
	PaginationResponse,
} from "@griddo/api-types";
import { logs } from "@ax/api";
import { appActions } from "@ax/containers/App";
import { usersActions } from "@ax/containers/Users";
import { pageEditorActions } from "@ax/containers/PageEditor";
import { sitesActions } from "@ax/containers/Sites";
import { integrationsActions } from "@ax/containers/Integrations";
import { formsActions } from "@ax/containers/Forms";
import { navigationActions } from "@ax/containers/Navigation";
import { structuredDataActions } from "@ax/containers/StructuredData";
import { handleRequest } from "@ax/helpers";
import { ILogItemsByUser, IRootState } from "@ax/types";

import { SET_ACTIVITY_LOG, SET_LIST_MODE } from "./constants";
import { ISetActivityLog, ISetListMode } from "./interfaces";
import { ILogItemsByDay } from "src/types/logs";

function setActivityLog(activityLog: ILogItemsByDay | ILogItemsByUser): ISetActivityLog {
	return { type: SET_ACTIVITY_LOG, payload: { activityLog } };
}

function setListMode(listMode: string): ISetListMode {
	return { type: SET_LIST_MODE, payload: { listMode } };
}

function getActivityLog(params: LogActivityPaginationRequest): (dispatch: Dispatch) => Promise<void> {
	return async (dispatch) => {
		try {
			const callback = async () => logs.getLogActivityTimelineByDay(params);

			const responseActions = {
				handleSuccess: (response: PaginationResponse<LogActivityGroupedDayDTO>) => {
					dispatch(setActivityLog(response));
				},
				handleError: (response: any) => appActions.handleError(response)(dispatch),
			};

			await handleRequest(callback, responseActions, [appActions.setIsLoading])(dispatch);
		} catch (e) {
			console.log(e);
		}
	};
}

function getActivityLogByUser(params: LogActivityPaginationRequest): (dispatch: Dispatch) => Promise<void> {
	return async (dispatch) => {
		try {
			const callback = async () => logs.getLogActivityTimelineByUser(params);

			const responseActions = {
				handleSuccess: (response: PaginationResponse<LogActivityGroupedUserDTO<LogActivityGroupedUserDTO[]>>) => {
					dispatch(setActivityLog(response));
				},
				handleError: (response: any) => appActions.handleError(response)(dispatch),
			};

			await handleRequest(callback, responseActions, [appActions.setIsLoading])(dispatch);
		} catch (e) {
			console.log(e);
		}
	};
}

function downloadActivityLog(data: LogActivityExportRequest): (dispatch: Dispatch) => Promise<void> {
	return async (dispatch) => {
		try {
			const responseActions = {
				handleSuccess: (response: any) => {
					const dateString = format(new Date(), "yyyy-MM-dd");
					const url = window.URL.createObjectURL(new Blob([response]));
					const a = document.createElement("a");
					a.href = url;
					a.download = `activity-log-${dateString}.${data.format[0]}`;
					document.body.appendChild(a);
					a.click();
					window.URL.revokeObjectURL(url);
				},
				handleError: (response: any) => appActions.handleError(response)(dispatch),
			};

			const callback = async () => logs.logExport(data);

			await handleRequest(callback, responseActions, [])(dispatch);
		} catch (e) {
			console.log(e);
		}
	};
}

function goToLogContent(
	contentType: LogContentTypeDTO | null,
	content: LogContentDTO | null,
	site: number | null,
): (dispatch: Dispatch, getState: () => IRootState) => void {
	return async (dispatch, getState) => {
		const {
			app: { lang, globalLangs },
		} = getState();

		let language = lang;

		if (content) {
			if (content.language && content.language !== lang.id) {
				const languageFound = globalLangs.find((lang) => lang.id === content.language);
				if (languageFound) {
					language = { locale: languageFound.locale, id: languageFound.id };
				}
			}

			switch (content.type) {
				case "user":
					usersActions.getUser(content.id)(dispatch, getState);
					appActions.setHistoryPush("/users/edit")(dispatch);
					break;
				case "category":
					if (site) {
						await sitesActions.getSite(site)(dispatch, getState);
						dispatch(appActions.setLanguage(language));
						appActions.setHistoryPush("/sites/categories")(dispatch);
					} else {
						dispatch(appActions.setLanguage(language));
						appActions.setHistoryPush("/categories")(dispatch);
					}
					break;
				case "site":
					if (site) {
						await sitesActions.getSite(site)(dispatch, getState);
						appActions.setHistoryPush("/sites/pages")(dispatch);
					}
					break;
				case "integrations":
					if (site) {
						await sitesActions.getSite(site)(dispatch, getState);
						integrationsActions.getIntegration(content.id, site)(dispatch);
						appActions.setHistoryPush("/sites/settings/addons/edit")(dispatch);
					}
					break;
				case "redirects":
					appActions.setHistoryPush("/settings/redirects")(dispatch);
					break;
				case "languages":
					if (site) {
						await sitesActions.getSite(site)(dispatch, getState);
						appActions.setHistoryPush("/sites/settings/languages")(dispatch);
					}
					break;
				case "file":
					if (site) {
						await sitesActions.getSite(site)(dispatch, getState);
						appActions.setHistoryPush("/sites/media-assets/files")(dispatch);
					} else {
						appActions.setHistoryPush("/media-assets/files")(dispatch);
					}
					break;
				case "image":
					if (site) {
						await sitesActions.getSite(site)(dispatch, getState);
						appActions.setHistoryPush("/sites/media-assets/gallery")(dispatch);
					} else {
						appActions.setHistoryPush("/media-assets/gallery")(dispatch);
					}
					break;
				case "form":
					if (site) {
						await sitesActions.getSite(site)(dispatch, getState);
						dispatch(formsActions.setCurrentFormID(content.id));
						dispatch(appActions.setLanguage(language));
						appActions.setHistoryPush("/sites/forms/editor", true)(dispatch);
					} else {
						dispatch(formsActions.setCurrentFormID(content.id));
						dispatch(appActions.setLanguage(language));
						appActions.setHistoryPush("/forms/editor", true)(dispatch);
					}
					break;
				case "data_pack":
					if (site) {
						await sitesActions.getSite(site)(dispatch, getState);
						appActions.setHistoryPush("/sites/settings/content-types")(dispatch);
					}
					break;
				case "menu":
					if (site) {
						await sitesActions.getSite(site)(dispatch, getState);
						dispatch(appActions.setLanguage(language));
						appActions.setHistoryPush("/sites/navigations/menus")(dispatch);
					}
					break;
				case "header":
					if (site) {
						await sitesActions.getSite(site)(dispatch, getState);
						dispatch(navigationActions.setSelectedDefault("Headers"));
						dispatch(navigationActions.setHeader(content.id));
						dispatch(appActions.setLanguage(language));
						appActions.setHistoryPush("/sites/navigations/editor", true)(dispatch);
					}
					break;
				case "footer":
					if (site) {
						await sitesActions.getSite(site)(dispatch, getState);
						dispatch(navigationActions.setSelectedDefault("Footers"));
						dispatch(navigationActions.setFooter(content.id));
						dispatch(appActions.setLanguage(language));
						appActions.setHistoryPush("/sites/navigations/editor", true)(dispatch);
					}
					break;
			}
		}

		if (contentType) {
			if (contentType.languageId && contentType.languageId !== lang.id) {
				const languageFound = globalLangs.find((lang) => lang.id === contentType.languageId);
				if (languageFound) {
					language = { locale: languageFound.locale, id: languageFound.id };
				}
			}

			switch (contentType.type) {
				case "template":
					if (site) {
						await sitesActions.getSite(site)(dispatch, getState);
						dispatch(pageEditorActions.setCurrentPageID(contentType.id));
						dispatch(appActions.setLanguage(language));
						appActions.setHistoryPush("/sites/pages/editor", true)(dispatch);
					} else {
						dispatch(pageEditorActions.setCurrentPageID(contentType.id));
						dispatch(appActions.setLanguage(language));
						appActions.setHistoryPush("/data/pages/editor", true)(dispatch);
					}
					break;
				case "structuredData":
					if (contentType.content) {
						if (site) {
							await sitesActions.getSite(site)(dispatch, getState);
							structuredDataActions.setSelectedStructuredData(contentType.content.id, "site")(dispatch, getState);
							dispatch(structuredDataActions.setCurrentDataID(contentType.id));
							await structuredDataActions.getDataContent(contentType.id)(dispatch);
							dispatch(appActions.setLanguage(language));
							appActions.setHistoryPush(`/sites/data/${contentType.content.id}/editor`)(dispatch);
						} else {
							structuredDataActions.setSelectedStructuredData(contentType.content.id, "global")(dispatch, getState);
							dispatch(structuredDataActions.setCurrentDataID(contentType.id));
							await structuredDataActions.getDataContent(contentType.id)(dispatch);
							dispatch(appActions.setLanguage(language));
							appActions.setHistoryPush(`/data/${contentType.content.id}/editor`)(dispatch);
						}
					}
					break;
			}
		}
	};
}

export { getActivityLog, getActivityLogByUser, setListMode, downloadActivityLog, goToLogContent };
