package cn.axzo.msg.center.inside.notices.service.impl;

import cn.axzo.basics.common.BeanMapper;
import cn.axzo.basics.profiles.api.UserProfileServiceApi;
import cn.axzo.basics.profiles.dto.basic.PersonProfileDto;
import cn.axzo.msg.center.api.request.v3.SearchPendingMessageReq;
import cn.axzo.msg.center.api.request.v3.SearchTodoLogReq;
import cn.axzo.msg.center.api.response.v3.SearchPendingMessageResp;
import cn.axzo.msg.center.api.response.v3.SearchTodoLogResponse;
import cn.axzo.msg.center.common.utils.BizAssertions;
import cn.axzo.msg.center.dal.TodoBusinessDao;
import cn.axzo.msg.center.dal.TodoBusinesses;
import cn.axzo.msg.center.dal.TodoDao;
import cn.axzo.msg.center.dal.TodoLogDao;
import cn.axzo.msg.center.domain.entity.Todo;
import cn.axzo.msg.center.domain.entity.TodoBusiness;
import cn.axzo.msg.center.domain.entity.TodoLog;
import cn.azxo.framework.common.model.CommonResponse;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author yanglin
 */
@Component
@RequiredArgsConstructor
public class TodoSearchService {

    private final TodoBusinessDao todoBusinessDao;
    private final TodoDao todoDao;
    private final TodoLogDao todoLogDao;
    private final UserProfileServiceApi userProfileServiceApi;

    public List<SearchTodoLogResponse> searchTodoLogs(SearchTodoLogReq req) {
        if (req.getLimit() >= 100) {
            req.setLimit(100);
        }
        List<TodoLog> logs = todoLogDao.lambdaQuery()
                .eq(StringUtils.isNotBlank(req.getSrcTemplateCode()), TodoLog::getSrcTemplateCode, req.getSrcTemplateCode())
                .eq(StringUtils.isNotBlank(req.getTemplateCode()), TodoLog::getTemplateCode, req.getTemplateCode())
                .eq(StringUtils.isNotBlank(req.getIdentityCode()), TodoLog::getIdentityCode, req.getIdentityCode())
                .eq(StringUtils.isNotBlank(req.getBizCode()), TodoLog::getBizCode, req.getBizCode())
                .eq(StringUtils.isNotBlank(req.getSubBizCode()), TodoLog::getSubBizCode, req.getSubBizCode())
                .eq(StringUtils.isNotBlank(req.getRequestNo()), TodoLog::getRequestNo, req.getRequestNo())
                .eq(req.getLogType() != null, TodoLog::getLogType, req.getLogType())
                .like(StringUtils.isNotBlank(req.getContext()), TodoLog::getContext, req.getContext())
                .orderByDesc(TodoLog::getId)
                .last("LIMIT " + req.getLimit())
                .list();
        return BeanMapper.copyList(logs, SearchTodoLogResponse.class);
    }

    public List<SearchPendingMessageResp> searchTodos(SearchPendingMessageReq req) {
        if (req.getLimit() >= 100) {
            req.setLimit(100);
        }
        if (req.getExecutorPersonId() == null && StringUtils.isNotBlank(req.getExecutorPhone())) {
            req.setExecutorPersonId(getPersonIdByPhone(req.getExecutorPhone()));
        }
        List<Todo> records = todoDao.lambdaQuery()
                .in(Todo::getType, req.determineTodoTypes())
                .eq(req.getExecutorPersonId() != null, Todo::getExecutorPersonId, req.getExecutorPersonId())
                .eq(req.getOuId() != null, Todo::getOuId, req.getOuId())
                .eq(req.getState() != null, Todo::getState, req.getState())
                .eq(StringUtils.isNotBlank(req.getBizCode()), Todo::getBizCode, req.getBizCode())
                .eq(StringUtils.isNotBlank(req.getSubBizCode()), Todo::getSubBizCode, req.getSubBizCode())
                .eq(StringUtils.isNotBlank(req.getTemplateCode()), Todo::getTemplateCode, req.getTemplateCode())
                .in(CollectionUtils.isNotEmpty(req.getIdentityCodes()), Todo::getIdentityCode, req.getIdentityCodes())
                .like(StringUtils.isNotBlank(req.getTitle()), Todo::getTitle, req.getTitle())
                .like(StringUtils.isNotBlank(req.getContent()), Todo::getContent, req.getContent())
                .ge(req.getStartTime() != null, Todo::getCreateAt, req.getStartTime())
                .le(req.getEndTime() != null, Todo::getCreateAt, req.getEndTime())
                .orderByDesc(Todo::getId)
                .last("LIMIT " + req.getLimit())
                .list();
        TodoBusinesses businesses = todoBusinessDao.getBusinesses(records);
        List<SearchPendingMessageResp> todos = BeanMapper.copyList(records, SearchPendingMessageResp.class);
        for (SearchPendingMessageResp todo : todos) {
            TodoBusiness business = businesses.findBusiness(todo.getTodoBusinessId()).orElse(null);
            if (business == null) continue;
            todo.setPromoterId(business.getPromoterId());
            todo.setPromoterPersonId(business.getPromoterPersonId());
            todo.setPromoterName(business.getPromoterName());
            todo.setPromoterOuId(business.getOuId());
            todo.setPromoterOrgId(business.getOrgId());
            todo.setPromoterOrgType(business.getOrgType());
        }
        return todos;
    }

    public Long getPersonIdByPhone(String phone) {
        CommonResponse<PersonProfileDto> profileResp = userProfileServiceApi
                .getUnionPersonProfile(null, phone);
        PersonProfileDto personProfile = BizAssertions.assertResponse(profileResp, "未找根据手机找到人员");
        BizAssertions.assertNotNull(personProfile, "未找根据手机找到人员");
        return personProfile.getId();
    }

}