/*
 * Copyright (C) 2026 Fluxer Contributors
 *
 * This file is part of Fluxer.
 *
 * Fluxer is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Fluxer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
 */

import * as GuildMemberActionCreators from '@app/actions/GuildMemberActionCreators';
import * as ModalActionCreators from '@app/actions/ModalActionCreators';
import {modal} from '@app/actions/ModalActionCreators';
import * as ToastActionCreators from '@app/actions/ToastActionCreators';
import {RemoveTimeoutModal} from '@app/components/modals/RemoveTimeoutModal';
import {getTimeoutDurationOptions, type TimeoutDurationOption} from '@app/components/modals/TimeoutMemberOptions';
import styles from '@app/components/modals/TimeoutMemberSheet.module.css';
import {
	MenuBottomSheet,
	type MenuGroupType,
	type MenuItemType,
	type MenuRadioType,
} from '@app/components/uikit/menu_bottom_sheet/MenuBottomSheet';
import {Logger} from '@app/lib/Logger';
import type {GuildMemberRecord} from '@app/records/GuildMemberRecord';
import type {UserRecord} from '@app/records/UserRecord';
import {Trans, useLingui} from '@lingui/react/macro';
import {ClockIcon, XCircleIcon} from '@phosphor-icons/react';
import {observer} from 'mobx-react-lite';
import type React from 'react';
import {useCallback, useMemo, useState} from 'react';

const logger = new Logger('TimeoutMemberSheet');

interface TimeoutMemberSheetProps {
	isOpen: boolean;
	onClose: () => void;
	guildId: string;
	targetUser: UserRecord;
	targetMember: GuildMemberRecord;
}

export const TimeoutMemberSheet: React.FC<TimeoutMemberSheetProps> = observer(
	({isOpen, onClose, guildId, targetUser, targetMember}) => {
		const {t, i18n} = useLingui();
		const isCurrentlyTimedOut = targetMember.isTimedOut();
		const timeoutOptions = useMemo(() => getTimeoutDurationOptions(i18n), [i18n]);
		const [timeoutDuration, setTimeoutDuration] = useState<number>(timeoutOptions[3].value);
		const [isSubmitting, setIsSubmitting] = useState(false);

		const handleTimeout = useCallback(async () => {
			setIsSubmitting(true);
			try {
				const timeoutUntil = new Date(Date.now() + timeoutDuration * 1000).toISOString();
				await GuildMemberActionCreators.timeout(guildId, targetUser.id, timeoutUntil);
				ToastActionCreators.createToast({
					type: 'success',
					children: <Trans>Successfully timed out {targetUser.tag}</Trans>,
				});
				onClose();
			} catch (error) {
				logger.error('Failed to timeout member:', error);
				ToastActionCreators.createToast({
					type: 'error',
					children: <Trans>Failed to timeout member. Please try again.</Trans>,
				});
			} finally {
				setIsSubmitting(false);
			}
		}, [guildId, onClose, targetUser.id, timeoutDuration, targetUser.tag]);

		const durationItems: Array<MenuRadioType> = useMemo(() => {
			return timeoutOptions.map((option: TimeoutDurationOption) => ({
				label: option.label,
				selected: option.value === timeoutDuration,
				onSelect: () => setTimeoutDuration(option.value),
			}));
		}, [timeoutDuration, timeoutOptions]);

		const actionItems: Array<MenuItemType> = useMemo(() => {
			const items: Array<MenuItemType> = [
				{
					id: 'timeout',
					icon: <ClockIcon size={20} />,
					label: t`Timeout`,
					onClick: handleTimeout,
					danger: true,
					disabled: isSubmitting,
				},
			];

			if (isCurrentlyTimedOut) {
				items.push({
					id: 'remove-timeout',
					icon: <XCircleIcon size={20} />,
					label: t`Remove Timeout`,
					onClick: () => {
						onClose();
						ModalActionCreators.push(modal(() => <RemoveTimeoutModal guildId={guildId} targetUser={targetUser} />));
					},
					danger: true,
					disabled: isSubmitting,
				});
			}

			return items;
		}, [guildId, handleTimeout, isCurrentlyTimedOut, isSubmitting, onClose, targetUser]);

		const headerContent = (
			<div className={styles.header}>
				<p className={styles.description}>
					{isCurrentlyTimedOut ? (
						<Trans>
							<strong>{targetUser.tag}</strong> is currently timed out. You can update their timeout duration or remove
							the timeout.
						</Trans>
					) : (
						<Trans>
							Prevent <strong>{targetUser.tag}</strong> from sending messages, reacting, and connecting to voice
							channels for the specified duration.
						</Trans>
					)}
				</p>
			</div>
		);

		const groups: Array<MenuGroupType> = [{items: durationItems}, {items: actionItems}];

		return (
			<MenuBottomSheet
				isOpen={isOpen}
				onClose={onClose}
				title={isCurrentlyTimedOut ? t`Update Timeout` : t`Timeout ${targetUser.tag}`}
				showCloseButton={true}
				headerContent={headerContent}
				groups={groups}
			/>
		);
	},
);
