package com.yizhi.application.protal.controller;

import java.util.*;

import com.yizhi.assignment.application.feign.AssignmentStudentClient;
import com.yizhi.assignment.application.vo.apivo.ToOthersApi;
import com.yizhi.core.application.context.ContextHolder;
import com.yizhi.core.application.context.RequestContext;
import com.yizhi.course.application.feign.CourseClient;
import com.yizhi.course.application.vo.ApiSeachCourseVo;
import com.yizhi.course.application.vo.HomePageCoursePageVo;
import com.yizhi.exam.application.feign.MyExamClient;
import com.yizhi.exam.application.vo.MyExamVO;
import com.yizhi.exam.application.vo.exam.MyExamPageVO;
import com.yizhi.live.application.feign.LiveActivityClient;
import com.yizhi.live.application.vo.PageLiveVo;
import com.yizhi.research.application.feign.ResearchClient;
import com.yizhi.research.application.vo.api.SearchVo;
import com.yizhi.research.application.vo.domain.ResearchVo;
import com.yizhi.site.application.feign.InformationStudentFeignClients;
import com.yizhi.site.application.vo.domain.InformationVo;
import com.yizhi.site.application.vo.site.InfomationParamVO;
import com.yizhi.site.application.vo.site.PortalHomeSearchVO;
import com.yizhi.training.application.feign.TrainingProjectClient;
import com.yizhi.training.application.model.BaseModel;
import com.yizhi.training.application.vo.api.TrainingProjectListVo;
import com.yizhi.training.application.vo.api.TrainingProjectParamVo;
import com.yizhi.util.application.domain.Response;
import com.yizhi.wechat.application.vo.wechat.Constants;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.plugins.Page;
import com.yizhi.application.protal.constant.SiteEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiParam;

/**
 * 首页搜索
 *
 * @author admin
 * @date 2018
 */
@Api(tags = "门户学员端 首页搜索", description = "门户学员端 首页搜索")
@RestController
@RequestMapping("/api/portal")
public class PortalHomeSearchController {

    private static final Logger LOG = LoggerFactory.getLogger(PortalHomeSearchController.class);

    @Autowired
    private TrainingProjectClient projectClient;
    @Autowired
    private CourseClient courseClient;
    @Autowired
    private LiveActivityClient liveClient;
    @Autowired
    private ResearchClient researchClient;
    @Autowired
    private AssignmentStudentClient assignmentClient;
    @Autowired
    private InformationStudentFeignClients infoClient;
    @Autowired
    private MyExamClient myExamClient;

    @GetMapping("/site/home/search")
    public Response<Page<PortalHomeSearchVO>> homeSearch(
            @ApiParam(name = "keyword", value = "搜索关键字", required = true) String keyword,
            @ApiParam(name = "pageNo", value = "开始", required = true) @RequestParam(defaultValue = "1") Integer pageNo,
            @ApiParam(name = "pageSize", value = "数量", required = true) @RequestParam(defaultValue = "10") Integer pageSize) {
        if (StringUtils.isBlank(keyword)) {
            return Response.fail("请输入关键字");
        }
        RequestContext context = ContextHolder.get();
        LOG.info("======context："+context);
        List<PortalHomeSearchVO> retList = new ArrayList<PortalHomeSearchVO>();
        //培训项目  搜索
        List<PortalHomeSearchVO> projectList = null;
        TrainingProjectParamVo projectVo = new TrainingProjectParamVo();
        projectVo.setKeyword(keyword);
        projectVo.setNow(new Date());
        projectVo.setPageNo(Constants.YES_FLAG);
        projectVo.setPageSize(99999);
        BaseModel<TrainingProjectParamVo> model = new BaseModel<>();
        model.setContext(context);
        model.setDate(new Date());
        model.setObj(projectVo);
        Page<TrainingProjectListVo> apiProjectList = null;
        try {
            LOG.info("传的参数："+model);
            apiProjectList = projectClient.apiPageList(model);

            LOG.info("返回的参数："+apiProjectList);
            LOG.info("返回的结果的长度："+apiProjectList.getRecords().size());
        } catch (Exception e) {
            LOG.error("培训项目搜索异常" + e.getLocalizedMessage());
        }
        if (apiProjectList != null) {
            projectList = formatProject(apiProjectList.getRecords());
            LOG.info("培训项目的长度：" + projectList.size());
            retList.addAll(projectList);
        }
        //课程搜索
        List<PortalHomeSearchVO> courseList = new ArrayList<>();
        ApiSeachCourseVo searchCourseVo = new ApiSeachCourseVo();
        searchCourseVo.setName(keyword);
        searchCourseVo.setAccountId(context.getAccountId());
        searchCourseVo.setType(1);
        searchCourseVo.setCompanyId(context.getCompanyId());
        searchCourseVo.setSiteId(context.getSiteId());
        searchCourseVo.setPageNo(1);
        searchCourseVo.setPageSize(99999);
        if (context.getRelationIds() != null) {
            List<HomePageCoursePageVo> apiCourseList = null;
            searchCourseVo.setIds(context.getRelationIds());
            try {
                apiCourseList = courseClient.hotList(searchCourseVo);
            } catch (Exception e) {
                LOG.error("课程搜索异常：" + e.getLocalizedMessage());
            }
            if (CollectionUtils.isNotEmpty(apiCourseList)) {
                courseList = formatCourse(apiCourseList);
                LOG.info("课程的长度：" + courseList.size());
                retList.addAll(courseList);
            }
        }
        // 直播 搜索
        List<PortalHomeSearchVO> liveList = new ArrayList<>();
        if (context.getRelationIds() != null) {
            List<PageLiveVo> searchLiveList = null;
            try {
                searchLiveList = liveClient.apiList(keyword, context.getCompanyId(), context.getSiteId(),
                        context.getRelationIds(), 1, 99999);
            } catch (Exception e) {
                LOG.error("直播搜索异常：" + e.getLocalizedMessage());
            }
            if (CollectionUtils.isNotEmpty(searchLiveList)) {
                liveList = formatLive(searchLiveList);
                LOG.info("直播的长度：" + liveList.size());
                retList.addAll(liveList);
            }
        }
        //考试 搜索
        // add @ 2018-6-28 19:36:45
        List<Long> ids = context.getRelationIds();
        if (null == ids) {
            ids = new ArrayList<Long>();
            ids.add(context.getAccountId());
        }
        List<PortalHomeSearchVO> examList = null;

        List<MyExamVO> examVOS = new ArrayList<>();
        MyExamPageVO myExamPageVO = null;
        try {
            myExamPageVO = myExamClient.searchMyExamInfo(keyword, 1, 99999, context.getAccountId(), context.getSiteId(), ids);
            LOG.info("考试搜索的结果："+myExamPageVO);
            if (myExamPageVO != null) {
                examVOS = myExamPageVO.getExamVOS();
            }

        } catch (Exception e) {
            LOG.error("考试 搜索 =" + e.getLocalizedMessage());
        }
        if (CollectionUtils.isNotEmpty(examVOS)) {
            examList = formatExam(examVOS);
            LOG.info("examList的长度" + examList.size());
            retList.addAll(examList);
        }
        //调研 搜索
        List<PortalHomeSearchVO> researchList = new ArrayList<>();
        SearchVo searchVo = new SearchVo();
        searchVo.setName(keyword);
        searchVo.setContext(context);
        searchVo.setPageNo(1);
        searchVo.setPageSize(99999);
        Page<ResearchVo> apiSearchPage = null;
        try {
            apiSearchPage = researchClient.apiSearchPage(searchVo);
        } catch (Exception e) {
            LOG.error("调研搜索异常" + e.getLocalizedMessage());
        }
        if (apiSearchPage != null) {
            List<ResearchVo> searchResearchList = apiSearchPage.getRecords();
            if (CollectionUtils.isNotEmpty(searchResearchList)) {
                researchList = formatResearch(searchResearchList);
                LOG.info("researchList的长度：" + researchList.size());
                retList.addAll(researchList);
            }
        }
        //作业 搜索      state
        List<PortalHomeSearchVO> assignmentList = new ArrayList<>();
        if (context.getRelationIds() != null) {

            List<ToOthersApi> searchAssignmentList = null;
            try {
                searchAssignmentList = assignmentClient.listSearchOthers(keyword, 1, 99999, context.getAccountId(), context.getRelationIds(), context.getSiteId());
            } catch (Exception e) {
                LOG.error("作业 搜索异常：" + e.getLocalizedMessage());
            }
            if (CollectionUtils.isNotEmpty(searchAssignmentList)) {
                assignmentList = formatAssignment(searchAssignmentList);
                LOG.info("作业的长度：" + assignmentList.size());
                retList.addAll(assignmentList);
            }
        }
        // 新闻公告 搜索
        List<PortalHomeSearchVO> newsList = new ArrayList<>();
        InfomationParamVO vo = new InfomationParamVO();
        vo.setContext(context);
        vo.setFileName(keyword);
        vo.setPageNo(1);
        vo.setPageSize(99999);
        Page<InformationVo> searchInfoList = null;
        try {
            searchInfoList = infoClient.searchInformation(vo);
        } catch (Exception e) {
            LOG.error("新闻公告 搜索 =" + e.getLocalizedMessage());
        }
        if (searchInfoList != null) {
            List<InformationVo> records = searchInfoList.getRecords();
            if (CollectionUtils.isNotEmpty(records)) {
                newsList = formatInfo(records);
                LOG.info("新闻公告的长度：" + newsList.size());
                retList.addAll(newsList);
            }
        }
        LOG.info("最终的list的长度："+retList.size());
        Map<String,Object> recordMap = getPagingResultMap(retList,pageNo,pageSize);

        return Response.ok(recordMap);
    }

    /**
     * 考试数据格式化
     *
     * @param examVOS
     * @return
     */
    private List<PortalHomeSearchVO> formatExam(List<MyExamVO> examVOS) {
        List<PortalHomeSearchVO> list = new ArrayList<PortalHomeSearchVO>();
        PortalHomeSearchVO vo = null;
        for (MyExamVO e : examVOS) {
            vo = new PortalHomeSearchVO();
            vo.setKind(SiteEnum.DETAIL.getValue());
            vo.setType(SiteEnum.EXAM.getValue());
            vo.setId(e.getId());
            vo.setTitle(e.getName());
            vo.setStartDate(e.getStartTime());
            vo.setEndDate(e.getEndTime());
            vo.setState(e.getState());
            list.add(vo);
        }
        return list;
    }

    /**
     * 新闻公告数据格式化
     *
     * @param records
     * @return
     */
    private List<PortalHomeSearchVO> formatInfo(List<InformationVo> records) {
        List<PortalHomeSearchVO> list = new ArrayList<PortalHomeSearchVO>();
        PortalHomeSearchVO vo = null;
        for (InformationVo info : records) {
            vo = new PortalHomeSearchVO();
            vo.setKind(SiteEnum.DETAIL.getValue());
            vo.setType(SiteEnum.NEWS.getValue());
            vo.setId(info.getId());
            vo.setTitle(info.getFileName());
            vo.setStartDate(info.getReleaseTime());
            vo.setImgUrl(info.getLogoPath());
            vo.setTeacher(info.getAuthor());
            vo.setState(info.getState());
            list.add(vo);
        }
        return list;
    }

    /**
     * 作业数据格式化
     *
     * @param searchAssignmentList
     * @return
     */
    private List<PortalHomeSearchVO> formatAssignment(List<ToOthersApi> searchAssignmentList) {
        List<PortalHomeSearchVO> list = new ArrayList<PortalHomeSearchVO>();
        PortalHomeSearchVO vo = null;
        for (ToOthersApi ass : searchAssignmentList) {
            vo = new PortalHomeSearchVO();
            vo.setKind(SiteEnum.DETAIL.getValue());
            vo.setType(SiteEnum.HOMEWORK.getValue());
            vo.setId(ass.getId());
            vo.setTitle(ass.getName());
            vo.setStartDate(ass.getStartTime());
            vo.setEndDate(ass.getEndTime());
            vo.setUrl(ass.getUrl());
            vo.setState(ass.getState());
            list.add(vo);
        }
        return list;
    }

    /**
     * 调研 数据格式化
     *
     * @param searchResearchList
     * @return
     */
    private List<PortalHomeSearchVO> formatResearch(List<ResearchVo> searchResearchList) {
        List<PortalHomeSearchVO> list = new ArrayList<PortalHomeSearchVO>();
        PortalHomeSearchVO vo = null;
        for (ResearchVo re : searchResearchList) {
            vo = new PortalHomeSearchVO();
            vo.setKind(SiteEnum.DETAIL.getValue());
            vo.setType(SiteEnum.SURVEY.getValue());
            vo.setId(re.getId());
            vo.setTitle(re.getName());
            vo.setStartDate(re.getStartTime());
            vo.setEndDate(re.getEndTime());
            vo.setState(re.getState());
            list.add(vo);
        }
        return list;
    }

    /**
     * 直播数据格式
     *
     * @param searchLiveList
     * @return
     */
    private List<PortalHomeSearchVO> formatLive(List<PageLiveVo> searchLiveList) {
        List<PortalHomeSearchVO> list = new ArrayList<PortalHomeSearchVO>();
        PortalHomeSearchVO vo = null;
        for (PageLiveVo liveVo : searchLiveList) {
            vo = new PortalHomeSearchVO();
            vo.setKind(SiteEnum.DETAIL.getValue());
            vo.setType(SiteEnum.LIVE.getValue());
            vo.setId(liveVo.getId());
            vo.setTitle(liveVo.getTitle());
            vo.setStartDate(liveVo.getStartTime());
            vo.setEndDate(liveVo.getEndTime());
            vo.setImgUrl(liveVo.getLogoImage());
            vo.setUrl(liveVo.getChannel());
            vo.setTeacher(liveVo.getAnchor());
            list.add(vo);
        }
        return list;
    }

    /**
     * 课程数据格式
     *
     * @param apiCourseList
     * @return
     */
    public List<PortalHomeSearchVO> formatCourse(List<HomePageCoursePageVo> apiCourseList) {
        List<PortalHomeSearchVO> list = new ArrayList<PortalHomeSearchVO>();
        PortalHomeSearchVO vo = null;
        for (HomePageCoursePageVo course : apiCourseList) {
            vo = new PortalHomeSearchVO();
            vo.setKind(SiteEnum.DETAIL.getValue());
            vo.setType(SiteEnum.COURSE.getValue());
            vo.setId(course.getCourseId());
            vo.setTitle(course.getName());
            vo.setStartDate(course.getStartTime());
            vo.setImgUrl(course.getImage());
            vo.setTeacher(course.getAuthorUnit());
            list.add(vo);
        }
        return list;
    }


    /**
     * 培训数据格式
     *
     * @param projectVoList
     * @return
     */
    public List<PortalHomeSearchVO> formatProject(List<TrainingProjectListVo> projectVoList) {
        List<PortalHomeSearchVO> list = new ArrayList<PortalHomeSearchVO>();
        PortalHomeSearchVO ph = null;
        for (TrainingProjectListVo vo : projectVoList) {
            ph = new PortalHomeSearchVO();
            ph.setKind(SiteEnum.DETAIL.getValue());
            ph.setType(SiteEnum.TRAIN.getValue());
            ph.setId(vo.getId());
            ph.setTitle(vo.getName());
            ph.setStartDate(vo.getStartTime());
            ph.setEndDate(vo.getEndTime());
            ph.setImgUrl(vo.getLogoImg());
            ph.setNum(vo.getJoinNumber());
            if (vo.getFinished()) {
                ph.setState(1);
            } else {
                ph.setState(0);
            }
            list.add(ph);
        }
        return list;
    }


    /**
     *   页面的方法
     * ?* @currPageNo? 页面传入的页号，从一开始
     * ?* @pageSize??? 每页记录数
     * ?
     */
    public <T> Map<String, Object> getPagingResultMap(List<T> list, Integer currPageNo, Integer pageSize) {
        Map<String, Object> retMap = new HashMap<>();

        if (list.isEmpty()) {
            retMap.put("records", Collections.emptyList());
            retMap.put("current", 0);
            retMap.put("size", 0);
            retMap.put("total", 0);
            retMap.put("pages", 0);

            return retMap;
        }

        int totalRowNum = list.size();
        int totalPageNum = (totalRowNum - 1) / pageSize + 1;

        int realPageNo = currPageNo;
        if (currPageNo > totalPageNum) {
            realPageNo = totalPageNum;
        } else if (currPageNo < 1) {
            realPageNo = 1;
        }

        int fromIdx = (realPageNo - 1) * pageSize;

        int toIdx = realPageNo * pageSize > totalRowNum ? totalRowNum : realPageNo * pageSize;


        List<T> result = list.subList(fromIdx, toIdx);

        retMap.put("records", result);
        retMap.put("current", realPageNo);
        retMap.put("size", result.size());
        retMap.put("total", totalRowNum);
        retMap.put("pages", totalPageNum);

        return retMap;
    }
}
