<script lang="ts">
	import { toast } from 'svelte-sonner';
	import { onMount, getContext, tick, onDestroy } from 'svelte';
	const i18n = getContext('i18n');

	import { page } from '$app/stores';
	import { channels, mobile, showSidebar, user } from '$lib/stores';
	import { getUserActiveStatusById } from '$lib/apis/users';
	import { updateChannelById, updateChannelMemberActiveStatusById } from '$lib/apis/channels';
	import { WEBUI_API_BASE_URL } from '$lib/constants';

	import Cog6 from '$lib/components/icons/Cog6.svelte';
	import ChannelModal from './ChannelModal.svelte';
	import Lock from '$lib/components/icons/Lock.svelte';
	import Hashtag from '$lib/components/icons/Hashtag.svelte';
	import Users from '$lib/components/icons/Users.svelte';
	import XMark from '$lib/components/icons/XMark.svelte';
	import Emoji from '$lib/components/common/Emoji.svelte';

	export let onUpdate: Function = () => {};

	export let className = '';
	export let channel;

	let showEditChannelModal = false;

	let itemElement;

	const hasPublicReadGrant = (grants: any) =>
		Array.isArray(grants) &&
		grants.some(
			(grant) =>
				grant?.principal_type === 'user' &&
				grant?.principal_id === '*' &&
				grant?.permission === 'read'
		);

	const isPublicChannel = (channel: any): boolean => {
		if (channel?.type === 'group') {
			if (typeof channel?.is_private === 'boolean') {
				return !channel.is_private;
			}
			return hasPublicReadGrant(channel?.access_grants);
		}
		return hasPublicReadGrant(channel?.access_grants);
	};
</script>

<ChannelModal
	bind:show={showEditChannelModal}
	{channel}
	edit={true}
	{onUpdate}
	onSubmit={async (payload: any) => {
		const { name, is_private, access_grants, group_ids, user_ids } = payload ?? {};
		const res = await updateChannelById(localStorage.token, channel.id, {
			name,
			is_private,
			access_grants,
			group_ids,
			user_ids
		}).catch((error) => {
			toast.error(error.message);
		});

		if (res) {
			toast.success($i18n.t('Channel updated successfully'));
		}

		onUpdate();
	}}
/>

<div
	id="sidebar-channel-item"
	bind:this={itemElement}
	class=" w-full {className} rounded-xl flex relative group hover:bg-gray-100 dark:hover:bg-gray-900 {$page
		.url.pathname === `/channels/${channel.id}`
		? 'bg-gray-100 dark:bg-gray-900 selected'
		: ''} {channel?.type === 'dm' ? 'px-1 py-[3px]' : 'p-1'}  {channel?.unread_count > 0
		? 'font-medium dark:text-white text-black'
		: ' dark:text-gray-400 text-gray-600'} cursor-pointer select-none"
>
	<a
		class=" w-full flex justify-between"
		href="/channels/{channel.id}"
		on:click={() => {
			console.log(channel);

			if ($channels) {
				channels.set(
					$channels.map((ch) => {
						if (ch.id === channel.id) {
							ch.unread_count = 0;
						}
						return ch;
					})
				);
			}

			if ($mobile) {
				showSidebar.set(false);
			}
		}}
		draggable="false"
	>
		<div class="flex items-center gap-1">
			<div>
				{#if channel?.type === 'dm'}
					{#if channel?.users}
						{@const channelMembers = channel.users.filter((u) => u.id !== $user?.id)}
						<div class="flex ml-[1px] mr-0.5 relative">
							{#each channelMembers.slice(0, 2) as u, index}
								<img
									src={`${WEBUI_API_BASE_URL}/users/${u.id}/profile/image`}
									alt={u.name}
									class=" size-5.5 rounded-full border-2 border-white dark:border-gray-900 {index ===
									1
										? '-ml-2.5'
										: ''}"
								/>
							{/each}

							{#if channelMembers.length === 1}
								<div class="absolute bottom-0 right-0">
									<span class="relative flex size-2">
										{#if channelMembers[0]?.is_active}
											<span
												class="absolute inline-flex h-full w-full animate-ping rounded-full bg-green-400 opacity-75"
											></span>
										{/if}
										<span
											class="relative inline-flex size-2 rounded-full {channelMembers[0]?.is_active
												? 'bg-green-500'
												: 'bg-gray-300 dark:bg-gray-700'} border-[1.5px] border-white dark:border-gray-900"
										></span>
									</span>
								</div>
							{/if}
						</div>
					{:else}
						<Users className="size-4 ml-1 mr-0.5" strokeWidth="2" />
					{/if}
				{:else}
					<div class=" size-4 justify-center flex items-center ml-1">
						{#if isPublicChannel(channel)}
							<Hashtag className="size-3.5" strokeWidth="2.5" />
						{:else}
							<Lock className="size-[15px]" strokeWidth="2" />
						{/if}
					</div>
				{/if}
			</div>

			<div
				class=" text-left self-center overflow-hidden w-full line-clamp-1 flex-1 pr-1 flex items-center gap-2.5"
			>
				{#if channel?.name}
					<span class="line-clamp-1">
						{channel.name}
					</span>
				{:else}
					<span class="shrink-0 line-clamp-1">
						{channel?.users
							?.filter((u) => u.id !== $user?.id)
							.map((u) => u.name)
							.join(', ')}
					</span>

					{#if channel?.users?.length === 2}
						{@const dmUser = channel.users.find((u) => u.id !== $user?.id)}

						{#if dmUser?.status_emoji || dmUser?.status_message}
							<span class="flex gap-1.5 line-clamp-1">
								{#if dmUser?.status_emoji}
									<div class=" self-center shrink-0">
										<Emoji className="size-3.5" shortCode={dmUser?.status_emoji} />
									</div>
								{/if}

								<div class="line-clamp-1 italic">
									{dmUser?.status_message}
								</div>
							</span>
						{/if}
					{/if}
				{/if}
			</div>
		</div>

		<div class="flex items-center">
			{#if channel?.unread_count > 0}
				<div
					class="text-xs py-[1px] px-2 rounded-xl bg-gray-100 text-black dark:bg-gray-800 dark:text-white font-medium whitespace-nowrap"
				>
					{new Intl.NumberFormat($i18n.locale, {
						notation: 'compact',
						compactDisplay: 'short'
					}).format(channel.unread_count)}
				</div>
			{/if}
		</div>
	</a>

	{#if ['dm'].includes(channel?.type)}
		<div
			class="ml-0.5 mr-1 invisible group-hover:visible self-center flex items-center dark:text-gray-300"
		>
			<button
				type="button"
				class="p-0.5 dark:hover:bg-gray-850 rounded-lg touch-auto"
				on:click={async (e) => {
					e.stopImmediatePropagation();
					e.stopPropagation();

					channels.update((chs) =>
						chs.filter((ch) => {
							return ch.id !== channel.id;
						})
					);

					await updateChannelMemberActiveStatusById(localStorage.token, channel.id, false).catch(
						(error) => {
							toast.error(`${error}`);
						}
					);
				}}
			>
				<XMark className="size-3.5" />
			</button>
		</div>
	{:else if $user?.role === 'admin' || channel.user_id === $user?.id}
		<div
			class="ml-0.5 mr-1 invisible group-hover:visible self-center flex items-center dark:text-gray-300"
		>
			<button
				type="button"
				class="p-0.5 dark:hover:bg-gray-850 rounded-lg touch-auto"
				on:click={(e) => {
					e.stopImmediatePropagation();
					e.stopPropagation();
					showEditChannelModal = true;
				}}
			>
				<Cog6 className="size-3.5" />
			</button>
		</div>
	{/if}
</div>
