import { useMemo } from "react";

import { Button, Flag, FloatingMenu, Icon, Modal, Tooltip } from "@ax/components";
import type { IActionMenuOption, ILanguage } from "@ax/types";

import * as S from "./style";

interface IMenuButton {
	action: () => void;
	disabled?: boolean;
	label: string;
	helpText?: string | null;
}

interface IMenu {
	button?: IMenuButton | null;
	options: IActionMenuOption[];
}

interface IDownArrowButtonProps {
	inversed?: boolean;
	disabled?: boolean;
}

const ActionMenuItem = (item: IActionMenuOption, color?: boolean) => {
	const { icon, action, label } = item;
	return (
		<S.ActionItem data-testid="action-menu-item" className={color ? "" : "grey"} key={icon} onClick={action}>
			<Icon name={icon} />
			<S.ActionText>{label}</S.ActionText>
		</S.ActionItem>
	);
};

const ActionMenuBtn = ({ menu }: { menu?: IMenu }) => {
	if (!menu?.button) return null;
	return (
		<S.ButtonWrapper>
			<Button type="button" buttonStyle="line" onClick={menu.button.action} disabled={menu.button.disabled}>
				{menu.button.label}
			</Button>
			{menu.button.helpText && <S.HelpText>{menu.button.helpText}</S.HelpText>}
		</S.ButtonWrapper>
	);
};

const ActionMenu = ({ menu }: { menu: IMenu }) => (
	<S.ActionMenu>
		<S.ActionMenuTitle> More actions </S.ActionMenuTitle>
		<ActionMenuBtn menu={menu} />
		{menu?.options.map((item) => item && ActionMenuItem(item))}
	</S.ActionMenu>
);

const DownArrowButton = ({ inversed, disabled }: IDownArrowButtonProps) => (
	<S.IconWrapper inversed={inversed} disabled={disabled} data-testid="down-arrow-button-wrapper">
		<Icon name="DownArrow" />
	</S.IconWrapper>
);

const ActionSimpleMenu = ({ menu }: { menu?: IMenu }) =>
	menu && menu.options.length > 0 ? (
		<S.ActionMenu data-testid="action-simple-menu">
			{menu.options.map((item) => item && ActionMenuItem(item, true))}
		</S.ActionMenu>
	) : null;

const StatusBtn = ({ pageStatus }: { pageStatus: string }) => (
	<S.StatusBtn data-testid="status-button">
		<Icon name={pageStatus} size="24" />
	</S.StatusBtn>
);

interface IPageStatusProps {
	pageStatus?: string;
	pageStatusActions?: IActionMenuOption[];
	hasRightButton?: boolean;
}

const PageStatus = ({ pageStatus, pageStatusActions, hasRightButton }: IPageStatusProps) => {
	const ps = pageStatus ?? "offline";
	const statusMenu: IMenu = { options: pageStatusActions ?? [] };
	const offset = hasRightButton ? -20 : -135;
	const BoundStatusBtn = useMemo(() => () => <StatusBtn pageStatus={ps} />, [ps]);
	return statusMenu.options && statusMenu.options.length > 0 ? (
		<FloatingMenu Button={BoundStatusBtn} isInAppBar position="left" offset={offset}>
			<ActionSimpleMenu menu={statusMenu} />
		</FloatingMenu>
	) : (
		<Icon name={ps} size="24" />
	);
};

const ErrorCenterBtn = () => (
	<S.ErrorWrapper>
		<Tooltip content="Error center" bottom>
			<Icon name="alert" size="24" />
		</Tooltip>
	</S.ErrorWrapper>
);

interface ILanguageBtnProps {
	language: { locale: string; id: number | null };
	availableLanguages?: ILanguage[];
}

const LanguageBtn = ({ language, availableLanguages }: ILanguageBtnProps) => (
	<>
		<S.FlagWrapper data-testid="language-menu-btn">
			<Flag name={language.locale} size="24" />
		</S.FlagWrapper>
		<S.LanguageTextWrapper data-testid="language-locale-label">{language.locale}</S.LanguageTextWrapper>
		{!!availableLanguages?.length && <DownArrowButton />}
	</>
);

interface IChangeLanguageModalProps {
	isOpen: boolean;
	hide: () => void;
	title: string;
	mainAction: { title: string; onClick: () => void };
	secondaryAction: { title: string; onClick: () => void };
}

const ChangeLanguageModal = ({ isOpen, hide, title, mainAction, secondaryAction }: IChangeLanguageModalProps) => (
	<Modal isOpen={isOpen} hide={hide} title={title} mainAction={mainAction} secondaryAction={secondaryAction}>
		<S.ModalContent>
			If you change without saving it, it will be lost. Do you want to discard your changes?
		</S.ModalContent>
	</Modal>
);

export {
	ActionMenu,
	ActionSimpleMenu,
	ChangeLanguageModal,
	DownArrowButton,
	ErrorCenterBtn,
	LanguageBtn,
	PageStatus,
	type IMenuButton,
};
