/*
 * 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 ModalActionCreators from '@app/actions/ModalActionCreators';
import * as UserSettingsActionCreators from '@app/actions/UserSettingsActionCreators';
import {ColorPickerField} from '@app/components/form/ColorPickerField';
import {Input} from '@app/components/form/Input';
import {Select, type SelectOption} from '@app/components/form/Select';
import {Switch} from '@app/components/form/Switch';
import * as Modal from '@app/components/modals/Modal';
import {Button} from '@app/components/uikit/button/Button';
import {useCursorAtEnd} from '@app/hooks/useCursorAtEnd';
import GuildStore from '@app/stores/GuildStore';
import UserSettingsStore from '@app/stores/UserSettingsStore';
import {
	DEFAULT_GUILD_FOLDER_ICON,
	GuildFolderFlags,
	type GuildFolderIcon,
	GuildFolderIcons,
} from '@fluxer/constants/src/UserConstants';
import {useLingui} from '@lingui/react/macro';
import {
	BookmarkSimpleIcon,
	FolderIcon,
	GameControllerIcon,
	HeartIcon,
	MusicNoteIcon,
	ShieldIcon,
	StarIcon,
} from '@phosphor-icons/react';
import {observer} from 'mobx-react-lite';
import type {ReactNode} from 'react';
import {useCallback, useMemo, useState} from 'react';

const FOLDER_ICON_MAP: Record<GuildFolderIcon, ReactNode> = {
	[GuildFolderIcons.FOLDER]: <FolderIcon weight="fill" size={18} />,
	[GuildFolderIcons.STAR]: <StarIcon weight="fill" size={18} />,
	[GuildFolderIcons.HEART]: <HeartIcon weight="fill" size={18} />,
	[GuildFolderIcons.BOOKMARK]: <BookmarkSimpleIcon weight="fill" size={18} />,
	[GuildFolderIcons.GAME_CONTROLLER]: <GameControllerIcon weight="fill" size={18} />,
	[GuildFolderIcons.SHIELD]: <ShieldIcon weight="fill" size={18} />,
	[GuildFolderIcons.MUSIC_NOTE]: <MusicNoteIcon weight="fill" size={18} />,
};

interface GuildFolderSettingsModalProps {
	folderId: number;
}

export const GuildFolderSettingsModal = observer(({folderId}: GuildFolderSettingsModalProps) => {
	const {t} = useLingui();

	const folder = useMemo(() => {
		return UserSettingsStore.guildFolders.find((f) => f.id === folderId);
	}, [folderId]);

	const autoGeneratedName = useMemo(() => {
		if (!folder) return '';
		const guildNames = folder.guildIds
			.slice(0, 3)
			.map((guildId) => GuildStore.getGuild(guildId)?.name)
			.filter((name): name is string => name != null);
		return guildNames.join(', ');
	}, [folder]);

	const [name, setName] = useState(folder?.name ?? '');
	const nameRef = useCursorAtEnd<HTMLInputElement>();
	const [color, setColor] = useState(folder?.color ?? 0);
	const [flags, setFlags] = useState(folder?.flags ?? 0);
	const [icon, setIcon] = useState<GuildFolderIcon>(folder?.icon ?? DEFAULT_GUILD_FOLDER_ICON);
	const [isSaving, setIsSaving] = useState(false);
	const showCollapsedIcon =
		(flags & GuildFolderFlags.SHOW_ICON_WHEN_COLLAPSED) === GuildFolderFlags.SHOW_ICON_WHEN_COLLAPSED;
	const iconOptions = useMemo<Array<SelectOption<GuildFolderIcon>>>(
		() => [
			{value: GuildFolderIcons.FOLDER, label: t`Folder`},
			{value: GuildFolderIcons.STAR, label: t`Star`},
			{value: GuildFolderIcons.HEART, label: t`Heart`},
			{value: GuildFolderIcons.BOOKMARK, label: t`Bookmark`},
			{value: GuildFolderIcons.GAME_CONTROLLER, label: t`Game controller`},
			{value: GuildFolderIcons.SHIELD, label: t`Shield`},
			{value: GuildFolderIcons.MUSIC_NOTE, label: t`Music note`},
		],
		[t],
	);

	const handleNameChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
		setName(event.target.value);
	}, []);

	const handleColorChange = useCallback((newColor: number) => {
		setColor(newColor);
	}, []);

	const handleShowCollapsedIconChange = useCallback((value: boolean) => {
		setFlags((currentFlags) => {
			if (value) {
				return currentFlags | GuildFolderFlags.SHOW_ICON_WHEN_COLLAPSED;
			}
			return currentFlags & ~GuildFolderFlags.SHOW_ICON_WHEN_COLLAPSED;
		});
	}, []);

	const handleIconChange = useCallback((value: GuildFolderIcon) => {
		setIcon(value);
	}, []);

	const renderIconOption = useCallback(
		(option: SelectOption<GuildFolderIcon>, _isSelected: boolean) => (
			<span style={{display: 'flex', alignItems: 'center', gap: 8}}>
				{FOLDER_ICON_MAP[option.value]}
				{option.label}
			</span>
		),
		[],
	);

	const handleCancel = useCallback(() => {
		ModalActionCreators.pop();
	}, []);

	const handleSave = useCallback(async () => {
		if (!folder) return;

		setIsSaving(true);
		try {
			const updatedFolders = UserSettingsStore.guildFolders.map((f) => {
				if (f.id === folderId) {
					return {
						...f,
						name: name.trim() || null,
						color: color || null,
						flags,
						icon,
					};
				}
				return f;
			});

			await UserSettingsActionCreators.update({guildFolders: updatedFolders});
			ModalActionCreators.pop();
		} finally {
			setIsSaving(false);
		}
	}, [folder, folderId, name, color, flags, icon]);

	if (!folder) {
		return null;
	}

	return (
		<Modal.Root size="small" centered>
			<Modal.Header title={t`Folder Settings`} />
			<Modal.Content>
				<Modal.ContentLayout>
					<Input
						ref={nameRef}
						autoFocus={true}
						label={t`Folder Name`}
						placeholder={autoGeneratedName}
						value={name}
						onChange={handleNameChange}
						autoComplete="off"
						maxLength={100}
					/>
					<ColorPickerField label={t`Folder Color`} value={color} onChange={handleColorChange} />
					<Switch
						label={t`Show icon when collapsed`}
						value={showCollapsedIcon}
						onChange={handleShowCollapsedIconChange}
					/>
					<Select
						label={t`Folder Icon`}
						value={icon}
						options={iconOptions}
						onChange={handleIconChange}
						isSearchable={false}
						renderOption={renderIconOption}
					/>
				</Modal.ContentLayout>
			</Modal.Content>
			<Modal.Footer>
				<Button onClick={handleCancel} variant="secondary">
					{t`Cancel`}
				</Button>
				<Button onClick={handleSave} submitting={isSaving}>
					{t`Save`}
				</Button>
			</Modal.Footer>
		</Modal.Root>
	);
});

export function openGuildFolderSettingsModal(folderId: number): void {
	ModalActionCreators.push(ModalActionCreators.modal(() => <GuildFolderSettingsModal folderId={folderId} />));
}
