<script>
	import { toast } from 'svelte-sonner';
	import dayjs from 'dayjs';
	import relativeTime from 'dayjs/plugin/relativeTime';
	dayjs.extend(relativeTime);

	import { onMount, getContext } from 'svelte';
	import { goto } from '$app/navigation';

	import { WEBUI_NAME, config, user, showSidebar, knowledge } from '$lib/stores';
	import { WEBUI_BASE_URL } from '$lib/constants';

	import Tooltip from '$lib/components/common/Tooltip.svelte';
	import Plus from '$lib/components/icons/Plus.svelte';
	import UsersSolid from '$lib/components/icons/UsersSolid.svelte';
	import ChevronRight from '$lib/components/icons/ChevronRight.svelte';
	import Search from '$lib/components/icons/Search.svelte';
	import EditGroupModal from './Groups/EditGroupModal.svelte';
	import GroupItem from './Groups/GroupItem.svelte';
	import XMark from '$lib/components/icons/XMark.svelte';
	import ChevronDown from '$lib/components/icons/ChevronDown.svelte';
	import Check from '$lib/components/icons/Check.svelte';
	import Select from '$lib/components/common/Select.svelte';
	import { createNewGroup, getGroups } from '$lib/apis/groups';
	import {
		getUserDefaultPermissions,
		getAllUsers,
		updateUserDefaultPermissions
	} from '$lib/apis/users';

	const i18n = getContext('i18n');

	let loaded = false;

	let groups = [];

	let query = '';
	let sortBy = 'members';

	const sortItems = [
		{ value: 'name', label: $i18n.t('Name') },
		{ value: 'members', label: $i18n.t('Members') }
	];

	$: filteredGroups = groups
		.filter((group) => {
			if (query === '') {
				return true;
			} else {
				let name = group.name.toLowerCase();
				const q = query.toLowerCase();
				return name.includes(q);
			}
		})
		.sort((a, b) => {
			if (sortBy === 'name') {
				return a.name.localeCompare(b.name);
			} else if (sortBy === 'members') {
				return (b.member_count ?? 0) - (a.member_count ?? 0);
			}
			return 0;
		});

	let defaultPermissions = {};

	let showAddGroupModal = false;
	let showDefaultPermissionsModal = false;

	const setGroups = async () => {
		groups = await getGroups(localStorage.token);
	};

	const addGroupHandler = async (group) => {
		const res = await createNewGroup(localStorage.token, group).catch((error) => {
			toast.error(`${error}`);
			return null;
		});

		if (res) {
			toast.success($i18n.t('Group created successfully'));
			groups = await getGroups(localStorage.token);
		}
	};

	const updateDefaultPermissionsHandler = async (group) => {
		console.debug(group.permissions);

		const res = await updateUserDefaultPermissions(localStorage.token, group.permissions).catch(
			(error) => {
				toast.error(`${error}`);
				return null;
			}
		);

		if (res) {
			toast.success($i18n.t('Default permissions updated successfully'));
			defaultPermissions = await getUserDefaultPermissions(localStorage.token);
		}
	};

	onMount(async () => {
		if ($user?.role !== 'admin') {
			await goto('/');
			return;
		}

		defaultPermissions = await getUserDefaultPermissions(localStorage.token);
		await setGroups();
		loaded = true;
	});
</script>

{#if loaded}
	<EditGroupModal
		bind:show={showAddGroupModal}
		edit={false}
		tabs={['general', 'permissions']}
		permissions={defaultPermissions}
		onSubmit={addGroupHandler}
	/>

	<div class="flex flex-col gap-1 px-1 mt-1.5 mb-3">
		<div class="flex justify-between items-center">
			<div class="flex items-center md:self-center text-xl font-medium px-0.5 gap-2 shrink-0">
				<div>
					{$i18n.t('Groups')}
				</div>

				<div class="text-lg font-medium text-gray-500 dark:text-gray-500">
					{filteredGroups.length}
				</div>
			</div>

			<div class="flex w-full justify-end gap-1.5">
				<button
					class="px-2 py-1.5 rounded-xl bg-black text-white dark:bg-white dark:text-black transition font-medium text-sm flex items-center"
					on:click={() => {
						showAddGroupModal = !showAddGroupModal;
					}}
				>
					<Plus className="size-3" strokeWidth="2.5" />

					<div class="hidden md:block md:ml-1 text-xs">{$i18n.t('New Group')}</div>
				</button>
			</div>
		</div>
	</div>

	<div
		class="py-2 bg-white dark:bg-gray-900 rounded-3xl border border-gray-100/30 dark:border-gray-850/30"
	>
		<div class="flex items-center w-full space-x-2 py-0.5 px-3.5">
			<div class="flex flex-1">
				<div class="self-center ml-1 mr-3">
					<Search className="size-3.5" />
				</div>
				<input
					class="w-full text-sm py-1 rounded-r-xl outline-hidden bg-transparent"
					bind:value={query}
					aria-label={$i18n.t('Search Groups')}
					placeholder={$i18n.t('Search Groups')}
				/>
				{#if query}
					<div class="self-center pl-1.5 translate-y-[0.5px] rounded-l-xl bg-transparent">
						<button
							class="p-0.5 rounded-full hover:bg-gray-100 dark:hover:bg-gray-900 transition"
							aria-label={$i18n.t('Clear search')}
							on:click={() => {
								query = '';
							}}
						>
							<XMark className="size-3" strokeWidth="2" />
						</button>
					</div>
				{/if}
			</div>

			<Select
				bind:value={sortBy}
				items={sortItems}
				placeholder={$i18n.t('Sort by')}
				triggerClass="relative flex items-center gap-0.5 px-2.5 py-1.5 text-sm bg-gray-50 dark:bg-gray-850 rounded-xl shrink-0"
				align="end"
			>
				<svelte:fragment slot="trigger" let:selectedLabel>
					<span
						class="inline-flex h-input px-0.5 outline-hidden bg-transparent truncate placeholder-gray-400 focus:outline-hidden"
					>
						{selectedLabel}
					</span>
					<ChevronDown className="size-3.5" strokeWidth="2.5" />
				</svelte:fragment>

				<svelte:fragment slot="item" let:item let:selected>
					{item.label}
					{#if selected}
						<div class="ml-auto">
							<Check />
						</div>
					{/if}
				</svelte:fragment>
			</Select>
		</div>

		{#if filteredGroups.length !== 0}
			<div class="my-2 px-3 grid grid-cols-1 gap-1">
				{#each filteredGroups as group}
					<GroupItem {group} {setGroups} {defaultPermissions} />
				{/each}
			</div>
		{:else}
			<div class="w-full h-full flex flex-col justify-center items-center my-16 mb-24">
				<div class="max-w-md text-center">
					<div class="text-3xl mb-3">👥</div>
					<div class="text-lg font-medium mb-1">{$i18n.t('No groups found')}</div>
					<div class="text-gray-500 text-center text-xs">
						{$i18n.t('Use groups to organize your users and assign permissions.')}
					</div>
				</div>
			</div>
		{/if}
	</div>

	{#if showDefaultPermissionsModal}
		<EditGroupModal
			bind:show={showDefaultPermissionsModal}
			tabs={['permissions']}
			permissions={defaultPermissions}
			custom={false}
			onSubmit={updateDefaultPermissionsHandler}
		/>
	{/if}

	<button
		class="flex items-center justify-between rounded-lg w-full transition mt-4"
		aria-haspopup="dialog"
		on:click={() => {
			showDefaultPermissionsModal = true;
		}}
	>
		<div class="flex items-center gap-2.5">
			<div class="p-1.5 bg-black/5 dark:bg-white/10 rounded-full">
				<UsersSolid className="size-4" />
			</div>

			<div class="text-left">
				<div class=" text-sm font-medium">{$i18n.t('Default permissions')}</div>

				<div class="flex text-xs mt-0.5">
					{$i18n.t('applies to all users with the "user" role')}
				</div>
			</div>
		</div>

		<div>
			<ChevronRight strokeWidth="2.5" />
		</div>
	</button>
{/if}
