package eu.dnetlib.uoaadmintools.controllers;

import com.sun.org.apache.xpath.internal.operations.Div;
import eu.dnetlib.uoaadmintools.dao.CommunityDAO;
import eu.dnetlib.uoaadmintools.dao.DivIdDAO;
import eu.dnetlib.uoaadmintools.dao.PageDAO;
import eu.dnetlib.uoaadmintools.entities.*;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@RestController
@CrossOrigin(origins = "*")
public class DivIdController {
    private final Logger log = Logger.getLogger(this.getClass());

    @Autowired
    private DivIdDAO divIdDAO;

    @Autowired
    private CommunityDAO communityDAO;

    @Autowired
    private PageDAO pageDAO;

    @Autowired
    private DivHelpContentController divHelpContentController;

    DivIdController() {}

    @RequestMapping(value = "/div", method = RequestMethod.GET)
    public List<DivId> getDivIds(@RequestParam(required = false) String community,
                                 @RequestParam(required = false) String page,
                                 @RequestParam(required = false) String name) {
        List<DivId> divIds = null;
        String communityId = null;
        if(community != null) {
            communityId = communityDAO.findByPid(community).getId();
        }

        if(community != null && page != null && name != null) {
            divIds = divIdDAO.findByCommunityAndPagesContainingAndName(communityId, page, name);
        } else if(community != null && page != null) {
            divIds = divIdDAO.findByCommunityAndPagesContaining(communityId, page);
        } else if(community != null && name != null) {
            divIds = divIdDAO.findByCommunityAndName(communityId, name);
        } else if(page != null && name != null) {
            divIds = divIdDAO.findByPagesContainingAndName(page, name);
        } else if(community != null) {
            divIds = divIdDAO.findByCommunity(communityId);
        } else if(page != null) {
            divIds = divIdDAO.findByPagesContaining(page);
        } else if(name != null) {
            divIds = divIdDAO.findByName(name);
        } else {
            divIds = divIdDAO.findAll();
        }
        return divIds;
    }

    @RequestMapping(value = "/divFull", method = RequestMethod.GET)
    public List<DivIdResponse> getDivIdsFull(@RequestParam(required = false) String community,
                                             @RequestParam(required = false) String page,
                                             @RequestParam(required = false) String name) {

        List<DivId> divIds = this.getDivIds(community, page, name);

        List<DivIdResponse> divIdResponses = new ArrayList<>();
        for(DivId divId : divIds) {
            DivIdResponse divIdResponse = new DivIdResponse(divId);
            divIdResponse.setCommunity(communityDAO.findById(divId.getCommunity()));
            List<Page> pages = new ArrayList<>();
            for(String pageId : divId.getPages()) {
                pages.add(pageDAO.findById(pageId));
            }
            divIdResponse.setPages(pages);

            divIdResponses.add(divIdResponse);
        }

        return divIdResponses;
    }

    @RequestMapping(value = "/div/{id}", method = RequestMethod.GET)
    public DivId getDivId(@PathVariable(value = "id") String id) {
        return divIdDAO.findById(id);
    }

    @RequestMapping(value = "/divFull/{id}", method = RequestMethod.GET)
    public DivIdResponse getDivIdFull(@PathVariable(value = "id") String id) {
        DivId divId = divIdDAO.findById(id);
        DivIdResponse divIdResponse = new DivIdResponse(divId);
        divIdResponse.setCommunity(communityDAO.findById(divId.getCommunity()));
        List<Page> pages = new ArrayList<>();
        for(String pageId : divId.getPages()) {
            pages.add(pageDAO.findById(pageId));
        }
        divIdResponse.setPages(pages);
        return divIdResponse;
    }

    @RequestMapping(value = "/div", method = RequestMethod.DELETE)
    public void deleteAllDivIds() {
        divIdDAO.deleteAll();
    }

    @RequestMapping(value = "/div/save", method = RequestMethod.POST)
    public DivIdResponse insertDivId(@RequestBody DivId divId) {
        String community_id = communityDAO.findByPid(divId.getCommunity()).getId();
        divId.setCommunity(community_id);
        divIdDAO.save(divId);
        return this.getDivIdFull(divId.getId());
    }

    @RequestMapping(value = "/div/update", method = RequestMethod.POST)
    public DivIdResponse updateDivId(@RequestBody DivId _divId) {
        DivId divId = divIdDAO.findById(_divId.getId());
        divId.setName(_divId.getName());
        /*List<String> pageIds = new ArrayList<>();
        for(Page page : divIdResponse.getPages()) {
            pageIds.add(page.getId());
        }*/
        divId.setPages(_divId.getPages());
        divIdDAO.save(divId);
        return this.getDivIdFull(divId.getId());
    }

    @RequestMapping(value = "/div/delete", method = RequestMethod.POST)
    public Boolean deleteDivIds(@RequestBody List<String> divIds) throws Exception {
        for (String id: divIds) {
            DivId divId = divIdDAO.findById(id);

            Community community = communityDAO.findById(divId.getCommunity());

            // delete div contents related to this divId
            List<DivHelpContentResponse> divHelpContentResponses = divHelpContentController.getDivHelpContents(community.getPid(), null, divId.getName(), null);
            for(DivHelpContentResponse divHelpContentResponse : divHelpContentResponses) {
                divHelpContentController.deleteDivHelpContent(divHelpContentResponse.getId());
            }

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

    @RequestMapping(value = "/div/{id}", method = RequestMethod.DELETE)
    public void deleteDivId(@PathVariable(value = "id") String id) {
        divIdDAO.delete(id);
    }

    @RequestMapping(value = "/div/pages", method = RequestMethod.GET)
    public Map<String, Set<String>> getDivIdsPages(@RequestParam(required = false) String community) {
        List<DivId> divIds = null;
        Map<String, Set<String>> hasCommunityPageDivIds = new HashMap<>();
        if(community != null) {
            String communityId = communityDAO.findByPid(community).getId();
            divIds = divIdDAO.findByCommunity(communityId);
        } else {
            divIds = divIdDAO.findAll();
        }

        for(DivId divId : divIds) {
            String communityPid;
            if(community == null) {
                communityPid = communityDAO.findById(divId.getCommunity()).getPid();
            } else {
                communityPid = community;
            }

            if(hasCommunityPageDivIds.containsKey(communityPid)) {
                for(String pageId : divId.getPages()) {
                    hasCommunityPageDivIds.get(communityPid).add(pageId);
                }
            } else {
                hasCommunityPageDivIds.put(communityPid, new HashSet<>());
                for(String pageId : divId.getPages()) {
                    hasCommunityPageDivIds.get(communityPid).add(pageId);
                }
            }
        }
        return hasCommunityPageDivIds;
    }

}
