from typing import TypedDict, Optional

from src.internals.database.database import cached_count, cached_query, get_cursor


class TDAnnouncement(TypedDict):
    service: str
    user_id: str
    hash: str
    content: str
    added: str
    published: Optional[str]

def get_artist_announcements(
    service: str, artist_id: str, query: str | None = None, reload: bool = False
) -> list[TDAnnouncement]:
    key = f"announcements:{service}:{artist_id}:{hash(query) if query else ""}"
    params: tuple[str, ...]

    if query:
        cur = get_cursor()
        ts_query = cur.mogrify("AND to_tsvector('english', content) @@ websearch_to_tsquery(%s)", (query,)).decode()
    else:
        ts_query = ""

    if service == "fanbox":
        query = f"""
            SELECT
                user_id,
                hash,
                content,
                added,
                published,
                'fanbox' AS service
            FROM
                fanbox_newsletters
            WHERE
                user_id = %s {ts_query}
            ORDER BY
                published DESC
        """
        params = (artist_id,)
    else:
        query = f"""
            SELECT
                user_id,
                hash,
                content,
                added,
                NULL as published,
                service
            FROM
                introductory_messages
            WHERE
                service = %s
                AND
                user_id = %s {ts_query}
            ORDER BY
                added DESC
        """
        params = (service, artist_id)

    return cached_query(query, key, params, reload=reload)


def get_announcement_count(service: str, artist_id: str, query: str, reload: bool = True):
    key = f"announcement_count:{service}:{artist_id}:{hash(query)}"

    if query:
        cur = get_cursor()
        ts_query = cur.mogrify("AND to_tsvector('english', content) @@ websearch_to_tsquery(%s)", (query,)).decode()
    else:
        ts_query = ""

    if service == "fanbox":
        query = f"SELECT COUNT(1) FROM fanbox_newsletters WHERE user_id = %s {ts_query}"
        params = (artist_id,)
    else:
        query = f"SELECT COUNT(1) FROM introductory_messages WHERE service = %s AND user_id = %s {ts_query}"
        params = (service, artist_id)

    return cached_count(query, key, params, reload)
