package eu.dnetlib.uoaadmintoolslibrary.services;

import eu.dnetlib.uoaadmintoolslibrary.dao.DivIdDAO;
import eu.dnetlib.uoaadmintoolslibrary.entities.DivId;
import eu.dnetlib.uoaadmintoolslibrary.entities.Page;
import eu.dnetlib.uoaadmintoolslibrary.entities.Portal;
import eu.dnetlib.uoaadmintoolslibrary.entities.fullEntities.DivHelpContentResponse;
import eu.dnetlib.uoaadmintoolslibrary.entities.fullEntities.DivIdResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class DivIdService {
    private final Logger log = Logger.getLogger(this.getClass());

    @Autowired
    private DivIdDAO divIdDAO;

    @Autowired
    private PageService pageService;

    @Autowired
    private PortalService portalService;

    @Autowired
    private DivHelpContentService divHelpContentService;

    public List<DivId> getDivIds(String page, String name, String pid) {
        List<DivId> divIds = null;

        if(page != null && name != null && pid != null) {
            Portal portal = portalService.getPortal(pid);
            if(portal == null) {
                return null;
            }
            String portalType = portal.getType();

            DivId divId = divIdDAO.findByPagesContainingAndNameAndPortalType(page, name, portalType);
            if(divId != null) {
                divIds = new ArrayList<>();
                divIds.add(divId);
            }
        }
        else if(page != null && name != null) {
            DivId divId = divIdDAO.findByPagesContainingAndName(page, name);
            if(divId != null) {
                divIds = new ArrayList<>();
                divIds.add(divId);
            }
        } else if(page != null && pid != null) {
            Portal portal = portalService.getPortal(pid);
            if(portal == null) {
                return null;
            }
            String portalType = portal.getType();
            divIds = divIdDAO.findByPagesContainingAndPortalType(page, portalType);
        } else if(name != null && pid != null) {
            Portal portal = portalService.getPortal(pid);
            if(portal == null) {
                return null;
            }

            String portalType = portal.getType();

            DivId divId = divIdDAO.findByNameAndPortalType(name, portalType);
            if(divId != null) {
                divIds = new ArrayList<>();
                divIds.add(divId);
            }
        } else if(page != null) {
            divIds = divIdDAO.findByPagesContaining(page);
        } else if(name != null) {
            divIds = divIdDAO.findByName(name);
        } else if(pid != null) {
            Portal portal = portalService.getPortal(pid);
            if(portal == null) {
                return null;
            }
            String portalType = portal.getType();
            divIds = divIdDAO.findByPortalType(portalType);
        } else {
            divIds = divIdDAO.findAll();
        }

//        if(portalType != null) {
//            Iterator<DivId> iteratorDivIds = divIds.iterator();
//            while(iteratorDivIds.hasNext()) {
//                DivId divId = iteratorDivIds.next();
//                if (!portalType.equals(divId.getPortalType())) {
//                    iteratorDivIds.remove();
//                }
//            }
//        }

        return divIds;
    }

    public List<DivId> getDivIdsByPortalType(String portalType) {
        if (portalType == null) {
            return null;
        }
        return divIdDAO.findByPortalType(portalType);
    }

    public List<DivIdResponse> getDivIdsFull(String page, String name, String pid) {
        List<DivId> divIds = this.getDivIds(page, name, pid);
        if(divIds == null) {
            return null;
        }

        List<DivIdResponse> divIdResponses = new ArrayList<>();
        for(DivId divId : divIds) {
            DivIdResponse divIdResponse = new DivIdResponse(divId);
            List<Page> pages = new ArrayList<>();
            for(String pageId : divId.getPages()) {
                pages.add(pageService.getPage(pageId));
            }
            divIdResponse.setPages(pages);

            divIdResponses.add(divIdResponse);
        }

        return divIdResponses;
    }

//    public DivId getDivIdByName(String name) {
//        return divIdDAO.findByName(name);
//    }

    public DivId getDivId(String id) {
        return divIdDAO.findById(id);
    }

    public DivIdResponse getDivIdFull(String id) {
        DivId divId = divIdDAO.findById(id);
        return divIdResponseFromDivId(divId);
    }

    public DivIdResponse divIdResponseFromDivId(DivId divId) {
        DivIdResponse divIdResponse = new DivIdResponse(divId);
        List<Page> pages = new ArrayList<>();
        for(String pageId : divId.getPages()) {
            pages.add(pageService.getPage(pageId));
        }
        divIdResponse.setPages(pages);
        return divIdResponse;
    }

    public void deleteAllDivIds() {
        divIdDAO.deleteAll();
    }

    public DivId insertOrUpdateDivId(DivId divId) {
        return divIdDAO.save(divId);
    }

    public DivIdResponse insertDivId(DivIdResponse divIdResponse) {
        DivId divId = this.getDivIdByDivIdResponse(divIdResponse);

        DivId savedDivId = divIdDAO.save(divId);
        divIdResponse.setId(savedDivId.getId());

        return this.getDivIdFull(divId.getId());
    }

    private DivId getDivIdByDivIdResponse(DivIdResponse divIdResponse) {
        DivId divId = new DivId();
        divId.setId(divIdResponse.getId());
        divId.setName(divIdResponse.getName());
        divId.setPortalType(divIdResponse.getPortalType());

        List<Page> fullPages = divIdResponse.getPages();
        List<String> pages = new ArrayList<String>();
        for(Page page : fullPages) {
            pages.add(page.getId());
        }
        divId.setPages(pages);

        return divId;
    }

    public DivIdResponse updateDivId(DivIdResponse divIdResponse) {
//        DivId divIdOld = divIdDAO.findById(divIdResponse.getId());
//        DivId divId = this.getDivIdByDivIdResponse(divIdResponse);
//        divIdDAO.save(divId);
//
//        boolean openaireEnabled = divId.getOpenaire();
//        boolean connectEnabled = divId.getConnect();
//
//        if(divId.getCommunities() && !divIdOld.getCommunities()) {
//            List<Portal> communities = communityController.getAllPortals();
//            for( Portal community : communities ) {
//                if(!community.getPid().equals("openaire") && !community.getPid().equals("connect")) {
//                    divHelpContentService.addDivHelpContentsInPortal(community.getPid(), community.getId(), divId.getName());
//                }
//            }
//        }
//        if(openaireEnabled && !divIdOld.getOpenaire()) {
//            Portal community = communityController.getPortal("openaire");
//            divHelpContentService.addDivHelpContentsInPortal(community.getPid(), community.getId(), divId.getName());
//        }
//
//        if(connectEnabled && !divIdOld.getConnect()) {
//            Portal community = communityController.getPortal("connect");
//            divHelpContentService.addDivHelpContentsInPortal(community.getPid(), community.getId(), divId.getName());
//        }
//
//        if(!divId.getCommunities()) {
//            List<Portal> communities = communityController.getAllPortals();
//            for( Portal community : communities ) {
//                if(!community.getPid().equals("openaire") && !community.getPid().equals("connect")) {
//                    // delete div contents related to this divId
//                    List<DivHelpContentResponse> divHelpContentResponses = divHelpContentService.getDivHelpContents(community.getPid(), null, divId.getName(), null);
//                    for(DivHelpContentResponse divHelpContentResponse : divHelpContentResponses) {
//                        divHelpContentService.deleteDivHelpContent(divHelpContentResponse.getId());
//                    }
//                }
//            }
//        }
//
//        if(!openaireEnabled) {
//            Portal community = communityController.getPortal("openaire");
//
//            // delete div contents related to this divId
//            List<DivHelpContentResponse> divHelpContentResponses = divHelpContentService.getDivHelpContents("openaire", null, divId.getName(), null);
//            for(DivHelpContentResponse divHelpContentResponse : divHelpContentResponses) {
//                divHelpContentService.deleteDivHelpContent(divHelpContentResponse.getId());
//            }
//        }
//
//        if(!connectEnabled) {
//            Portal community = communityController.getPortal("connect");
//
//            // delete div contents related to this divId
//            List<DivHelpContentResponse> divHelpContentResponses = divHelpContentService.getDivHelpContents("connect", null, divId.getName(), null);
//            for(DivHelpContentResponse divHelpContentResponse : divHelpContentResponses) {
//                divHelpContentService.deleteDivHelpContent(divHelpContentResponse.getId());
//            }
//        }

        DivId divId = this.getDivIdByDivIdResponse(divIdResponse);
        divIdDAO.save(divId);

        return divIdResponse;
    }

    public Boolean deleteDivIds(List<String> divIds) throws Exception {
        for (String id: divIds) {
            // delete div contents related to this divId
            List<DivHelpContentResponse> divHelpContentResponses = divHelpContentService.getDivHelpContents(null, null, id, null);
            for(DivHelpContentResponse divHelpContentResponse : divHelpContentResponses) {
                divHelpContentService.deleteDivHelpContent(divHelpContentResponse.getId());
            }

            divIdDAO.delete(id);
        }
        return true;
    }

    public void deleteDivId(String id) {
        divIdDAO.delete(id);
    }

    public Set<String> getDivIdsPages(String pid) {
        List<DivId> divIds = null;
        Set<String> hasPortalPageDivIds = new HashSet<>();

        if(pid != null) {
            Portal portal = portalService.getPortal(pid);
            if(portal == null) {
                return null;
            }
            String portalType = portal.getType();
            divIds = divIdDAO.findByPortalType(portalType);
        } else {
            divIds = divIdDAO.findAll();
        }

        for(DivId divId : divIds) {
            for(String pageId : divId.getPages()) {
                hasPortalPageDivIds.add(pageId);
            }
        }
        return hasPortalPageDivIds;
    }

}