from flask import jsonify, make_response, request

from src.config import Configuration
from src.lib.post import get_artist_posts_full, get_post, get_post_revisions
from src.lib.posts import get_all_posts_for_query, get_all_posts_summary
from src.pages.api.v1 import v1api_bp
from src.pages.artists import do_artist_post_search
from src.utils.utils import get_query_parameters_dict, parse_int, positive_or_none, step_int


@v1api_bp.get("/<service>/user/<creator_id>/posts")
@v1api_bp.get("/<service>/user/<creator_id>")
def list_posts_api(service, creator_id):
    limit = 50
    offset = positive_or_none(step_int(parse_int(request.args.get("o"), 0), limit))
    if offset is None:
        response = make_response(jsonify({"error": "offset not multiple of 50"}), 400)
        return response

    query = request.args.get("q", default="").strip()
    if not query or len(query) < 2:
        posts = get_artist_posts_full(creator_id, service, offset, limit, "published DESC NULLS LAST")
    else:
        (posts, total_count) = do_artist_post_search(creator_id, service, query, offset, limit)
    response = make_response(jsonify(posts), 200)
    return response


@v1api_bp.get("/<service>/user/<creator_id>/post/<post_id>")
def get_post_api(service, creator_id, post_id):
    post = get_post(service, creator_id, post_id)
    if not post or post["user"] != creator_id:
        response = make_response(jsonify({"error": "Not Found"}), 404)
        return response
    response = make_response(jsonify(post), 200)
    return response


@v1api_bp.get("/<service>/user/<creator_id>/post/<post_id>/revisions")
def list_post_revision_api(service, creator_id, post_id):
    revisions = get_post_revisions(service, creator_id, post_id)
    response = make_response(jsonify(revisions), 200 if revisions else 404)
    response.headers["Cache-Control"] = "max-age=600"
    return response


@v1api_bp.route("/posts")
def recent():
    limit = 50
    query_params = get_query_parameters_dict(request, on_errors="ignore", clean_query_string=True)

    extra_pages = Configuration().webserver["extra_pages_to_load_on_posts"]
    max_offset = limit * 1000  # only load 1000 pages of any result
    query = query_params.get("q", "").strip()[: Configuration().webserver["max_full_text_search_input_len"]]
    o = query_params.pop("o", 0)
    offset = positive_or_none(step_int(parse_int(o, 0), limit))
    if offset is None or offset > max_offset:
        response = make_response(jsonify({"error": "offset not multiple of 150 or too large"}), 400)
        return response
    extra_offset = positive_or_none(step_int(parse_int(o, 0), limit * extra_pages))
    slice_offset = offset - extra_offset
    if not query or len(query) < 2:
        extra_results = get_all_posts_summary(extra_offset, limit * extra_pages, cache_ttl=Configuration().cache_ttl_for_recent_posts)[slice_offset : limit + slice_offset]
        # true_count = count_all_posts()
        # count = limit_int(count_all_posts(), max_offset)
    else:
        try:
            extra_results = get_all_posts_for_query(query, extra_offset, limit * extra_pages)
        except Exception as error:
            if "failed to parse expression" not in str(error):
                raise
            query = "Failed to parse query."
            query_params["q"] = query
            extra_results = get_all_posts_for_query(query, extra_offset, limit * extra_pages)

        # count not used
        # if not offset and len(extra_results) < limit:
        #     true_count = 0
        #     count = len(extra_results)
        # else:
        #     try:
        #         true_count = count_all_posts_for_query(query)
        #         count = limit_int(props["true_count"], max_offset)
        #     except Exception as count_error:  # catch timeouts, set count as max offset
        #         logging.exception(
        #             "Caught error in count_all_posts_for_query",
        #             extra={"e": count_error},
        #         )
        #         true_count = 0
        #         count = max_offset

    results = extra_results[slice_offset : limit + slice_offset]
    response = make_response(jsonify(results), 200)
    response.headers["Cache-Control"] = "max-age=60, public, stale-while-revalidate=2592000"
    return response
