package org.texttechnologylab.project.gruppe_05_1.rest;

import gnu.trove.impl.sync.TSynchronizedShortObjectMap;
import io.javalin.http.Context;
import io.javalin.openapi.*;
import org.apache.commons.collections.bag.SynchronizedSortedBag;
import org.texttechnologylab.project.gruppe_05_1.database.MongoPprUtils;
import org.texttechnologylab.project.gruppe_05_1.domain.html.HtmlSpeech;
import org.texttechnologylab.project.gruppe_05_1.domain.html.Parlamentarier;
import org.texttechnologylab.project.gruppe_05_1.domain.html.ParlamentarierDetails;
import org.texttechnologylab.project.gruppe_05_1.domain.speech.SpeechMetaData;
import org.texttechnologylab.project.gruppe_05_1.util.Logger;
import org.texttechnologylab.project.gruppe_05_1.util.PPRUtils;
import org.texttechnologylab.project.gruppe_05_1.xml.speeches.Interfaces.Speech;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FrontEndController {
    @OpenApi(
            summary = "Get alle Parlamentarier. Man kann nach Vor-, Nachname oder Partei filtern.",
            description = "Listet alle Parlamentarier bzw. diejenige, welche den Filter entsprechen",
            operationId = "getAllParlamentarier",
            path = "/",
            methods = HttpMethod.GET,
            tags = {"Parlamentarier"},
            queryParams = {
                    @OpenApiParam(name = "filter", description = "Full-Text-Filter. Kann Vorname, Nachname oder Partei filtern", required = false),
            },
            responses = {
                    @OpenApiResponse(status = "200", content = {@OpenApiContent(from = Parlamentarier[].class)})
            })
    public static void getAllParlamentarier(Context ctx) {
        String filter = ctx.queryParam("filter");
        Logger.info("Filter: '" + filter + "'");

        List<Parlamentarier> parlamentarier = MongoPprUtils.getAllParlamentarier(filter);
        PPRUtils.sortParlamentarierByName(parlamentarier);
        Logger.info(parlamentarier.size() + " MdBs gefunden");

        Map<String, Object> attributes = new HashMap<>();
        attributes.put("parlamentarier", parlamentarier);
        attributes.put("filter", filter);
        ctx.render("parlamentarier.ftl", attributes);
    }

    /**
     * Zeigt die Details eines Parlamentariers an:
     * - persönliche Daten (Geburtsdatum, -ort, Vita, Religion etc.).
     * - Mitgliederschaften, falls vorhanden
     * - Fotos, falls vorhanden
     * @param ctx JavaLin-Context
     */

    @OpenApi(
            summary = "Zeigt die Details eines Parlamentariers an",
            description = "Zeigt persönliche Daten, Mitgliederschaften, Fotos",
            operationId = "getParlamentarierDetails",
            path = "/portfolio/{id}",
            methods = HttpMethod.GET,
            tags = {"Parlamentarier"},
            pathParams = {
                    @OpenApiParam(name = "id", description = "id des Parlamentariers", required = true),
            },
            responses = {
                    @OpenApiResponse(status = "200", content = {@OpenApiContent(from = ParlamentarierDetails.class)})
            })
    public static void getParlamentarierDetails(Context ctx) {
        String id = ctx.pathParam("id");
        Logger.info("getParlamentarierDetails, ID = " + id);

        ParlamentarierDetails pd = MongoPprUtils.getParlamentarierDetailsByID(id);

        Map<String, Object> attributes = new HashMap<>();
        attributes.put("p", pd);
        Long speechCount = MongoPprUtils.countSpeechesOfSpeaker(pd.getId());
        attributes.put("speechesCount", speechCount);
        attributes.put("pic", MongoPprUtils.getMemberPhoto(pd.getId()));
        if (speechCount == 0) {
            attributes.put("speechesPlaceholder", null);
        } else {
            attributes.put("speechesPlaceholder", new ArrayList<>());
        }

        ctx.render("parlamentarierDetails.ftl", attributes);
    }

    /**
     * Liste alle Reden eines Parlamentariers an
     * @param ctx Javalin Context
     */
    @OpenApi(
            summary = "Liste alle Reden eines Parlamentariers an",
            description = "Liste alle Reden eines Parlamentariers an",
            operationId = "listSpeeches",
            path = "/reden/{id}",
            methods = HttpMethod.GET,
            tags = {"Rede"},
            pathParams = {
                    @OpenApiParam(name = "id", description = "id des Parlamentariers", required = true),
            },
            responses = {
                    @OpenApiResponse(status = "200", content = {@OpenApiContent(from = Speech[].class)})
            })
    public static void listSpeeches(Context ctx) {
        String parlamentarierId = ctx.pathParam("id");

        ParlamentarierDetails p = MongoPprUtils.getParlamentarierDetailsByID(parlamentarierId);
        List<SpeechMetaData> speechMetaDataList = MongoPprUtils.getSpeechesMetadataForSpeaker(parlamentarierId);

        Map<String, Object> attributes = new HashMap<>();
        attributes.put("p", p);
        attributes.put("speechesMetaDataList", speechMetaDataList);
        ctx.render("showSpeechesList.ftl", attributes);
    }

    /**
     * Zeige eine bestimmte Rede des Parlamentariers an
     * @param ctx Javalin Context
     */
    @OpenApi(
            summary = "Zeige eine bestimmte Rede des Parlamentariers an",
            description = "Zeige eine bestimmte Rede des Parlamentariers an",
            operationId = "showSpeech",
            path = "/reden/{id}/{redeID}",
            methods = HttpMethod.GET,
            tags = {"Rede"},
            pathParams = {
                    @OpenApiParam(name = "id", description = "id des Parlamentariers", required = true),
                    @OpenApiParam(name = "redeId", description = "id der Rede", required = true),
            },
            responses = {
                    @OpenApiResponse(status = "200", content = {@OpenApiContent(from = Speech.class)})
            })
    public static void showSpeech(Context ctx) {
        String redeId = ctx.pathParam("redeId");

        Map<String, Object> attributes = new HashMap<>();

        HtmlSpeech speech = MongoPprUtils.getSpeechByKey(redeId);
        attributes.put("s", speech);

        ctx.render("speech.ftl", attributes);
    }
}
