import fetch from "node-fetch";
import config from "../config";
import Action from "../domain/Action";
import ActionInteraction from "../domain/ActionInteraction";
import Comment from "../domain/Comment";
import CommentInteraction from "../domain/CommentInteraction";
import Mapping from "../domain/Mapping";
import Session from "../domain/Session";
import SessionRepository from "../domain/SessionRepository";
import WebSite from "../domain/WebSite";

const WebSiteURL: string = `http://${config.website.host}:${config.website.port}/website/`;
const SessionURL: string = `http://${config.session.host}:${config.session.port}/session/`;

export default class SessionRepositoryREST implements SessionRepository {
    public webSiteName: string;

    public findSessionById(sessionId: string): Promise<Session> {
        const sessionFetch: string = SessionURL + sessionId;
        return fetch(sessionFetch)
            .then( (response) => {
                if (response.ok) {
                    return response.json();
                } else {
                    return Promise.reject("findSessionSite REST error");
                }
            })
            .then( (sessionData) => {
                const session = new Session(sessionData.id, sessionData.baseURL);
                sessionData.explorationList.forEach((explorationData) => {
                    const explorationNumber: number = session.startExploration();
                    const interactionList = explorationData.interactionList
                    .sort( (interA, interB) => interA.index - interB.index)
                    .map((interaction) => {
                        if (interaction.concreteType === "Action") {
                            return new ActionInteraction(interaction.index, new Action(interaction.kind, interaction.value));
                        }
                        if (interaction.concreteType === "Comment") {
                            return new CommentInteraction(interaction.index, new Comment(interaction.kind, interaction.value));
                        }
                    });
                    session.addInteractionListToExploration(explorationNumber, interactionList);
                });

                const websiteFetch: string = WebSiteURL + sessionData.webSite.id;
                return fetch(websiteFetch)
                    .then( (response) => {
                        if (response.ok) {
                            return response.json();
                        } else {
                            return Promise.reject("findWebSite REST error");
                        }
                    })
                    .then( (webSiteData) => {
                        const webSite = new WebSite(webSiteData.id, webSiteData.name);
                        webSiteData.mappingList.forEach((mappingData) => {
                            webSite.addMapping(new Mapping(mappingData.match, mappingData.output));
                        });
                        session.webSite = webSite;
                        return session;
                    });
            });
    }

}
