import json
from typing import TYPE_CHECKING, Union

import redis

import jingrow
from jingrow.utils import cstr

if TYPE_CHECKING:
	from jingrow.model.page import Page

queue_prefix = "insert_queue_for_"


def deferred_insert(pagetype: str, records: list[Union[dict, "Page"]] | str):
	if isinstance(records, dict | list):
		_records = json.dumps(records)
	else:
		_records = records

	try:
		jingrow.cache.rpush(f"{queue_prefix}{pagetype}", _records)
	except redis.exceptions.ConnectionError:
		for record in records:
			insert_record(record, pagetype)


def save_to_db():
	queue_keys = jingrow.cache.get_keys(queue_prefix)
	for key in queue_keys:
		record_count = 0
		queue_key = get_key_name(key)
		pagetype = get_pagetype_name(key)
		while jingrow.cache.llen(queue_key) > 0 and record_count <= 500:
			records = jingrow.cache.lpop(queue_key)
			records = json.loads(records.decode("utf-8"))
			if isinstance(records, dict):
				record_count += 1
				insert_record(records, pagetype)
				continue
			for record in records:
				record_count += 1
				insert_record(record, pagetype)


def insert_record(record: Union[dict, "Page"], pagetype: str):
	try:
		record.update({"pagetype": pagetype})
		jingrow.get_pg(record).insert()
	except Exception as e:
		jingrow.logger().error(f"Error while inserting deferred {pagetype} record: {e}")


def get_key_name(key: str) -> str:
	return cstr(key).split("|")[1]


def get_pagetype_name(key: str) -> str:
	return cstr(key).split(queue_prefix)[1]
