import { RelayContext } from "@shared/relayProvider";

import HeartBeatIcon from "@icons/heartbeat";

import { READONLY_RELAYS } from "@stores/constants";
import { hasNewerNoteAtom } from "@stores/note";

import { dateToUnix } from "@utils/date";
import { useActiveAccount } from "@utils/hooks/useActiveAccount";
import { createChat, createNote, updateAccount } from "@utils/storage";
import { getParentID, nip02ToArray } from "@utils/transform";

import { useSetAtom } from "jotai";
import { useContext, useRef } from "react";
import useSWRSubscription from "swr/subscription";

function isJSON(str: string) {
	try {
		JSON.parse(str);
	} catch (e) {
		return false;
	}
	return true;
}

export default function EventCollector() {
	const pool: any = useContext(RelayContext);

	const setHasNewerNote = useSetAtom(hasNewerNoteAtom);
	const now = useRef(new Date());

	const { account, isLoading, isError } = useActiveAccount();

	useSWRSubscription(
		!isLoading && !isError && account ? ["eventCollector", account] : null,
		([, key]) => {
			const follows = JSON.parse(key.follows);
			const followsAsArray = nip02ToArray(follows);
			const unsubscribe = pool.subscribe(
				[
					{
						kinds: [1, 6],
						authors: followsAsArray,
						since: dateToUnix(now.current),
					},
					{
						kinds: [3],
						authors: [key.pubkey],
					},
					{
						kinds: [4],
						"#p": [key.pubkey],
						since: dateToUnix(now.current),
					},
					{
						kinds: [30023],
						since: dateToUnix(now.current),
					},
				],
				READONLY_RELAYS,
				(event: any) => {
					switch (event.kind) {
						// short text note
						case 1: {
							const parentID = getParentID(event.tags, event.id);
							createNote(
								event.id,
								account.id,
								event.pubkey,
								event.kind,
								event.tags,
								event.content,
								event.created_at,
								parentID,
							);
							// notify user reload to get newer note
							setHasNewerNote(true);
							break;
						}
						// contacts
						case 3: {
							const follows = nip02ToArray(event.tags);
							// update account's folllows with NIP-02 tag list
							updateAccount("follows", follows, event.pubkey);
							break;
						}
						// chat
						case 4:
							createChat(
								event.id,
								key.pubkey,
								event.pubkey,
								event.content,
								event.created_at,
							);
							break;
						// repost
						case 6:
							createNote(
								event.id,
								key.id,
								event.pubkey,
								event.kind,
								event.tags,
								event.content,
								event.created_at,
								event.id,
							);
							break;
						// long post
						case 30023: {
							const verifyMetadata = isJSON(event.tags);
							if (verifyMetadata) {
								// insert event to local database
								createNote(
									event.id,
									account.id,
									event.pubkey,
									event.kind,
									event.tags,
									event.content,
									event.created_at,
									"",
								);
							}
							break;
						}
						default:
							break;
					}
				},
			);

			return () => {
				unsubscribe();
			};
		},
	);

	return (
		<div className="inline-flex h-6 w-6 items-center justify-center rounded text-zinc-500 hover:bg-zinc-900 hover:text-green-500">
			<HeartBeatIcon width={16} height={16} />
		</div>
	);
}
