package com.yizhi.application.share.controller;

import com.alibaba.fastjson.JSONObject;
import com.yizhi.album.application.feign.AlbumClient;
import com.yizhi.album.application.vo.domain.Album;
import com.yizhi.album.application.vo.domain.AlbumVisibleRange;
import com.yizhi.assignment.application.feign.AssignmentClient;
import com.yizhi.assignment.application.vo.AssignmentSelectVo;
import com.yizhi.assignment.application.vo.entity.AssignmentStudent;
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.CourseAccountVO;
import com.yizhi.course.application.vo.CourseVo;
import com.yizhi.exam.application.feign.ExamClient;
import com.yizhi.exam.application.vo.TrExamAuthorizeVO;
import com.yizhi.exam.application.vo.domain.Exam;
import com.yizhi.forum.application.constans.ForumConstans;
import com.yizhi.forum.application.feign.PostsVisibleRangeClient;
import com.yizhi.forum.application.feign.remote.RemotePostsClient;
import com.yizhi.forum.application.vo.domain.PostsVo;
import com.yizhi.forum.application.vo.forum.PostsVisibleRangeVo;
import com.yizhi.library.application.feign.CaseLibraryClient;
import com.yizhi.library.application.feign.StudentCaseClient;
import com.yizhi.library.application.vo.CaseLibraryVO;
import com.yizhi.library.application.vo.CaselibraryAuthorizeVO;
import com.yizhi.live.application.feign.LiveActivityClient;
import com.yizhi.live.application.vo.LiveActivityResultVO;
import com.yizhi.live.application.vo.LiveActivityVO;
import com.yizhi.live.application.vo.ScopeAuthorizationVO;
import com.yizhi.message.application.feign.remote.RemoteMessageClient;
import com.yizhi.message.application.vo.domain.MessageRemindVo;
import com.yizhi.message.application.vo.domain.MessageVisibleRangeVo;
import com.yizhi.practice.application.feign.MyPracticeStudentClient;
import com.yizhi.research.application.feign.ResearchAuthorizeClient;
import com.yizhi.research.application.feign.ResearchClient;
import com.yizhi.research.application.vo.domain.ResearchVo;
import com.yizhi.research.application.vo.domain.TrResearchAuthorizeVo;
import com.yizhi.site.application.feign.InformationStudentFeignClients;
import com.yizhi.site.application.vo.site.IdOneVO;
import com.yizhi.site.application.vo.site.InformationViewVO;
import com.yizhi.statistics.application.entity.Report;
import com.yizhi.statistics.application.entity.ReportVisibleRange;
import com.yizhi.statistics.application.feign.ReportClient;
import com.yizhi.system.application.system.remote.AccountClient;
import com.yizhi.system.application.vo.AccountVO;
import com.yizhi.training.application.feign.TpPlanClient;
import com.yizhi.training.application.feign.TrainingProjectClient;
import com.yizhi.training.application.vo.domain.TpAuthorizationRangeVo;
import com.yizhi.training.application.vo.domain.TpPlanVo;
import com.yizhi.training.application.vo.domain.TrainingProjectVo;
import com.yizhi.util.application.domain.BizResponse;
import com.yizhi.util.application.domain.Response;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections.CollectionUtils;
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 java.util.ArrayList;
import java.util.List;

@Api(tags = "页面分享关联可见范围接口", description = "页面分享关联可见范围接口")
@RestController
@RequestMapping("/api/share")
public class ShareController {

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

    @Autowired
    private TrainingProjectClient trainingProjectClient;

    @Autowired
    private AccountClient accountClient;

    @Autowired
    private CourseClient courseClient;

    @Autowired
    private AssignmentClient assignmentClient;

    @Autowired
    private ExamClient examClient;

    @Autowired
    private ResearchClient researchClient;

    @Autowired
    private ResearchAuthorizeClient researchAuthorizeClient;

    @Autowired
    private LiveActivityClient liveActivityClient;

//    @Autowired
//    private SystemMessageClient systemMessageClient;

    @Autowired
    private StudentCaseClient studentCaseClient;

    @Autowired
    private CaseLibraryClient caseLibraryClient;

    @Autowired
    private RemoteMessageClient remoteMessageClient;

    @Autowired
    private ReportClient reportClient;

    @Autowired
    private AlbumClient albumClient;
    @Autowired
    private RemotePostsClient remotePostsClient;
    @Autowired
    private PostsVisibleRangeClient postsVisibleRangeClient;
    @Autowired
    private TpPlanClient planClient;
    @Autowired
    private MyPracticeStudentClient practiceStudentClient;

    @Autowired
    private InformationStudentFeignClients informationStudentFeignClients;

    @ApiOperation(value = "分享页面关联可见范围")
    @GetMapping("/isVisible")
    public Response<Integer> isVisible(
            @ApiParam(name = "type", value = "类型：1.培训;2.课程;3.作业; 4.考试;5.调研;6.直播;7.消息;8 案例活动;9 平台报告；10专辑 11帖子；15智能陪练", required = true) @RequestParam(value = "type", required = true) Integer type,
            @ApiParam(name = "id", value = "分享的id，如课程、考试等", required = true) @RequestParam(value = "id", required = true) Long id,
            @ApiParam(name = "tpId", value = "分享培训项目下的活动必传", required = false) @RequestParam(value = "tpId", required = false) Long tpId,
            @ApiParam(name = "alId", value = "分享专辑下的课程必传", required = false) @RequestParam(value = "alId", required = false) Long alId,
            @ApiParam(name = "isVisible", value = "是否需要判断可见范围 0:否 | 1:是", required = false) @RequestParam(value = "isVisible", required = false) Integer isVisible
            ) {
        LOG.info("可见范围参数：" + "业务类型type:" + type + " 业务id:" + id + " 专辑id:" + alId + " 项目id" + tpId+"是否需要判断可见范围"+isVisible);
        RequestContext requestContext = ContextHolder.get();
        Integer result = 0;
        if (isVisible!=null&&isVisible==0) {
        	result = 1;
        	return Response.ok(result);
		}
        if (tpId == null) {
            result = getVisible(type, id, tpId, requestContext,false);
        } else {
            TrainingProjectVo tProject = trainingProjectClient.getOne(tpId);
            if (tProject == null) {
                LOG.error("返回培训项目对象实体为空！！！");
                return Response.ok(result);
            }
            LOG.info("返回培训项目对象实体" + tProject.toString());
            Integer range = tProject.getVisibleRange();
            if (range == 1) {
                result = 1;
            } else if (range == 0) {
                List<Long> accountIds = new ArrayList<>();
                List<TpAuthorizationRangeVo> visibleRanges = trainingProjectClient.VisibleRange(tpId);
                for (TpAuthorizationRangeVo visibleRange : visibleRanges) {
                    if (2 == visibleRange.getType()) {
                        accountIds.add(visibleRange.getRelationId());
                    } else {
                        accountIds = getAccountIds(accountIds, visibleRange.getRelationId(), requestContext.getCompanyId());
                        if (accountIds == null) {
                            continue;
                        }
                    }
                }
                result = accountIds.contains(requestContext.getAccountId()) ? 1 : 0;
            }
        }
        if (alId != null) {
            Album album = albumClient.get(alId);
            if (album == null) {
                LOG.error("返回专辑对象实体为空！！！");
                return Response.ok(result);
            }
            LOG.info("返回专辑对象实体" + album.toString());
            Integer range = album.getScope();
            if (range == 1) {
                result = 1;
            } else if (range == 2) {
                List<Long> accountIds = new ArrayList<>();
                List<AlbumVisibleRange> visibleRanges = albumClient.VisibleRange(alId);
                for (AlbumVisibleRange visibleRange : visibleRanges) {
                    if (2 == visibleRange.getType()) {
                        accountIds.add(visibleRange.getRelationId());
                    } else {
                        accountIds = getAccountIds(accountIds, visibleRange.getRelationId(), requestContext.getCompanyId());
                        if (accountIds == null) {
                            continue;
                        }
                    }
                }
                result = accountIds.contains(requestContext.getAccountId()) ? 1 : 0;
            }
        }
        return Response.ok(result);

    }

    /**
     * 获取可见范围
     *
     * @param type
     * @param id
     * @param tpId
     * @param requestContext
     * @return
     */
    public Integer getVisible(Integer type, Long id, Long tpId, RequestContext requestContext,Boolean fromMessage) {

        Integer result = 0;
        List<Long> accountIds = new ArrayList<Long>();
        // 初始可见范围
        Integer range = null;

        switch (type) {
            case 1:
                TrainingProjectVo trainingProject = trainingProjectClient.getOne(id);
                if (trainingProject == null) {
                    LOG.error("返回培训项目对象实体为空！！！");
                    return result;
                }
                // LOG.info("返回培训项目对象实体"+trainingProject.toString());
                range = trainingProject.getVisibleRange();
                if (range == 1) {
                    result = 1;
                } else if (0 == range) {
                    List<TpAuthorizationRangeVo> visibleRanges = trainingProjectClient.VisibleRange(id);
                    for (TpAuthorizationRangeVo visibleRange : visibleRanges) {
                        if (2 == visibleRange.getType()) {
                            accountIds.add(visibleRange.getRelationId());
                        } else {
                            accountIds = getAccountIds(accountIds, visibleRange.getRelationId(), requestContext.getCompanyId());
                            if (accountIds == null) {
                                continue;
                            }
                        }
                    }
                    // LOG.info("----");
                    // LOG.info("培训项目可见范围："+accountIds.toString());
                    return accountIds.contains(requestContext.getAccountId()) ? 1 : 0;
                }
                break;
            case 2:
                //如果关联培训项目，判断培训项目可见范围
                CourseVo courseVo = courseClient.getOne(id);
                if (courseVo == null) {
                    LOG.error("返回课程对象实体为空！！！");
                    return result;
                }
                // LOG.info("返回课程对象实体"+courseVo.toString());
                range = courseVo.getScope();
                if (1 == range) {
                    result = 1;
                } else if (2 == range) {
                    List<CourseAccountVO> visibleRange = courseClient.VisibleRange(id);
                    for (CourseAccountVO courseAccount : visibleRange) {
                        if (2 == courseAccount.getType()) {
                            accountIds.add(courseAccount.getRelationId());
                        } else {
                            accountIds = getAccountIds(accountIds, courseAccount.getRelationId(), requestContext.getCompanyId());
                            if (accountIds == null) {
                                continue;
                            }
                        }
                    }
                    // LOG.info("课程可见范围："+accountIds.toString());
                    result = accountIds.contains(requestContext.getAccountId()) ? 1 : 0;
                }
                break;
            case 3:
                AssignmentSelectVo assignmentSelectVo = assignmentClient.query(id);
                if (assignmentSelectVo == null) {
                    LOG.error("返回作业对象实体为空！！！");
                    return result;
                }
                //LOG.info("返回作业对象实体"+assignmentSelectVo.toString());
                range = assignmentSelectVo.getVisibleRange();
                if (1 == range) {
                    result = 1;
                } else if (2 == range) {
                    List<AssignmentStudent> visibleRanges = assignmentClient.VisibleRange(id);
                    for (AssignmentStudent visibleRange : visibleRanges) {
                        if (2 == visibleRange.getType()) {
                            accountIds.add(visibleRange.getAccountId());
                        } else {
                            accountIds = getAccountIds(accountIds, visibleRange.getAccountId(), requestContext.getCompanyId());
                            if (accountIds == null) {
                                continue;
                            }
                        }
                    }
                    //LOG.info("作业可见范围："+accountIds.toString());
                    result = accountIds.contains(requestContext.getAccountId()) ? 1 : 0;
                }
                break;
            case 4:
                Exam exam = examClient.examViewInfo(id);
                if (exam == null) {
                    LOG.error("返回考试对象实体为空！！！");
                    return result;
                }
                //LOG.info("返回考试对象实体"+exam.toString());
                range = exam.getVisibleRange();
                if (1 == range) {
                    result = 1;
                } else if (2 == range) {
                    List<TrExamAuthorizeVO> visibleRanges = examClient.VisibleRange(id);
                    for (TrExamAuthorizeVO visibleRange : visibleRanges) {
                        Integer examRangeType = visibleRange.getType();
                        if (2 == examRangeType) {
                            accountIds.add(visibleRange.getRelationId());
                        } else {
                            accountIds = getAccountIds(accountIds, visibleRange.getRelationId(), requestContext.getCompanyId());
                            if (accountIds == null) {
                                continue;
                            }
                        }
                    }
                    //LOG.info("考试可见范围："+accountIds.toString());
                    result = accountIds.contains(requestContext.getAccountId()) ? 1 : 0;
                }
                break;
            case 5:
                ResearchVo research = researchClient.getResearchView(id);
                if (research == null) {
                    LOG.error("返回调研对象实体为空！！！");
                    return result;
                }
                // LOG.info("返回调研对象实体"+research.toString());
                range = research.getVisibleRange();
                if (1 == range) {
                    result = 1;
                } else if (2 == range) {
                    List<TrResearchAuthorizeVo> visibleRanges = researchAuthorizeClient.getResearchAuthorize(id);
                    for (TrResearchAuthorizeVo visibleRange : visibleRanges) {
                        Integer rangeType = visibleRange.getType();
                        if (2 == rangeType) {
                            accountIds.add(visibleRange.getRelationId());
                        } else {
                            accountIds = getAccountIds(accountIds, visibleRange.getRelationId(), requestContext.getCompanyId());
                            if (accountIds == null) {
                                continue;
                            }
                        }
                    }
                    //LOG.info("调研可见范围："+accountIds.toString());
                    result = accountIds.contains(requestContext.getAccountId()) ? 1 : 0;
                }
                break;
            case 6:
                LiveActivityVO liveActivityResultVO = null;
                if (fromMessage) {
                    LiveActivityResultVO liveVo = liveActivityClient.get(id);
                    LiveActivityVO live = liveVo.getLiveActivity();
                    if (live != null) {
                        liveActivityResultVO = liveActivityClient.viewByChannelId(live.getChannel());
                    }

                } else {
                    liveActivityResultVO = liveActivityClient.viewByChannelId(String.valueOf(id));
                }
                if (liveActivityResultVO == null) {
                    LOG.error("返回直播对象实体为空！！！");
                    return result;
                }
                //LOG.info("返回直播对象实体"+liveActivityResultVO.toString());
                
                if (liveActivityResultVO.getScope()==0) {
                    result = 1;
                } else {
                	List<ScopeAuthorizationVO> visibleRanges = liveActivityClient.getScopeAuthorizationList(liveActivityResultVO.getId());
                    for (ScopeAuthorizationVO visibleRange : visibleRanges) {
                        Integer liveRange = visibleRange.getType();
                        if (2 == liveRange) {
                            accountIds.add(visibleRange.getAccountId());
                        } else {
                            accountIds = getAccountIds(accountIds, visibleRange.getAccountId(), requestContext.getCompanyId());
                            if (accountIds == null) {
                                continue;
                            }
                        }
                    }
                    //LOG.info("直播可见范围："+accountIds.toString());
                    result = accountIds.contains(requestContext.getAccountId()) ? 1 : 0;
                }
                break;
            case 7:
                MessageRemindVo one = remoteMessageClient.getMessageRemind(id);
                if (one == null) {
                    LOG.error("返回待发消息对象实体为空！！！");
                    return result;
                }
                LOG.info("返回待发消息对象实体" + one.toString());
                if (one.getMessageType().equals(1)) {
                    range = one.getVisibleRange();
                    //全平台
                    if (0 == range) {
                        result = 1;
                    } else if (1 == range) {
                        List<MessageVisibleRangeVo> visibleRanges = remoteMessageClient.getAuthorize(one.getMessageId());
                        for (MessageVisibleRangeVo visibleRange : visibleRanges) {
                            if (2 == visibleRange.getType()) {
                                accountIds.add(visibleRange.getRelationId());
                            } else {
                                List<AccountVO> list = accountClient.findByOrgId(visibleRange.getRelationId(),
                                        requestContext.getCompanyId());
                                if (list == null) {
                                    continue;
                                }
                                for (AccountVO accountVO : list) {
                                    accountIds.add(accountVO.getId());
                                }
                            }
                        }
                        // LOG.info("消息可见范围："+accountIds.toString());
                        result = accountIds.contains(requestContext.getAccountId()) ? 1 : 0;
                    }
                } else {
                    int rationType = one.getRelationType();
                    switch (rationType) {
                        //学习计划
                        case 1:
                            result = getVisible(12, one.getRelationId(), tpId, requestContext,true);
                            break;
                        //考试
                        case 2:
                            result = getVisible(4, one.getRelationId(), tpId, requestContext,true);
                            break;
                        //调研
                        case 3:
                            result = getVisible(5, one.getRelationId(), tpId, requestContext,true);
                            break;
                        //作业
                        case 6:
                            result = getVisible(3, one.getRelationId(), tpId, requestContext,true);
                            break;
                        //项目
                        case 8:
                            result = getVisible(1, one.getRelationId(), tpId, requestContext,true);
                            break;
                        //直播
                        case 9:
                            result = getVisible(6, one.getRelationId(), tpId, requestContext,true);

                            break;
                        //课程
                        case 11: case 16:
                            result = getVisible(2, one.getRelationId(), tpId, requestContext,true);
                            break;
                    }
                }
                break;
            case 8:
                CaseLibraryVO library = caseLibraryClient.getCaseLibrary(id);
                if (library == null) {
                    LOG.error("返回案例对象实体为空！！！");
                    return result;
                }
                //LOG.info("返回案例活动对象实体"+library.toString());
                range = library.getVisibleRange();
                if (1 == range) {
                    result = 1;
                } else if (2 == range) {
                    List<CaselibraryAuthorizeVO> visibleRanges = caseLibraryClient.getAuthorize(library.getId());
                    for (CaselibraryAuthorizeVO visibleRange : visibleRanges) {
                        if (2 == visibleRange.getType()) {
                            accountIds.add(visibleRange.getRelationId());
                        } else {
                            List<AccountVO> list = accountClient.findByOrgId(visibleRange.getRelationId(),
                                    requestContext.getCompanyId());
                            if (list == null) {
                                continue;
                            }
                            for (AccountVO accountVO : list) {
                                accountIds.add(accountVO.getId());
                            }
                        }
                    }
                    // LOG.info("案例活动可见范围："+accountIds.toString());
                    result = accountIds.contains(requestContext.getAccountId()) ? 1 : 0;
                }
                break;
            case 9:
                Report report = reportClient.getById(id);
                if (report == null) {
                    LOG.error("返回平台报告对象实体为空！！！");
                    return result;
                }
                //LOG.info("返回平台报告对象实体"+report.toString());
                range = report.getVisibleRange();
                if (1 == range) {
                    result = 1;
                } else if (2 == range) {
                    List<ReportVisibleRange> visibleRanges = reportClient.VisibleRange(id);
                    for (ReportVisibleRange visibleRange : visibleRanges) {
                        if (2 == visibleRange.getType()) {
                            accountIds.add(visibleRange.getRelationId());
                        } else {
                            List<AccountVO> list = accountClient.findByOrgId(visibleRange.getRelationId(),
                                    requestContext.getCompanyId());
                            if (list == null) {
                                continue;
                            }
                            for (AccountVO accountVO : list) {
                                accountIds.add(accountVO.getId());
                            }
                        }
                    }
                    //LOG.info("平台报告可见范围："+accountIds.toString());
                    result = accountIds.contains(requestContext.getAccountId()) ? 1 : 0;
                }
                break;
            case 10:
                Album album = albumClient.get(id);
                if (album == null) {
                    LOG.error("返回专辑对象实体为空！！！");
                    return result;
                }
                //LOG.info("返回专辑对象实体"+album.toString());
                range = album.getScope();
                if (range == 1) {
                    result = 1;
                } else if (range == 2) {
                    accountIds = new ArrayList<>();
                    List<AlbumVisibleRange> visibleRanges = albumClient.VisibleRange(id);
                    for (AlbumVisibleRange visibleRange : visibleRanges) {
                        if (2 == visibleRange.getType()) {
                            accountIds.add(visibleRange.getRelationId());
                        } else {
                            accountIds = getAccountIds(accountIds, visibleRange.getRelationId(), requestContext.getCompanyId());
                            if (accountIds == null) {
                                continue;
                            }
                        }
                    }
                    //LOG.info("专辑可见范围："+accountIds.toString());
                    result = accountIds.contains(requestContext.getAccountId()) ? 1 : 0;
                }
                break;
            case 11:
                //1-有权限  0-无权限
                result = 0;
                PostsVo info = remotePostsClient.getInfo(id);
                if (info == null) {
                    LOG.error("返回帖子对象实体为空！！！");
                    return result;
                }
                range = info.getVisibleRange();
                if (ForumConstans.SITE_ACCOUNT.equals(range)) {
                    result = 1;
                } else {
                    List<com.yizhi.forum.application.vo.forum.PostsVisibleRangeVo> visibleRanges = postsVisibleRangeClient.getVisibleRange(id);
                    if (CollectionUtils.isNotEmpty(visibleRanges)) {
                        accountIds = new ArrayList<>();
                        for (PostsVisibleRangeVo a : visibleRanges) {
                            //1-部门   2-用户
                            if (ForumConstans.ACCOUNT.equals(a.getAccountType())) {
                                accountIds.add(a.getAccountId());
                            } else {
                                List<AccountVO> list = accountClient.findByOrgId(a.getAccountId(), requestContext.getCompanyId());
                                if (list == null) {
                                    continue;
                                }
                                for (AccountVO accountVO : list) {
                                    accountIds.add(accountVO.getId());
                                }
                            }
                        }
                        //LOG.info("论坛可见范围："+accountIds.toString());
                        result = accountIds.contains(requestContext.getAccountId()) ? 1 : 0;
                    }
                }
                break;
            //培训计划
            case 12:
                TpPlanVo tpPlan = planClient.getOne(id);
                if (tpPlan != null) {
                    result = getVisible(1,tpPlan.getTrainingProjectId(), tpId, requestContext,true);
                }else {
                    LOG.error("计划id无效！");
                }
                break;
            //报名
            case 13:
                break;
            //签到
            case 14:
                break;
            case 15:
                //智能陪练
                if (null == id){
                    result = 0;
                    break;
                }
                BizResponse<Boolean> userPracticeAuth = practiceStudentClient.getUserPracticeAuth(requestContext, id);
                if (null == userPracticeAuth || null == userPracticeAuth.getData() || false == userPracticeAuth.getData()){
                    result = 0;
                    LOG.error("智能陪练获取用户陪练权限失败！requestContext = {}", JSONObject.toJSONString(requestContext));
                    break;
                }else if (true == userPracticeAuth.getData()){
                    result = 1;
                    break;
                }
            case 16:
                InformationViewVO informationViewVO = informationStudentFeignClients.getInformation(new IdOneVO(){{setId(id);}});
                if (informationViewVO == null) {
                    LOG.error("返回培训项目对象实体为空！！！");
                    return result;
                }
                result = 1;
                break;
        }
        return result;
    }

    /**
     * 获取用户ids
     *
     * @param relationId
     * @param companyId
     * @return
     */
    public List<Long> getAccountIds(List<Long> accountIds, Long relationId, Long companyId) {

        List<AccountVO> list = accountClient.findByOrgId(relationId, companyId);
        List<Long> ids = new ArrayList<Long>();
        if (CollectionUtils.isNotEmpty(list)) {
            LOG.info("可见范围关联部门：" + list.toString());
            for (AccountVO vo : list) {
                ids.add(vo.getId());
            }
        }
        if (CollectionUtils.isNotEmpty(ids)) {
            accountIds.addAll(ids);
            return accountIds;
        } else {
            return accountIds;
        }

    }
}
