package com.bcxin.tenant.domain.services.impls;

import com.bcxin.Infrastructures.TenantContext;
import com.bcxin.Infrastructures.TenantUserContext;
import com.bcxin.Infrastructures.enums.ActionType;
import com.bcxin.Infrastructures.UnitWork;
import com.bcxin.Infrastructures.enums.InviteType;
import com.bcxin.Infrastructures.enums.OrganizationLevel;
import com.bcxin.Infrastructures.enums.RelationshipsStatus;
import com.bcxin.Infrastructures.exceptions.BadTenantException;
import com.bcxin.Infrastructures.exceptions.ForbidTenantException;
import com.bcxin.api.interfaces.tenants.requests.organizationRelationship.OrganizationRelationshipCreateRequest;
import com.bcxin.api.interfaces.tenants.requests.organizationRelationship.OrganizationRelationshipStatusUpdateRequest;
import com.bcxin.tenant.domain.entities.*;
import com.bcxin.tenant.domain.repositories.*;
import com.bcxin.tenant.domain.repositories.dtos.OrganizationDto;
import com.bcxin.tenant.domain.services.OrganizationRelationshipService;
import com.bcxin.tenant.domain.services.commands.organizationrelationship.OrganizationRelationshipInfoUpdateCommand;
import io.jsonwebtoken.lang.Collections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class OrganizationRelationshipServiceImpl implements OrganizationRelationshipService {
    private final Logger logger = LoggerFactory.getLogger(OrganizationRelationshipServiceImpl.class);

    private final OrganizationRelationshipRepository organizationRelationshipRepository;

    private final OrganizationTypeRepository organizationTypeRepository;

    private final InviteOrganizationRelationshipRepository inviteOrganizationRelationshipRepository;

    private final OrganizationRepository organizationRepository;

    private final UnitWork unitWork;

    private final OrganizationRelationshipActionHistoriesRepository organizationRelationshipActionHistoriesRepository;

    public OrganizationRelationshipServiceImpl(OrganizationRelationshipRepository organizationRelationshipRepository, OrganizationTypeRepository organizationTypeRepository, InviteOrganizationRelationshipRepository inviteOrganizationRelationshipRepository, OrganizationRepository organizationRepository,UnitWork unitWork, OrganizationRelationshipActionHistoriesRepository organizationRelationshipActionHistoriesRepository) {
        this.organizationRelationshipRepository = organizationRelationshipRepository;
        this.organizationTypeRepository = organizationTypeRepository;
        this.inviteOrganizationRelationshipRepository = inviteOrganizationRelationshipRepository;
        this.organizationRepository = organizationRepository;
        this.unitWork = unitWork;
        this.organizationRelationshipActionHistoriesRepository = organizationRelationshipActionHistoriesRepository;
    }


    @Override
    public void join(OrganizationRelationshipCreateRequest organizationRelationshipCreateRequest) {

        //如果邀请类型是集团码
        if (organizationRelationshipCreateRequest.getInviteType() == InviteType.GroupCode) {

            //通过集团码获取集团的信息
            Collection<InviteOrganizationRelationshipEntity> inviteOrganizationRelationshipEntities =
                    inviteOrganizationRelationshipRepository.findByCode(organizationRelationshipCreateRequest.getGroupCode());
            if (inviteOrganizationRelationshipEntities.size() == 0) {
                throw new ForbidTenantException("集团码不存在");
            }
            if (inviteOrganizationRelationshipEntities != null && inviteOrganizationRelationshipEntities.size() > 0) {
                String organizationId = inviteOrganizationRelationshipEntities.iterator().next().getOrganizationId();
                Optional<OrganizationEntity> optional = organizationRepository.findById(organizationId);
                if (optional.isPresent()) {
                    OrganizationEntity organization = optional.get();
                    if (!OrganizationLevel.contain(organization.getOrganizationLevel(),OrganizationLevel.Premium)){
                        throw new ForbidTenantException("请求加入的组织不是集团组织！");
                    }
                    TenantUserContext.UserModel currentUser = TenantContext.getInstance().getUserContext().get();
                    if (currentUser == null) {
                        throw new ForbidTenantException("必须有人来操作离职");
                    }
                    String tranId=unitWork.beginTransaction();
                    try {
                        //新增组织关系
                        OrganizationRelationshipEntity organizationRelationshipEntity = organizationRelationshipRepository.save(
                                OrganizationRelationshipEntity.create(
                                        organization.getId(),
                                        organization.getName(),
                                        organizationRelationshipCreateRequest.getSelectedOrganizationId(),
                                        organizationRelationshipCreateRequest.getSelectedOrganizationName(),
                                        null,
                                        null,
                                        null,
                                        null,
                                        null,
                                        organization.getId() + "---" + organizationRelationshipCreateRequest.getSelectedOrganizationId(),
                                        RelationshipsStatus.Verify,
                                        null,
                                        null,
                                        null,
                                        null,
                                        organization.getId(),
                                        currentUser.getId(),
                                        organizationRelationshipCreateRequest.getInviteType()));
                        //添加组织关系操作记录
                        organizationRelationshipActionHistoriesRepository.save(OrganizationRelationshipActionHistoriesEntity.
                                create(organizationRelationshipEntity.getId(),
                                        ActionType.Request, "", organizationRelationshipCreateRequest.getSelectedOrganizationId()
                                        , currentUser.getId(), organizationRelationshipCreateRequest.getInviteType()));
                        unitWork.commit(tranId);

                    } catch (Exception e) {
                        unitWork.rollback(tranId);
                        //如果新增失败，通过组织id和被选中的组织id查询是否已经存在了
                        Collection<OrganizationRelationshipEntity> byOrganizationIdAndSelectedOrganizationId =
                                organizationRelationshipRepository.findByOrganizationIdAndSelectedOrganizationId(organization.getId(),
                                        organizationRelationshipCreateRequest.getSelectedOrganizationId());
                        //如果不存在则抛出异常
                        if (byOrganizationIdAndSelectedOrganizationId.size() == 0) {
                            throw e;
                        } else {
                            //如果存在，则判断该条记录是否是逻辑删除状态，如果是逻辑删除，这恢复数据为有效数据，并且初始化请求，如果不是逻辑删除，则抛出异常，组织关系已存在
                            OrganizationRelationshipEntity organizationRelationshipEntity1 = byOrganizationIdAndSelectedOrganizationId.iterator().next();

                            if (organizationRelationshipEntity1.isDeleted()) {
                                String tranId2=unitWork.beginTransaction();
                                try {
                                    organizationRelationshipEntity1.restartRelationship(organizationRelationshipCreateRequest.getInviteType());
                                    organizationRelationshipRepository.save(organizationRelationshipEntity1);

                                    organizationRelationshipActionHistoriesRepository.save(OrganizationRelationshipActionHistoriesEntity.
                                            create(organizationRelationshipEntity1.getId(),
                                                    ActionType.Request, "", organizationRelationshipCreateRequest.getSelectedOrganizationId()
                                                    , currentUser.getId(), organizationRelationshipCreateRequest.getInviteType()));
                                    unitWork.commit(tranId2);
                                }catch (Exception e2){
                                    unitWork.rollback(tranId2);
                                    throw e2;
                                }
                            } else {
                                throw new ForbidTenantException("组织关系已存在");
                            }

                        }
                    }
                }


            }
        }
        //如果邀请类型是邀请
        //如果邀请类型是连接
        //如果邀请类型是二维码
    }

    @Override
    public void updateOrganizationRelationshipStatus(String organizationId,OrganizationRelationshipStatusUpdateRequest organizationRelationshipStatusUpdateRequest) {
        OrganizationRelationshipEntity organizationRelationshipEntity =
                organizationRelationshipRepository.findById(organizationRelationshipStatusUpdateRequest.getId());
        if (organizationRelationshipEntity == null) {
            throw new ForbidTenantException("组织关系不存在！");
        }
        if (!organizationRelationshipEntity.getOrganizationId().equals(organizationId)) {
            throw new ForbidTenantException("当前集团组织无效！");
        }
        Optional<OrganizationEntity> optional = organizationRepository.findById(organizationId);
        if (optional.isPresent()) {
            OrganizationEntity organization = optional.get();
            if (!OrganizationLevel.contain(organization.getOrganizationLevel(),OrganizationLevel.Premium)){
                throw new ForbidTenantException("当前组织不是集团组织！");
            }
        }
        String tranId=unitWork.beginTransaction();
        try {
            //修改组织关系状态
            organizationRelationshipEntity.changeRelationshipStatus(organizationRelationshipStatusUpdateRequest.getStatus());
            organizationRelationshipRepository.save(organizationRelationshipEntity);

            //添加操作记录
            TenantUserContext.UserModel currentUser = TenantContext.getInstance().getUserContext().get();
            //判断修改的组织状态是否是已关联
            if (organizationRelationshipStatusUpdateRequest.getStatus() == RelationshipsStatus.Related){
                organizationRelationshipActionHistoriesRepository.save(OrganizationRelationshipActionHistoriesEntity.create(
                        organizationRelationshipStatusUpdateRequest.getId(),
                        ActionType.Confirm, "", organizationId,
                        currentUser.getId(),organizationRelationshipEntity.getInviteType()));
            //判断修改的组织状态是否是待确认
            }else if (organizationRelationshipStatusUpdateRequest.getStatus() == RelationshipsStatus.TargetVerify
                    || organizationRelationshipStatusUpdateRequest.getStatus() == RelationshipsStatus.Verify){
                organizationRelationshipActionHistoriesRepository.save(OrganizationRelationshipActionHistoriesEntity.create(
                        organizationRelationshipStatusUpdateRequest.getId(),
                        ActionType.Request, "", organizationId,
                        currentUser.getId(),organizationRelationshipEntity.getInviteType()));
            //修改的组织状态为已拒绝
            }else {
                organizationRelationshipActionHistoriesRepository.save(OrganizationRelationshipActionHistoriesEntity.create(
                        organizationRelationshipStatusUpdateRequest.getId(),
                        ActionType.Refuse, "", organizationId,
                        currentUser.getId(),organizationRelationshipEntity.getInviteType()));
            }
            unitWork.commit(tranId);
        }catch (Exception e){
            unitWork.rollback(tranId);
            throw e;
        }

    }

    @Override
    public void updateOrganizationRelationshipInfo(OrganizationRelationshipInfoUpdateCommand command) {
        OrganizationRelationshipEntity organizationRelationshipEntity =
                organizationRelationshipRepository.findById(command.getId());
        if (organizationRelationshipEntity == null ||
                !command.getOrganizationId().equals(organizationRelationshipEntity.getOrganizationId())) {
            throw new BadTenantException("组织关系不存在");
        }

        OrganizationTypeEntity organizationTypeEntity = null;
        if(command.getOrganizationTypeId() != null){
            Optional<OrganizationTypeEntity> organizationTypeOptional = organizationTypeRepository.findById(command.getOrganizationTypeId());
            if(organizationTypeOptional.isPresent()){
                organizationTypeEntity = organizationTypeOptional.get();
            }else{
                throw new BadTenantException("组织类型不存在");
            }
        }
        String tranId=unitWork.beginTransaction();
        try {
        organizationRelationshipEntity.changeRelationshipInfo(command.getOrganizationNote(),
                organizationTypeEntity,
                command.getParentId(),
                command.getParentName(),
                command.getParentIndex(),
                command.getCode(),
                command.getContactName(),
                command.getContactTelephone());
        organizationRelationshipRepository.save(organizationRelationshipEntity);
            unitWork.commit(tranId);
        }catch (Exception e){
            unitWork.rollback(tranId);
            throw e;
        }
    }

    @Override
    public void delete(Collection<Long> ids,String organizationId) {
        if (ids == null) {
            throw new ForbidTenantException("需要删除组织关系id不能为空");
        }
        if (organizationId.isEmpty()){
            throw new ForbidTenantException("集团组织id不能为空");
        }
        Collection<OrganizationRelationshipEntity> organizationRelationshipEntities = organizationRelationshipRepository.findAllById(ids);
        if (!Collections.isEmpty(organizationRelationshipEntities)){
            organizationRelationshipEntities.forEach(organizationRelationshipEntity -> {
                organizationRelationshipEntity.removeRelationship();
            });
            String tranId=unitWork.beginTransaction();
            try {
                organizationRelationshipRepository.saveAll(organizationRelationshipEntities);
                TenantUserContext.UserModel currentUser = TenantContext.getInstance().getUserContext().get();
                Collection<OrganizationRelationshipActionHistoriesEntity> organizationRelationshipActionHistoriesEntities
                        = organizationRelationshipEntities.stream().map(organizationRelationshipEntity -> {
                    return OrganizationRelationshipActionHistoriesEntity.create(organizationRelationshipEntity.getId(), ActionType.Delete, "", organizationId,
                            currentUser.getId(),organizationRelationshipEntity.getInviteType());
                }).collect(Collectors.toList());
                organizationRelationshipActionHistoriesRepository.saveAll(organizationRelationshipActionHistoriesEntities);
                unitWork.commit(tranId);
            }catch (Exception e){
                unitWork.rollback(tranId);
                throw e;
            }
        }


    }
}
