import multer from "multer";
import SessionService from "../application/SessionService";
import ActionInteraction from "../domain/ActionInteraction";
import AnswerInteraction from "../domain/AnswerInteraction";
import CommentInteraction from "../domain/CommentInteraction";

const ERROR_STATUS: number = 500;
const SUCCESS_STATUS: number = 200;

export default function attachRoutes(app, sessionService: SessionService): void {

    app.get("/session/ping", (req, res) => {
        res.send("alive");
    });

    app.post("/session/create", (req, res) => {
        const {webSiteId, baseURL} = req.body;
        sessionService.createNewSessionForWebSiteId(webSiteId, baseURL)
        .then((sessionId) => {
            res.json(sessionId);
        })
        .catch((e) => {
            console.log(e);
            res.status(ERROR_STATUS).send(e);
        });
    });

    app.get("/session/:sessionId", (req, res) => {
        const {sessionId} = req.params;
        sessionService.mountSession(sessionId)
        .then((session) => {
            res.json({
                id: session.id,
                baseURL: session.baseURL,
                webSite: session.webSite,
                createdAt: session.createdAt,
                updatedAt: session.updatedAt,
                explorationList: session.explorationList.map((exploration) => {
                    return {
                        testerName: exploration.tester.name,
                        interactionList: exploration.interactionList.map((interaction) => {
                            if (interaction instanceof ActionInteraction) {
                                return {
                                    concreteType: "Action",
                                    index: interaction.index,
                                    kind: interaction.action.kind,
                                    value: interaction.action.value,
                                };
                            }
                            if (interaction instanceof CommentInteraction) {
                                return {
                                    concreteType: "Comment",
                                    index: interaction.index,
                                    kind: interaction.comment.kind,
                                    value: interaction.comment.value,
                                };
                            }
                            if (interaction instanceof AnswerInteraction) {
                                return {
                                    concreteType: "Answer",
                                    index: interaction.index,
                                    kind: interaction.answer.kind,
                                    value: interaction.answer.value,
                                };
                            }
                        }),
                    };
                }),
            });
        })
        .catch( (e) => {
            console.log(e);
            res.status(ERROR_STATUS).send("error");
        });
    });

    app.post("/session/:sessionId/exploration/start",  (req, res) => {
        const {sessionId} = req.params;
        const testerName: string = req.body.testerName;
        sessionService.startExploration(sessionId, testerName)
        .then((explorationNumber) => {
            res.json(explorationNumber);
        })
        .catch( (e) => {
            console.log(e);
            res.status(ERROR_STATUS).send("error");
        });
    });

    app.post("/session/:sessionId/exploration/:explorationNumber/stop",  (req, res) => {
        const {sessionId, explorationNumber} = req.params;
        sessionService.stopExploration(sessionId, explorationNumber)
        .then((exploNumber) => {
            res.json(exploNumber);
        })
        .catch( (e) => {
            console.log(e);
            res.status(ERROR_STATUS).send("error");
        });
    });

    app.post("/session/:sessionId/exploration/add",  (req, res) => {
        const {sessionId} = req.params;
        const {testerName, interactionList} = req.body;
        sessionService.addExploration(sessionId, testerName, interactionList)
        .then((explorationNumber) => {
            res.json(explorationNumber);
        })
        .catch( (e) => {
            console.log(e);
            res.status(ERROR_STATUS).send("error");
        });
    });

    app.post("/session/:sessionId/exploration/continue",  (req, res) => {
        const {sessionId} = req.params;
        const {actionKind, actionValue, explorationNumber} = req.body;
        sessionService.addActionToExploration(sessionId, explorationNumber, actionKind, actionValue)
        .then(() => {
            res.sendStatus(SUCCESS_STATUS);
        })
        .catch( (e) => {
            console.error(e);
            res.status(ERROR_STATUS).send(e);
        });
    });

    app.post("/session/addscreenshotlist",  (req, res) => {
        const {screenshotList} = req.body;
        // console.log('receive comments : ', screenshotList.length);

        const addPromise = screenshotList.map( (screenshot) => sessionService.addScreenshot(screenshot.sessionId, screenshot.explorationNumber, screenshot.interactionIndex, screenshot.image));

        Promise.all(addPromise)
            .then(() => {
                // console.log('screenshot stored');
                res.status(SUCCESS_STATUS).json({nbsaved: screenshotList.length});
            })
            .catch( (e) => {
                console.error(e);
                res.status(ERROR_STATUS).send(e);
            });
    });

    app.post("/session/addvideo/:sessionId/:explorationNumber", multer().single("video"), (req, res) => {
        const {sessionId, explorationNumber} = req.params;
        const video: Express.Multer.File = req.file;
        const fileBuffer: Buffer = video.buffer;
        // console.log('receive comments : ', screenshotList.length);
        console.log("sessionId:", sessionId);
        console.log("explorationNumber:", explorationNumber);
        console.log("video:", video);

        sessionService.addVideo(sessionId, explorationNumber, fileBuffer )
            .then( () => {
                res.status(SUCCESS_STATUS).json({});
            })
            .catch( (e) => {
                console.error(e);
                res.status(ERROR_STATUS).send(e);
            });
    });

    app.get("/session/:sessionId/screenshotlist", (req, res) => {
        const {sessionId} = req.params;

        sessionService.findScreenshotBySession(sessionId)
            .then( (screenshotList) => {
                // console.log('get list', screenshotList);
                res.status(SUCCESS_STATUS).json({screenshotList});
            })
            .catch( (e) => {
                console.error(e);
                res.status(ERROR_STATUS).send(e);
            });
    });

    app.get("/session/:sessionId/videolist", (req, res) => {
        const {sessionId} = req.params;

        sessionService.findVideoBySession(sessionId)
            .then( (videoList) => {
                res.status(SUCCESS_STATUS).json({videoList});
            })
            .catch( (e) => {
                console.error(e);
                res.status(ERROR_STATUS).send(e);
            });
    });

}
