package org.texttechnologylab.project.gruppe_05_1.domain.html;

import org.bson.Document;
import org.texttechnologylab.project.gruppe_05_1.database.MongoDBHandler;
import org.texttechnologylab.project.gruppe_05_1.database.MongoPprUtils;
import org.texttechnologylab.project.gruppe_05_1.domain.nlp.*;
import org.texttechnologylab.project.gruppe_05_1.domain.speech.SpeechMetaData;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.StringJoiner;

public class HtmlSpeech {
    String                  speechKey;
    String                  speakerName;
    String                  fraction;
    String                  dateTimeString;     // aus "sessions" Collection
    String                  agendaTitle;        // aus "agendaItems" Collection
    List<SpeechContent> content = new ArrayList<>();
    NlpInfo                 nlp = null;

    public HtmlSpeech() {
    }

    public HtmlSpeech(Document doc) {
        setSpeechKey(doc.getString("speechKey"));
        setSpeakerName(doc.getString("speakerName"));
        setFraction(doc.getString("fraction"));

        List<Document> contentDocList = doc.get("speechContents", MongoDBHandler.DOC_LIST_CLASS);
        if (contentDocList == null) {
            setContent(new ArrayList<>());
        } else {
            for (Document contentDoc : contentDocList) {
                addContent(new SpeechContent(contentDoc));
            }
        }

        // ergänzen um Datum, Uhrzeit und Agendapunkt der Rede
        SpeechMetaData md = new SpeechMetaData();
        int sessionId = doc.getInteger("sessionId");
        md.setSessionId(sessionId);
        MongoPprUtils.augmentSpeechMetaDataFromSession(sessionId, md);
        dateTimeString = md.getDateTimeString();

        int agendaItemId = doc.getInteger("agendaItemId");
        String title = MongoPprUtils.getAgendaTitle(sessionId, agendaItemId);
        agendaTitle = title;

        // Ergänzung um NLP-Informationen
        Document nlpDoc = (Document) doc.get("analysisResults");
        nlp = readNlpInfo(nlpDoc);
    }

    private NlpInfo readNlpInfo(Document nlpDoc) {
        if (nlpDoc == null) return null;
        NlpInfo nlp = new NlpInfo();

        // TODO: HERE
        List<Document> tokensDocs = nlpDoc.get("tokens", MongoDBHandler.DOC_LIST_CLASS);
        nlp.setTokens(Token.readTokensFromMongo(tokensDocs));

        List<Document> sentencesDocs = nlpDoc.get("sentences", MongoDBHandler.DOC_LIST_CLASS);

        List<Document> dependenciesDocs = nlpDoc.get("dependencies", MongoDBHandler.DOC_LIST_CLASS);

        List<Document> namedEntitiesDocs = nlpDoc.get("namedEntities", MongoDBHandler.DOC_LIST_CLASS);
        nlp.setNamedEntities(NamedEntity.readNamedEntitiesFromMongo(namedEntitiesDocs));

        List<Document> sentimentDocs = nlpDoc.get("sentiments", MongoDBHandler.DOC_LIST_CLASS);
        nlp.setSentiments(Sentiment.readSentimentsFromMongo((sentimentDocs)));

        List<Document> topicsDocs = nlpDoc.get("topics", MongoDBHandler.DOC_LIST_CLASS);
        nlp.setTopics(Topic.readTopicsFromMongo(topicsDocs));

        // TODO: Video

        return nlp;
    }

    public String getSpeechKey() {
        return speechKey;
    }

    public void setSpeechKey(String speechKey) {
        this.speechKey = speechKey;
    }

    public String getSpeakerName() {
        return speakerName;
    }

    public void setSpeakerName(String speakerName) {
        this.speakerName = speakerName;
    }

    public String getFraction() {
        return fraction;
    }

    public void setFraction(String fraction) {
        this.fraction = fraction;
    }
    public String getDateTimeString() {return dateTimeString;}

    public void setDateTimeString(String dateTimeString) {this.dateTimeString = dateTimeString;}

    public String getAgendaTitle() {return agendaTitle;}

    public void setAgendaTitle(String agendaTitle) {this.agendaTitle = agendaTitle;}

    public List<SpeechContent> getContent() {
        return content;
    }

    public void setContent(List<SpeechContent> content) {
        this.content = content;
    }

    public void addContent(SpeechContent contentLine) {
        content.add(contentLine);
    }

    public NlpInfo getNlp() {
        return nlp;
    }

    public void setNlp(NlpInfo nlp) {
        this.nlp = nlp;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof HtmlSpeech that)) return false;
        return Objects.equals(speechKey, that.speechKey) && Objects.equals(speakerName, that.speakerName)
                && Objects.equals(fraction, that.fraction) && Objects.equals(dateTimeString, that.dateTimeString)
                && Objects.equals(agendaTitle, that.agendaTitle) && Objects.equals(content, that.content)
                && Objects.equals(nlp, that.nlp);
    }

    @Override
    public int hashCode() {
        return Objects.hash(speechKey, speakerName, fraction, dateTimeString, agendaTitle, content, nlp);
    }

    @Override
    public String toString() {
        return new StringJoiner(", ", HtmlSpeech.class.getSimpleName() + "[", "]")
                .add("speechKey='" + speechKey + "'")
                .add("speakerName='" + speakerName + "'")
                .add("fraction='" + fraction + "'")
                .add("dateTimeString='" + dateTimeString + "'")
                .add("agendaTitle='" + agendaTitle + "'")
                .add("content=" + content)
                .add("nlp=" + nlp)
                .toString();
    }
}
