<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 {
		REXPRO_NAME,
		config,
		user,
		showSidebar,
		knowledge,
	} from "$lib/stores";
	import { REXPRO_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"
				>
					{groups.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>

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

	<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}
