/**
 */
package com.sifang.modules.taskdispatch.dao;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.sys.common.persistence.BaseDao;
import com.sifang.modules.sys.common.persistence.Parameter;
import com.sifang.modules.sys.common.utils.IdGen;
import com.sifang.modules.sys.util.LayuiPage;
import com.sifang.modules.sys.util.SqlBuilder;
import com.sifang.modules.taskdispatch.entity.CrmReviewGroupMember;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 审核组成员信息DAO接口
 * @author gaols
 */
@Repository
public class CrmReviewGroupMemberDao extends BaseDao<CrmReviewGroupMember> {
    public List<Record> listData(LayuiPage<Record> page, Map<String, String> params) {
        SqlBuilder sb = new SqlBuilder();
        sb.line("select e.name,m.group_id,m.partner_id,m.employee_id,m.leadership,m.id,e.user_id");
        sb.line("from crm_review_group_member as m");
        sb.line("inner join crm_platform_employee as e on e.id=m.employee_id and e.status='0'");
        sb.line("where m.status='0'");
        queryConditions(sb, params);
        sb.line("order by m.sort");
        List<Record> records = Db.find(sb.build(), sb.params());
        if (page != null) {
            sb.limit(page.getPage(), page.getLimit());
            page.setData(records);
        }
        return records;
    }

    public List<Record> findAllMembers() {
        Map<String, String> params = new HashMap<>();
        return listData(null, params);
    }

    public void queryConditions(SqlBuilder sb, Map<String, String> params) {
        if (StringUtils.isNotBlank(params.get("groupId"))) {
            sb.line("and m.group_id=?", params.get("groupId"));
        }
        if (StringUtils.isNotBlank(params.get("leadership"))) {
            sb.line("and m.leadership=?", params.get("leadership"));
        }
        if (StringUtils.isNotBlank(params.get("partnerId"))) {
            sb.line("and m.partner_id=?", params.get("partnerId"));
        }
    }

    public void listDataCount(LayuiPage<Record> page, Map<String, String> params) {
        SqlBuilder sb = new SqlBuilder();
        page.setCount(Db.queryLong(sb.build(), sb.params()));
    }

    public List<Record> findByEmployeeId(String employeeId) {
        SqlBuilder sb = new SqlBuilder();
        sb.line("select *");
        sb.line("from crm_review_group_member as m");
        sb.line("where m.employee_id=? and status='0'", employeeId);
        return Db.find(sb.build(), sb.params());
    }

    public Record findFirstByEmployeeId(String employeeId) {
        SqlBuilder sb = new SqlBuilder();
        sb.line("select *");
        sb.line("from crm_review_group_member as m");
        sb.line("where m.employee_id=? and status='0'", employeeId);
        return Db.findFirst(sb.build(), sb.params());
    }

    public List<CrmReviewGroupMember> findMemberByEmployeeId(String employeeId) {
        SqlBuilder sb = new SqlBuilder();
        sb.line("from CrmReviewGroupMember");
        sb.line("where employeeId=:p1 and status='0'");
        return find(sb.build(), new Parameter(employeeId));
    }

    public List<Record> findByEmployeeIds(List<String> employeeIds, String partnerId) {
        if (CollectionUtils.isEmpty(employeeIds)) {
            return new ArrayList<>();
        }
        SqlBuilder sb = new SqlBuilder();
        sb.line("select *");
        sb.line("from crm_review_group_member as m");
        sb.line("where status='0'");
        sb.line("and m.partner_id=?", partnerId);
        sb.inst("and m.employee_id in", employeeIds);
        return Db.find(sb.build(), sb.params());
    }

    public List<Record> onlineMembers() {
        SqlBuilder sb = new SqlBuilder()
                .line("select id,group_id from crm_review_group_member where status='0' and signin_time is not null")
                .line("and signout_time is null");
        return Db.find(sb.build(), sb.params());
    }

    public List<Record> groupMemberCount() {
        SqlBuilder sb = new SqlBuilder()
                .line("select group_id,count(id) as cnt from crm_review_group_member")
                .line("where status='0'")
                .line("group by group_id");
        return Db.find(sb.build(), sb.params());
    }

    public Long groupMemberCount(String groupId) {
        SqlBuilder sb = new SqlBuilder()
                .line("select count(id) as cnt from crm_review_group_member")
                .line("where status='0'")
                .line("and group_id=?", groupId);
        return Db.queryLong(sb.build(), sb.params());
    }

    public void updateSort(List<Record> updates, Map<String, Integer> orderMap, String groupId) {
        SqlBuilder sb = new SqlBuilder();
        sb.line("update crm_review_group_member set sort=? where id=? and group_id=?");
        Object[][] paras = new Object[updates.size()][];
        int i = 0;
        for (Record update : updates) {
            paras[i][0] = orderMap.get(update.getStr("employee_id"));
            paras[i][1] = update.getStr("id");
            paras[i][2] = groupId;
            i++;
        }
        Db.batch(sb.build(), paras, 100);
    }

    public void insert(List<CrmReviewGroupMember> members) {
        Object[][] paras = new Object[members.size()][];
        int i = 0;
        for (CrmReviewGroupMember member : members) {
            paras[i] = new Object[13];
            paras[i][0] = IdGen.uuid();
            paras[i][1] = member.getPartnerId();
            paras[i][2] = member.getGroupId();
            paras[i][3] = member.getEmployeeId();
            paras[i][4] = member.getLeadership();
            paras[i][5] = member.getSort();
            paras[i][6] = member.getSigninTime();
            paras[i][7] = member.getSignoutTime();
            paras[i][8] = member.getStatus();
            paras[i][9] = member.getCreateBy();
            paras[i][10] = member.getCreator();
            paras[i][11] = member.getCreateTime();
            paras[i][12] = member.getUserId();
            i++;
        }

        SqlBuilder sb = new SqlBuilder();
        sb.line("INSERT INTO crm_review_group_member (id, partner_id,group_id, employee_id, leadership, sort, signin_time, signout_time, status, create_by, creator, create_time,user_id)");
        sb.line("VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)");
        String sql  = sb.build();
        Db.batch(sql, paras, 100);
    }

    public void deleteByEmployeeIds(Set<String> delEmps, String groupId) {
        if (delEmps.isEmpty()) {
            return;
        }
        SqlBuilder sb = new SqlBuilder();
        sb.line("update crm_review_group_member set status=? where status='0' and group_id=?", IdGen.uuid(), groupId);
        sb.inst("and employee_id in", new ArrayList<>(delEmps));
        Db.update(sb.build(), sb.params());
    }

    public List<Record> findFreeOnlineWorkers(String partnerId) {
        return findFreeOnlineWorkers(partnerId, null);
    }

    public List<Record> findFreeOnlineWorkers(String partnerId, List<String> userIds) {
        SqlBuilder sb = new SqlBuilder();
        sb.line("select m.id,m.employee_id,e.provices,e.city,e.user_id,e.name,m.group_id,m.partner_id");
        sb.line("from crm_review_group_member as m");
        sb.line("inner join crm_platform_employee as e on e.id=m.employee_id and e.status='0'");
        sb.line("inner join sys_user as u on u.id=e.user_id and u.status='0'");
        sb.line("where m.partner_id=? and m.status='0' and m.signin_time is not null and m.signout_time is null", partnerId);
        if (!CollectionUtils.isEmpty(userIds)) {
            sb.inst("and u.id in", userIds);
        }
        sb.line("and not exists(");
        sb.line("    select 1 from crm_item_manage as ma where ma.assign_audit_user_id=u.id and ma.status='1' and ma.end_time is null");
        sb.line(")");
        List<Record> ret = Db.find(sb.build(), sb.params());

        Set<String> relativeUserIds = ret.stream().map(e -> e.getStr("user_id")).collect(Collectors.toSet());
        List<Record> members = findByUserIds(relativeUserIds);
        Map<String, List<Record>> memberGroupMap = members.stream().collect(Collectors.groupingBy(e -> e.getStr("user_id")));
        for (Record record : ret) {
            String userId = record.getStr("user_id");
            List<Record> groups = memberGroupMap.get(userId);
            if (groups == null) {
                // this should never happen, just for safety
                groups = new ArrayList<>();
            }
            record.set("groups", groups.stream().map(e -> e.getStr("group_id")).collect(Collectors.toSet()));
        }

        return ret;
    }

    public List<Record> findByUserIds(Set<String> userIds) {
        if (CollectionUtils.isEmpty(userIds)) {
            return new ArrayList<>();
        }
        SqlBuilder sb = new SqlBuilder()
                .line("select user_id,partner_id,group_id from crm_review_group_member")
                .inst("where user_id in", userIds)
                .line("and status='0'");
        return Db.find(sb.build(), sb.params());
    }

    public boolean isMemberOnline(String userId) {
        return Db.findFirst("select * from crm_review_group_member where user_id=? and status='0' and (signin_time is not null and signout_time is null)", userId) != null;
    }

    public void setLeader(String leaderEmpId, String groupId) {
        SqlBuilder sb = new SqlBuilder()
                .line("update crm_review_group_member set leadership='0' where group_id=? and status='0'", groupId);
        Db.update(sb.build(), sb.params());
        SqlBuilder sb1 = new SqlBuilder()
                .line("update crm_review_group_member set leadership='1' where group_id=? and status='0' and employee_id=?", groupId, leaderEmpId);
        Db.update(sb1.build(), sb1.params());
    }

    public void deleteGroupMemberById(String id) {
        StringBuffer sb = new StringBuffer();
        sb.append("DELETE FROM crm_review_group_member WHERE group_id = ? ");
        Db.update(sb.toString(), id);
    }
}
