package eu.dnetlib.efg1914.various.managers;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import eu.dnetlib.efg1914.authoring.components.Item;
import eu.dnetlib.efg1914.various.locales.MyLocale;
import org.apache.log4j.Logger;

import eu.dnetlib.efg1914.authoring.components.Frame;
import eu.dnetlib.efg1914.authoring.components.Theme;
import eu.dnetlib.efg1914.authoring.components.Topic;
import eu.dnetlib.efg1914.authoring.components.dao.ArchiveDAO;
import eu.dnetlib.efg1914.authoring.components.dao.ConfigurationDAO;
import eu.dnetlib.efg1914.authoring.components.dao.FrameDAO;
import eu.dnetlib.efg1914.authoring.components.dao.ItemDAO;
import eu.dnetlib.efg1914.authoring.components.dao.ThemeDAO;
import eu.dnetlib.efg1914.authoring.components.dao.TopicDAO;
import eu.dnetlib.efg1914.commons.dao.DAOException;
import eu.dnetlib.efg1914.commons.store.XMLStoreException;
import eu.dnetlib.efg1914.various.managers.components.CreditsPage;
import eu.dnetlib.efg1914.various.managers.components.FramePage;
import eu.dnetlib.efg1914.various.managers.components.ItemPage;
import eu.dnetlib.efg1914.various.managers.components.MainPage;
import eu.dnetlib.efg1914.various.managers.components.ThemePage;
import eu.dnetlib.efg1914.various.utils.Aliases;
import eu.dnetlib.efg1914.various.utils.Frames;
import eu.dnetlib.efg1914.various.utils.Themes;

public class PageCreator {
    private static Logger logger = Logger.getLogger(PageCreator.class);

    public static MainPage createMainPage(ConfigurationDAO configurationDao, ThemeDAO themeDao, String configurationName, String locale) {
        logger.debug("Main page for " + configurationName);

        MainPage mainPage = new MainPage();
        try {
            mainPage.setConfiguration(configurationDao.getByName(configurationName));
            if (mainPage.getConfiguration() != null) {
                for (String id : mainPage.getConfiguration().getPublishedThemesOrder()) {
                    mainPage.getThemes().add(themeDao.getById(id));
                }
            }
        } catch (DAOException daoe) {
            logger.error("Cannot get configuration file", daoe);
        }
        JAXBContext jc;
        try {
            jc = JAXBContext.newInstance(Aliases.class);
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            Aliases aliases = (Aliases) unmarshaller.unmarshal(new ByteArrayInputStream(themeDao.getAllAlias().getBytes()));
            mainPage.setAliases(aliases);
        } catch (JAXBException e) {
            e.printStackTrace();
        } catch (XMLStoreException e) {
            e.printStackTrace();
        }
        try {
            MyLocale myLocale = new MyLocale(locale);
            mainPage.setTooltip(myLocale.getValue("mainPage.tooltip"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        return mainPage;
    }

    public static FramePage createFramePage(FrameDAO frameDao, ItemDAO itemDao, String frameId) throws JAXBException {
        logger.debug("Frame page for frame id " + frameId);

        FramePage framePage = new FramePage();
        JAXBContext jc = JAXBContext.newInstance(Frames.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        try {
            Frame frame = frameDao.getById(frameId);
            if (frame != null) {

                framePage.setFrames((Frames) unmarshaller.unmarshal(new ByteArrayInputStream(frameDao.getFrameWithItems(frameId).getBytes())));
            }

        } catch (DAOException daoe) {
            logger.error("Fail to create page for frame " + frameId);
        }
        return framePage;

    }

    public static FramePage createFramePage(ConfigurationDAO configurationDAO, String configurationName,ThemeDAO themeDao, TopicDAO topicDao, FrameDAO frameDao, ItemDAO itemDao, String frameId, String themeId) throws JAXBException {
        logger.debug(" Frame page for frame id " + frameId);
        JAXBContext jc = JAXBContext.newInstance(Frames.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();

        FramePage framePage = new FramePage();
        try {

            Frame frame=frameDao.getByIdOrAlias(frameId);

            if (frame != null) {
                frameId=frame.getId();
                framePage.setFrames((Frames) unmarshaller.unmarshal(new ByteArrayInputStream(frameDao.getFrameWithItems(frameId).getBytes())));
                // framePage.getItems().addAll(itemDao.getFrameItems(frame));
            }

            Theme th = themeDao.getByIdOrAlias(themeId);
            themeId=th.getId();
            framePage.setThemeId(themeId);
            framePage.setThemeAlias(th.getAlias());
            List<String> frameIds = new ArrayList<String>();
            frameIds.add(0, th.getIntroFrameId());

            for (String topicId : th.getTopics()) {
                frameIds.addAll(topicDao.getById(topicId).getFrames());
            }

            int currentFramePosition = frameIds.indexOf(frameId);

            // if (currentFramePosition > 0) {
            // framePage.setPreviousFrame(frameIds.get(currentFramePosition -
            // 1));
            // }
            //
            // if (currentFramePosition < frameIds.size() - 1) {
            // framePage.setNextFrame(frameIds.get(currentFramePosition + 1));
            // }

            if (currentFramePosition > 0) {
                String prevFrameId = frameIds.get(currentFramePosition - 1);
                Frame prevframe = frameDao.getById(prevFrameId);
                if (prevframe.getAlias() != null) {
                    prevFrameId = prevframe.getAlias();
                }
                framePage.setPreviousFrame(prevFrameId);
            }

            if (currentFramePosition < frameIds.size() - 1) {
                String nextFrameId = frameIds.get(currentFramePosition + 1);
                Frame nextframe = frameDao.getById(nextFrameId);
                if (nextframe.getAlias() != null) {
                    nextFrameId = nextframe.getAlias();
                }
                framePage.setNextFrame(nextFrameId);
            }
            framePage.setConfiguration(configurationDAO.getByName(configurationName));
        } catch (DAOException daoe) {
            logger.error("Fail to create page for frame " + frameId);
        } catch (XMLStoreException e) {
            e.printStackTrace();
        }
        return framePage;

    }

    public static ItemPage createItemPage(ConfigurationDAO configurationDAO, String configurationName,ItemDAO itemDao, ThemeDAO themeDao, String itemId, boolean withThemes) {
        logger.debug("Item page for item id " + itemId);

        ItemPage itemPage = new ItemPage();
        try {

            Item item=itemDao.getByIdOrAlias(itemId);
            itemPage.setItem(item);
            itemId=item.getId();
            if (withThemes) {
                itemPage.setTheme(themeDao.getThemeItem(itemId));
            }
            itemPage.setConfiguration(configurationDAO.getByName(configurationName));
        } catch (DAOException daoe) {
            logger.warn("Fail to create item page for item " + itemId, daoe);
        }catch (XMLStoreException e) {
            e.printStackTrace();
        }

        return itemPage;
    }

    public static ThemePage createThemePage(ConfigurationDAO configurationDAO, String configurationName, String themeid, ThemeDAO themeDao, TopicDAO topicDao, FrameDAO frameDao, ItemDAO itemDao) throws JAXBException {
        logger.debug("Theme page for theme id " + themeid);
//        try {
//            JAXBContext jc1;
//
//            jc1 = JAXBContext.newInstance(Aliases.class);
//            Unmarshaller unmarshaller1 = jc1.createUnmarshaller();
//            Aliases aliases = (Aliases) unmarshaller1.unmarshal(new ByteArrayInputStream(themeDao.getAllAlias().getBytes()));
//            if (aliases.getAliasMap().get(themeid) != null) {
//                themeid = aliases.getAliasMap().get(themeid);
//            }
//        } catch (XMLStoreException e1) {
//            e1.printStackTrace();
//        }
        ThemePage themePage = new ThemePage();
        try {
//            Theme theme = themeDao.getById(themeid);
            Theme theme=themeDao.getByIdOrAlias(themeid);
            themeid=theme.getId();
            if (theme != null) {
                logger.debug("Theme page for theme " + theme.getTitle());
                themePage.setTheme(theme);
                List<String> topics = theme.getTopics();
                logger.debug("theme name " + theme.getTitle());
                System.out.println("theme name " + theme.getTitle());
                logger.debug("Frame has topics " + topics);

                JAXBContext jc;

                jc = JAXBContext.newInstance(Frames.class);

                Unmarshaller unmarshaller = jc.createUnmarshaller();

                for (String topicId : topics) {
                    Topic topic = topicDao.getById(topicId);
                    logger.debug("Topic has frames " + topic.getFrames());
                    for (String frameId : topic.getFrames()) {
                        // logger.debug("adding frame page for frame id " +
                        // frameId);
                        // logger.debug(">>>>" +
                        // frameDao.getFrameWithItems(frameId));
                        try {
                            themePage.getFrames().add((Frames) unmarshaller.unmarshal(new ByteArrayInputStream(frameDao.getFrameWithItems(frameId).getBytes())));
                        } catch (JAXBException e) {
                            logger.error("problem!", e);
                        }
                    }
                }

                try {

                    if (theme.getIntroFrameId() != null) {
                        themePage.getFrames().add(0, (Frames) unmarshaller.unmarshal(new ByteArrayInputStream(frameDao.getFrameWithItems(theme.getIntroFrameId()).getBytes())));
                    }

                } catch (JAXBException e) {
                    logger.error("problem!", e);
                }

                for (String themeId : configurationDAO.getByName(configurationName).getPublishedThemesOrder()) {
                    themePage.getCollection().add(themeDao.getById(themeId));
                }

                logger.debug(themePage.getCollection());
            }
        } catch (DAOException daoe) {
            logger.warn("Fail to create theme page for theme " + themeid, daoe);
        } catch (XMLStoreException e) {
            e.printStackTrace();
        }

        return themePage;
    }

    public static CreditsPage createCreditsPage(ConfigurationDAO configurationDao, ArchiveDAO archiveDao, String configurationName) {

        CreditsPage creditsPage = new CreditsPage();
        try {
            creditsPage.setConfiguration(configurationDao.getByName(configurationName));
            // creditsPage.setThemeCredits(new ArrayList<ThemeCredits>());
            // for (String themeId :
            // creditsPage.getConfiguration().getPublishedThemesOrder()) {
            // try {
            // JAXBContext jc;
            // jc = JAXBContext.newInstance(ThemeCredits.class);
            // Unmarshaller unmarshaller = jc.createUnmarshaller();
            // creditsPage.getThemeCredits().add(((ThemeCredits)
            // unmarshaller.unmarshal(new
            // ByteArrayInputStream(configurationDao.getPublishedThemesWithTopics(themeId).getBytes()))));
            //
            // } catch (JAXBException e) {
            // e.printStackTrace();
            // }
            // }
            JAXBContext jc;
            try {
                jc = JAXBContext.newInstance(Themes.class);
                Unmarshaller unmarshaller = jc.createUnmarshaller();
                Themes themes = (Themes) unmarshaller.unmarshal(new ByteArrayInputStream(configurationDao.getPublishedThemesWithTopics().getBytes()));
                creditsPage.setThemeCredits(themes.getThemesCredits());
            } catch (JAXBException e) {

                e.printStackTrace();
            }

            // if (creditsPage.getConfiguration() != null) {
            // //TODO uncomment
            // /*for (String
            // id:mainPage.getConfiguration().getPublishedThemesOrder()){
            // mainPage.getThemes().add(themeDao.getById(id));
            // }*/
            // creditsPage.getArchives().addAll(archiveDao.getAll());
            // }

        } catch (DAOException daoe) {
            logger.error("Cannot get configuration file", daoe);
        }

        return creditsPage;
    }
}
