package com.gree.mall.miniapp.logic.worker;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.miniapp.bean.user.CurrentCompanyWechat;
import com.gree.mall.miniapp.bean.worker.TeamCount;
import com.gree.mall.miniapp.bean.worker.WebsitWorkerBean;
import com.gree.mall.miniapp.bean.worker.WorkerTeamApplyBean;
import com.gree.mall.miniapp.bean.worker.WorkerTeamBean;
import com.gree.mall.miniapp.enums.ExamineStatusEnum;
import com.gree.mall.miniapp.enums.ExamineWorkerStatusEnum;
import com.gree.mall.miniapp.enums.StateEnum;
import com.gree.mall.miniapp.exception.RemoteServiceException;
import com.gree.mall.miniapp.logic.common.CommonLogic;
import com.gree.mall.miniapp.plus.entity.*;
import com.gree.mall.miniapp.plus.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class WorkerTeamLogic {

    @Resource
    WorkerTeamService workerTeamService;
    @Resource
    WorkerTeamApplyService workerTeamApplyService;
    @Resource
    CommonLogic commonLogic;
    @Resource
    UserService userService;
    @Resource
    WebsitUserService websitUserService;
    @Resource
    AdminWebsitService adminWebsitUserService;


    public IPage<WorkerTeamApplyBean> page(Integer pageNum, Integer pageSize) {
        CurrentCompanyWechat current = commonLogic.getCurrentCompanyWechat();
        final Page<WorkerTeamApply> page = workerTeamApplyService.lambdaQuery()
                .eq(WorkerTeamApply::getCompanyWechatId, current.getUser().getCompanyWechatId())
                .and(v -> v.eq(WorkerTeamApply::getMasterWorkerId, current.getUser().getUserId())
                        .or()
                        .eq(WorkerTeamApply::getAssistantWorkerId, current.getUser().getUserId())
                )
                .eq(WorkerTeamApply::getStatus, ExamineStatusEnum.WAIT.getKey())
                .page(new Page<>(pageNum, pageSize));
        Page<WorkerTeamApplyBean> newPage = new Page<>();
        BeanUtil.copyProperties(page, newPage, "records");
        newPage.setRecords(new ArrayList<>());

        if (CollectionUtil.isNotEmpty(page.getRecords())) {
            List<AdminWebsit> adminWebsitList = adminWebsitUserService.lambdaQuery()
                    .eq(AdminWebsit::getCompanyWechatId, current.getUser().getCompanyWechatId())
                    .in(AdminWebsit::getWebsitId, page.getRecords().stream()
                            .map(WorkerTeamApply::getWebsitId)
                            .collect(Collectors.toList()))
                    .list();
            Map<String, String> websitMap = adminWebsitList.stream().collect(Collectors.toMap(AdminWebsit::getWebsitId, AdminWebsit::getName));
            final List<WorkerTeamApplyBean> beanList = BeanUtil.copyToList(page.getRecords(), WorkerTeamApplyBean.class);
            for (WorkerTeamApplyBean applyBean : beanList) {
                final String name = websitMap.get(applyBean.getWebsitId());
                applyBean.setWebsitName(name);
            }
            newPage.setRecords(beanList);
        }

        return newPage;
    }

    public IPage<WorkerTeamBean> managePage(Integer pageNum, Integer pageSize) {
        CurrentCompanyWechat current = commonLogic.getCurrentCompanyWechat();
        final Page<WorkerTeam> page = workerTeamService.lambdaQuery()
                .eq(WorkerTeam::getCompanyWechatId, current.getUser().getCompanyWechatId())
                .and(v -> v.eq(WorkerTeam::getMasterWorkerId, current.getUser().getUserId())
                        .or()
                        .eq(WorkerTeam::getAssistantWorkerId, current.getUser().getUserId())
                )
                .page(new Page<>(pageNum, pageSize));

        Page<WorkerTeamBean> newPage = new Page<>();
        BeanUtil.copyProperties(page, newPage, "records");
        newPage.setRecords(new ArrayList<>());

        if (CollectionUtil.isNotEmpty(page.getRecords())) {
            List<AdminWebsit> adminWebsitList = adminWebsitUserService.lambdaQuery()
                    .eq(AdminWebsit::getCompanyWechatId, current.getUser().getCompanyWechatId())
                    .in(AdminWebsit::getWebsitId, page.getRecords().stream()
                            .map(WorkerTeam::getWebsitId)
                            .collect(Collectors.toList()))
                    .list();
            Map<String, String> websitMap = adminWebsitList.stream().collect(Collectors.toMap(AdminWebsit::getWebsitId, AdminWebsit::getName));
            final List<WorkerTeamBean> beanList = BeanUtil.copyToList(page.getRecords(), WorkerTeamBean.class);
            for (WorkerTeamBean applyBean : beanList) {
                final String name = websitMap.get(applyBean.getWebsitId());
                applyBean.setWebsitName(name);
            }
            newPage.setRecords(beanList);
        }
        return newPage;
    }


    public void add(WorkerTeamApply workerTeam) {
        CurrentCompanyWechat current = commonLogic.getCurrentCompanyWechat();
        workerTeam.setCompanyWechatId(current.getUser().getCompanyWechatId())
                .setCompanyWechatName(current.getUser().getCompanyName());
        if (StringUtils.isBlank(workerTeam.getWebsitId())) {
            throw new RemoteServiceException("网点编号不能为空");
        }
        if (StringUtils.isBlank(workerTeam.getMasterWorkerId()) || StringUtils.isBlank(workerTeam.getMasterWorkerName())) {
            workerTeam.setMasterWorkerId(current.getUser().getUserId())
                    .setMasterWorkerNumber(current.getUser().getWorkerNumber())
                    .setMasterWorkerName(current.getUser().getNickName());
        }
        if (StringUtils.isBlank(workerTeam.getAssistantWorkerId()) || StringUtils.isBlank(workerTeam.getAssistantWorkerName())) {
            throw new RemoteServiceException("组队师傅不能为空");
        }
        final User assistantWorker = userService.getById(workerTeam.getAssistantWorkerId());
        workerTeam.setAssistantWorkerNumber(assistantWorker.getWorkerNumber());
        final Integer count = workerTeamService.lambdaQuery()
                .eq(WorkerTeam::getWebsitId, workerTeam.getWebsitId())
                .eq(WorkerTeam::getMasterWorkerId, workerTeam.getMasterWorkerId())
                .eq(WorkerTeam::getAssistantWorkerId, workerTeam.getAssistantWorkerId())
                .count();
        if (count > 0) {
            throw new RemoteServiceException("已和 " + workerTeam.getAssistantWorkerName() + " 师傅组队");
        }
        final Integer count1 = workerTeamService.lambdaQuery()
                .eq(WorkerTeam::getWebsitId, workerTeam.getWebsitId())
                .eq(WorkerTeam::getMasterWorkerId, workerTeam.getAssistantWorkerId())
                .eq(WorkerTeam::getAssistantWorkerId, workerTeam.getMasterWorkerId())
                .count();
        if (count1 > 0) {
            throw new RemoteServiceException("已和 " + workerTeam.getAssistantWorkerName() + " 师傅组队");
        }
        final Integer count3 = workerTeamApplyService.lambdaQuery()
                .eq(WorkerTeamApply::getWebsitId, workerTeam.getWebsitId())
                .eq(WorkerTeamApply::getMasterWorkerId, workerTeam.getMasterWorkerId())
                .eq(WorkerTeamApply::getAssistantWorkerId, workerTeam.getAssistantWorkerId())
                .eq(WorkerTeamApply::getStatus, ExamineStatusEnum.WAIT.getKey())
                .count();
        if (count3 > 0) {
            throw new RemoteServiceException("已有一条待确认记录和 " + workerTeam.getAssistantWorkerName() + " 师傅组队");
        }
        final Integer count4 = workerTeamApplyService.lambdaQuery()
                .eq(WorkerTeamApply::getWebsitId, workerTeam.getWebsitId())
                .eq(WorkerTeamApply::getMasterWorkerId, workerTeam.getAssistantWorkerId())
                .eq(WorkerTeamApply::getAssistantWorkerId, workerTeam.getMasterWorkerId())
                .eq(WorkerTeamApply::getStatus, ExamineStatusEnum.WAIT.getKey())
                .count();
        if (count4 > 0) {
            throw new RemoteServiceException("已有一条待确认记录和 " + workerTeam.getAssistantWorkerName() + " 师傅组队");
        }
        workerTeam.insert();
    }

    @Transactional
    public void confirm(String id, ExamineStatusEnum status) {
        CurrentCompanyWechat current = commonLogic.getCurrentCompanyWechat();
        final WorkerTeamApply apply = workerTeamApplyService.getById(id);
        if (!apply.getStatus().equals(ExamineStatusEnum.WAIT.getKey())) {
            throw new RemoteServiceException("申请记录非”待确认“状态");
        }
        if (apply.getMasterWorkerId().equals(current.getUser().getUserId())) {
            throw new RemoteServiceException("申请发起人不能”确认“记录");
        }
        if (status.getKey().equals(ExamineStatusEnum.OK.getKey())) {
            apply.setStatus(status.getKey())
                    .updateById();
            final Integer count = workerTeamService.lambdaQuery()
                    .eq(WorkerTeam::getWebsitId, apply.getWebsitId())
                    .eq(WorkerTeam::getMasterWorkerId, apply.getMasterWorkerId())
                    .eq(WorkerTeam::getAssistantWorkerId, apply.getAssistantWorkerId())
                    .count();
            final Integer count1 = workerTeamService.lambdaQuery()
                    .eq(WorkerTeam::getWebsitId, apply.getWebsitId())
                    .eq(WorkerTeam::getMasterWorkerId, apply.getAssistantWorkerId())
                    .eq(WorkerTeam::getAssistantWorkerId, apply.getMasterWorkerId())
                    .count();

            if (count > 0 || count1 > 0) {
                return;
            }
            new WorkerTeam()
                    .setCompanyWechatId(apply.getCompanyWechatId())
                    .setCompanyWechatName(apply.getCompanyWechatName())
                    .setWebsitId(apply.getWebsitId())
                    .setMasterWorkerId(apply.getMasterWorkerId())
                    .setMasterWorkerNumber(apply.getMasterWorkerNumber())
                    .setMasterWorkerName(apply.getMasterWorkerName())
                    .setAssistantWorkerId(apply.getAssistantWorkerId())
                    .setAssistantWorkerNumber(apply.getAssistantWorkerNumber())
                    .setAssistantWorkerName(apply.getAssistantWorkerName())
                    .setStatus(StateEnum.ON.getKey())
                    .insert();
        } else {
            apply.setStatus(status.getKey())
                    .updateById();
        }
    }

    public List<WebsitWorkerBean> queryWebsitWorker(String websitId) {
        CurrentCompanyWechat current = commonLogic.getCurrentCompanyWechat();
        final List<WebsitUser> websitUsers = websitUserService.lambdaQuery()
                .eq(WebsitUser::getCompanyWechatId, current.getUser().getCompanyWechatId())
                .eq(WebsitUser::getWebsitId, websitId)
                .ne(WebsitUser::getUserId, current.getUserId())
                .in(WebsitUser::getExamineStatus, ExamineWorkerStatusEnum.OK.getKey(), ExamineWorkerStatusEnum.EXPIRED.getKey())
                .list();
        if (CollectionUtil.isEmpty(websitUsers)) {
            return new ArrayList<>();
        }
        final List<User> userList = userService.lambdaQuery()
                .eq(User::getCompanyWechatId, current.getUser().getCompanyWechatId())
                .in(User::getUserId, websitUsers.stream().map(WebsitUser::getUserId).collect(Collectors.toList()))
                .list();
        final Map<String, String> userMap = userList.stream().collect(Collectors.toMap(User::getUserId, User::getNickName));

        Map<String, WebsitWorkerBean> workerMap = new HashMap<>();
        for (WebsitUser websitUser : websitUsers) {
            if (userMap.containsKey(websitUser.getUserId())) {
                WebsitWorkerBean bean = new WebsitWorkerBean();
                bean.setWorkerId(websitUser.getUserId());
                bean.setWorkerNumber(websitUser.getWorkerNumber());
                bean.setWorkerName(userMap.get(websitUser.getUserId()));
                workerMap.put(bean.getWorkerId(), bean);
            }
        }
        return new ArrayList<>(workerMap.values());
    }


    public TeamCount count() {
        CurrentCompanyWechat current = commonLogic.getCurrentCompanyWechat();
        final Integer count1 = workerTeamApplyService.lambdaQuery()
                .eq(WorkerTeamApply::getCompanyWechatId, current.getUser().getCompanyWechatId())
                .eq(WorkerTeamApply::getStatus, ExamineStatusEnum.WAIT.getKey())
                .and(v -> v.eq(WorkerTeamApply::getMasterWorkerId, current.getUser().getUserId())
                        .or()
                        .eq(WorkerTeamApply::getAssistantWorkerId, current.getUser().getUserId())
                )
                .count();

        final Integer count2 = workerTeamService.lambdaQuery()
                .eq(WorkerTeam::getCompanyWechatId, current.getUser().getCompanyWechatId())
                .and(v -> v.eq(WorkerTeam::getMasterWorkerId, current.getUser().getUserId())
                        .or()
                        .eq(WorkerTeam::getAssistantWorkerId, current.getUser().getUserId())
                )
                .count();

        TeamCount count = new TeamCount();
        count.setApplyCount(count1);
        count.setTeamCount(count2);
        return count;
    }
}
