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

import com.bcxin.Infrastructures.TenantContext;
import com.bcxin.Infrastructures.UnitWork;
import com.bcxin.Infrastructures.enums.EmploymentStatus;
import com.bcxin.Infrastructures.enums.TrueFalseStatus;
import com.bcxin.Infrastructures.exceptions.BadTenantException;
import com.bcxin.Infrastructures.exceptions.NotAllowedTenantException;
import com.bcxin.Infrastructures.exceptions.NotFoundTenantException;
import com.bcxin.tenant.domain.entities.EmployeeEntity;
import com.bcxin.tenant.domain.entities.OrganizationAdminEntity;
import com.bcxin.tenant.domain.entities.OrganizationEntity;
import com.bcxin.tenant.domain.repositories.EmployeeRepository;
import com.bcxin.tenant.domain.repositories.OrganizationAdminRepository;
import com.bcxin.tenant.domain.repositories.OrganizationRepository;
import com.bcxin.tenant.domain.services.OrganizationAdminService;
import com.bcxin.tenant.domain.services.commands.organizationAdmins.CreateOrganizationAdminCommand;
import com.bcxin.tenant.domain.services.commands.organizationAdmins.DeleteOrganizationAdminCommand;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;

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

@Service
public class OrganizationAdminServiceImpl implements OrganizationAdminService {
    private final OrganizationAdminRepository organizationAdminRepository;
    private final EmployeeRepository employeeRepository;
    private final UnitWork unitWork;
    private final OrganizationRepository organizationRepository;

    public OrganizationAdminServiceImpl(OrganizationAdminRepository organizationAdminRepository,
                                        EmployeeRepository employeeRepository, UnitWork unitWork,
                                        OrganizationRepository organizationRepository) {
        this.organizationAdminRepository = organizationAdminRepository;
        this.employeeRepository = employeeRepository;
        this.unitWork = unitWork;
        this.organizationRepository = organizationRepository;
    }

    @Override
    public void dispatch(CreateOrganizationAdminCommand command) {
        command.validate();
        Collection<EmployeeEntity> employees = this.employeeRepository.getByIds(command.getOrganizationId(), command.getEmployeeIds());
        Collection<String> notFoundEmployeeIds = command.getEmployeeIds().stream().filter(ii -> !employees.stream().anyMatch(ix -> ix.getId().equals(ii)))
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(notFoundEmployeeIds)) {
            throw new NotFoundTenantException(String.format("找不到职员(%s)", notFoundEmployeeIds.stream().collect(Collectors.joining(","))));
        }

        Collection<EmployeeEntity> employeeAdmins = employees.stream().filter(ii -> ii.getDomainAdmin() == TrueFalseStatus.True).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(employeeAdmins)) {
            throw new NotAllowedTenantException(String.format("职员已经是组织管理员(%s)",
                    employeeAdmins.stream().map(ix -> ix.getId())
                            .collect(Collectors.joining(","))));
        }

        this.unitWork.executeTran(() -> {
            employees.forEach(ix -> {
                ix.markAsDomainAdmin(true,false);
                this.employeeRepository.save(ix);
            });
        });
    }

    @Override
    public void dispatch(DeleteOrganizationAdminCommand command) {
        command.validate();
        Collection<EmployeeEntity> employeeAdmins = this.employeeRepository.getByIds(command.getOrganizationId(), command.getIds());

        Collection<String> notFoundOrganizationAdminIds = command.getIds().stream().filter(ii -> !employeeAdmins.stream().anyMatch(ix -> ix.getDomainAdmin() == TrueFalseStatus.True && ix.getId().equals(ii)))
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(notFoundOrganizationAdminIds)) {
            throw new NotFoundTenantException(String.format("找不到组织管理员(%s)", notFoundOrganizationAdminIds.stream().collect(Collectors.joining(","))));
        }

        this.unitWork.executeTran(() -> {
            employeeAdmins.forEach(ix -> {
                ix.markAsDomainAdmin(false, false);
                this.employeeRepository.save(ix);
            });
        });
    }

    @Override
    public void dispatch(OrganizationEntity organization) {
        throw new BadTenantException("未实现");
        /*
        if (organization==null) {
            throw new NotFoundTenantException("无效组织");
        }

        Collection<EmployeeEntity> employees = organization.getEmployees().stream().filter(ii->ii.getStatus()!= EmploymentStatus.OffJob)
                .collect(Collectors.toList());

        if (!CollectionUtils.isEmpty(employees)) {
            this.unitWork.executeTran(() -> {
                employees.forEach(el -> {
                    OrganizationAdminEntity organizationAdmin = OrganizationAdminEntity.create(organization, el);
                    this.organizationAdminRepository.save(organizationAdmin);
                });
            });
        }

         */
    }
}
