package com.cool.store.service.impl;


import com.cool.store.dao.EnterpriseUserDAO;
import com.cool.store.dao.OperationLogDAO;
import com.cool.store.dao.ShopAuditInfoDAO;
import com.cool.store.dto.OperationLogDTO;
import com.cool.store.entity.EnterpriseUserDO;
import com.cool.store.entity.OperationLogDO;
import com.cool.store.entity.ShopAuditInfoDO;
import com.cool.store.enums.*;
import com.cool.store.enums.point.ShopSubStageStatusEnum;
import com.cool.store.response.AuditInfoResponse;
import com.cool.store.service.OperationLogService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


@Service
public class OperationLogServiceImpl implements OperationLogService {


    @Resource
    private ShopAuditInfoDAO shopAuditInfoDAO;
    @Resource
    private OperationLogDAO operationLogDAO;
    @Resource
    private EnterpriseUserDAO enterpriseUserDAO;


    @Override
    public Boolean addOperationLog(Long shopId, ShopSubStageStatusEnum shopSubStageStatusEnum, String userId, String userName, OperationTypeEnum operationTypeEnum, String remark, OperationStatusEnum operationStatusEnum) {
        OperationLogDO OperationLogDO = new OperationLogDO();
        OperationLogDO.setShopId(shopId);
        OperationLogDO.setShopSubStage(shopSubStageStatusEnum.getShopSubStageEnum().getShopSubStage());
        OperationLogDO.setShopSubStageStatus(shopSubStageStatusEnum.getShopSubStageStatus());
        OperationLogDO.setType(operationTypeEnum.getCode());
        OperationLogDO.setStatus(operationStatusEnum.getCode());
        OperationLogDO.setOperatorName(userName);
        OperationLogDO.setOperator(userId);
        OperationLogDO.setCreateUserId(userId);
        OperationLogDO.setRemarks(remark);
        OperationLogDO.setCreateTime(new Date());
        OperationLogDO.setUpdateTime(new Date());
        operationLogDAO.addOperationLog(OperationLogDO);
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long addOperationLog(Long shopId, ShopSubStageStatusEnum shopSubStageStatusEnum, String userId, List<EnterpriseUserDO> operationUserList, OperationTypeEnum operationTypeEnum, String remark, OperationStatusEnum operationStatusEnum) {
        List<OperationLogDO> operationLogDOList = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.SECOND, 1);
        Date date = calendar.getTime();
        for (EnterpriseUserDO operationUser : operationUserList) {
            OperationLogDO OperationLogDO = new OperationLogDO();
            OperationLogDO.setShopId(shopId);
            OperationLogDO.setShopSubStage(shopSubStageStatusEnum.getShopSubStageEnum().getShopSubStage());
            OperationLogDO.setShopSubStageStatus(shopSubStageStatusEnum.getShopSubStageStatus());
            OperationLogDO.setType(operationTypeEnum.getCode());
            OperationLogDO.setStatus(operationStatusEnum.getCode());
            OperationLogDO.setOperatorName(operationUser.getName());
            OperationLogDO.setOperator(operationUser.getUserId());
            OperationLogDO.setCreateUserId(userId);
            OperationLogDO.setRemarks(remark);
            OperationLogDO.setCreateTime(date);
            OperationLogDO.setUpdateTime(date);
            operationLogDOList.add(OperationLogDO);
        }
        return operationLogDAO.batchAddOperationLog(operationLogDOList);
    }

    @Override
    public List<AuditInfoResponse> getAuditInfo(Long shopId, List<Integer> shopSubStageList) {
        List<AuditInfoResponse> responses = new ArrayList<>();
        List<OperationLogDO> logList = operationLogDAO.getByShopSubStage(shopId, shopSubStageList, null);
        Map<Date, List<OperationLogDO>> operationLogMap = logList.stream().collect(Collectors.groupingBy(OperationLogDO::getCreateTime));
        for (Date date : operationLogMap.keySet()) {
            List<OperationLogDO> operations = operationLogMap.get(date);
            AuditInfoResponse auditInfoResponse = new AuditInfoResponse();
            List<AuditInfoResponse.AuditUserInfoVO> list = new ArrayList<>();
            List<String> userIds = new ArrayList<>();
            Long auditId = null;
            Integer operationType = 0;
            for (OperationLogDO operationLogDO : operations) {
                //提交时候只会有一个人
                if (operationLogDO.getType().equals(OperationTypeEnum.OPERATION_TYPE_0.getCode())) {
                    operationType = operationLogDO.getType();
                    auditInfoResponse.setType(OperationLogAuditEnum.SUBMIT_AUDIT.getCode());
                    auditInfoResponse.setStatus(operationLogDO.getStatus());
                    auditInfoResponse.setExecute(AuditExecuteEnum.FRANCHISEES.getCode());
                    AuditInfoResponse.AuditUserInfoVO user = new AuditInfoResponse.AuditUserInfoVO();
                    user.setUserId(operationLogDO.getOperator());
                    user.setName(operationLogDO.getOperatorName());
                    auditInfoResponse.setList(Collections.singletonList(user));
                    auditInfoResponse.setActualUserId(operationLogDO.getOperator());
                    auditInfoResponse.setCreateTime(operationLogDO.getCreateTime());

                }
                //审批
                if (operationLogDO.getType().equals(OperationTypeEnum.OPERATION_TYPE_1.getCode())) {
                    if (operationLogDO.getShopSubStageStatus().equals(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_181.getShopSubStageStatus())
                            || operationLogDO.getShopSubStageStatus().equals(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_193.getShopSubStageStatus())
                            || operationLogDO.getShopSubStageStatus().equals(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_201.getShopSubStageStatus())
                            || operationLogDO.getShopSubStageStatus().equals(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_213.getShopSubStageStatus())
                            || operationLogDO.getShopSubStageStatus().equals(ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_221.getShopSubStageStatus())
                    ) {
                        auditInfoResponse.setExecute(AuditExecuteEnum.HEADQUARTERS.getCode());
                    }else {
                        auditInfoResponse.setExecute(AuditExecuteEnum.OPERATION.getCode());
                    }

                    operationType = operationLogDO.getType();
                    userIds.add(operationLogDO.getOperator());
                    if (Objects.isNull(operationLogDO.getUpdateTime())) {
                        auditInfoResponse.setCreateTime(operationLogDO.getCreateTime());
                    } else {
                        auditInfoResponse.setCreateTime(operationLogDO.getUpdateTime());
                    }
                    auditInfoResponse.setStatus(operationLogDO.getStatus());
                    // 判断审批人
                    if (Objects.nonNull(operationLogDO.getAuditResultId())) {
                        auditId = operationLogDO.getAuditResultId();
                        auditInfoResponse.setActualUserId(operationLogDO.getOperator());
                        auditInfoResponse.setRemark(operationLogDO.getRemarks());
                    }
                }
            }
            if (operationType.equals(OperationTypeEnum.OPERATION_TYPE_1.getCode())) {
                Map<String, EnterpriseUserDO> userInfoMap = enterpriseUserDAO.getUserInfoMap(userIds);
                for (EnterpriseUserDO enterpriseUserDO : userInfoMap.values()) {
                    AuditInfoResponse.AuditUserInfoVO user = new AuditInfoResponse.AuditUserInfoVO();
                    user.setUserId(enterpriseUserDO.getUserId());
                    user.setName(enterpriseUserDO.getName());
                    user.setAvatar(enterpriseUserDO.getAvatar());
                    list.add(user);
                }
                auditInfoResponse.setList(list);
                if (Objects.nonNull(auditId)) {
                    ShopAuditInfoDO auditInfo = shopAuditInfoDAO.getAuditInfo(auditId);
                    if (Objects.nonNull(auditInfo)) {
                        if (auditInfo.getResultType().equals(AuditResultTypeEnum.PASS.getCode())) {
                            auditInfoResponse.setType(OperationLogAuditEnum.PASS.getCode());
                            auditInfoResponse.setRemark(auditInfo.getPassReason());
                        } else {
                            auditInfoResponse.setRemark(auditInfo.getRejectReason());
                            auditInfoResponse.setType(OperationLogAuditEnum.REFUSE.getCode());
                        }
                    }
                } else {
                    auditInfoResponse.setType(OperationLogAuditEnum.WAIT_AUDIT.getCode());
                }

            }
            responses.add(auditInfoResponse);
        }
        return responses.stream().sorted(Comparator.comparing(AuditInfoResponse::getCreateTime)).collect(Collectors.toList());
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchUpdateProcessed(List<OperationLogDO> operationLogs, Long audit, String userId, String reason) {
        List<OperationLogDO> operationLogList = new ArrayList<>();
        for (OperationLogDO operationLogDO : operationLogs) {
            operationLogDO.setUpdateTime(new Date());
            operationLogDO.setUpdateUserId(userId);
            operationLogDO.setStatus(OperationStatusEnum.PROCESSED.getCode());
            if (operationLogDO.getOperator().equals(userId)) {
                operationLogDO.setAuditResultId(audit);
            }
            operationLogDO.setRemarks(reason);
            operationLogList.add(operationLogDO);
        }
        return operationLogDAO.batchUpdateByPrimaryKeySelective(operationLogList);
    }

}




