from __future__ import annotations

import json
from collections.abc import Collection

from generalresearch.models.repdata.question import RepDataQuestion
from generalresearch.sql_helper import SqlHelper


def get_profiling_library(
    sql_helper: SqlHelper,
    country_iso: str | None = None,
    language_iso: str | None = None,
    question_ids: Collection[str] | None = None,
    max_options: int | None = None,
    is_live: bool | None = None,
    pks: Collection[tuple[str, str, str]] | None = None,
) -> list[RepDataQuestion]:
    """
    Accepts lots of optional filters.

    :param country_iso: filters on country_iso field
    :param language_iso: filters on language_iso field
    :param question_ids: filters on question_id field, accepts multiple values
    :param max_options: filters on max_options field
    :param is_live: filters on is_live field
    :param pks: The pk is (question_id, country_iso, language_iso). pks accepts a collection of
        len(3) tuples. e.g. [('123', 'us', 'eng'), ('123', 'us', 'spa')]
    :return:
    """
    filters = []
    params = {}
    if country_iso:
        params["country_iso"] = country_iso
        filters.append("`country_iso` = %(country_iso)s")
    if language_iso:
        params["language_iso"] = language_iso
        filters.append("`language_iso` = %(language_iso)s")
    if question_ids:
        params["question_ids"] = question_ids
        filters.append("lucid_id IN %(question_ids)s")
    if max_options is not None:
        params["max_options"] = max_options
        filters.append("COALESCE(num_options, 0) <= %(max_options)s")
    if is_live is not None:
        params["is_live"] = is_live
        filters.append("is_live = %(is_live)s")
    if pks:
        params["pks"] = pks
        filters.append("(lucid_id, country_iso, language_iso) IN %(pks)s")
    filter_str = " AND ".join(filters)
    filter_str = "WHERE " + filter_str if filter_str else ""
    res = sql_helper.execute_sql_query(
        query=f"""
            SELECT *
            FROM `thl-repdata`.`repdata_question` q
            {filter_str}
        """,
        params=params,
    )
    for x in res:
        x["options"] = json.loads(x["options"]) if x["options"] else None
    qs = [RepDataQuestion.from_db(x) for x in res]
    return qs
