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

import com.bcxin.Infrastructures.exceptions.ArgumentTenantException;
import com.bcxin.Infrastructures.exceptions.BadTenantException;
import com.bcxin.Infrastructures.exceptions.NotFoundTenantException;
import com.bcxin.tenant.domain.entities.DepartmentAdminEntity;
import com.bcxin.tenant.domain.entities.DepartmentEntity;
import com.bcxin.tenant.domain.entities.EmployeeEntity;
import com.bcxin.tenant.domain.repositories.DepartmentAdminRepository;
import com.bcxin.tenant.domain.repositories.DepartmentRepository;
import com.bcxin.tenant.domain.repositories.EmployeeRepository;
import com.bcxin.tenant.domain.services.DepartAdminService;
import com.bcxin.tenant.domain.services.commands.BatchCreateDepartAdminCommand;
import com.bcxin.tenant.domain.services.commands.BatchDeleteDepartAdminCommand;
import com.bcxin.tenant.domain.services.commands.UpdateDepartAdminCommand;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

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

@Service
public class DepartAdminServiceImpl implements DepartAdminService {
    private final DepartmentAdminRepository departmentAdminRepository;
    private final DepartmentRepository departmentRepository;
    private final EmployeeRepository employeeRepository;

    public DepartAdminServiceImpl(DepartmentAdminRepository departmentAdminRepository,
                                  DepartmentRepository departmentRepository,
                                  EmployeeRepository employeeRepository) {
        this.departmentAdminRepository = departmentAdminRepository;
        this.departmentRepository = departmentRepository;
        this.employeeRepository = employeeRepository;
    }

    @Override
    public void dispatch(BatchCreateDepartAdminCommand command) {
        command.validate();

        Collection<DepartmentEntity> departmentEntities =
                this.departmentRepository.getByIds(command.getOrganizationId(), command.getDepartIds());
        Collection<String> notExistsDepartmentIds = command.getDepartIds().stream()
                .filter(ii -> !departmentEntities.stream().anyMatch(ix -> ix.getId().equals(ii)))
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(notExistsDepartmentIds)) {
            throw new NotFoundTenantException(String.format("找不到部门(%s)信息",
                    notExistsDepartmentIds.stream().collect(Collectors.joining(","))));
        }

        Collection<EmployeeEntity> employeeEntities = this.employeeRepository.getByIds(command.getOrganizationId(), command.getEmployeeIds());
        Collection<String> notExistsEmployeeIds = command.getEmployeeIds().stream()
                .filter(ii -> !employeeEntities.stream().anyMatch(ix -> ix.getId().equals(ii)))
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(notExistsDepartmentIds)) {
            throw new NotFoundTenantException(String.format("找不到职员(%s)信息",
                    notExistsEmployeeIds.stream().collect(Collectors.joining(","))));
        }

        this.departmentAdminRepository.batchCreate(employeeEntities, departmentEntities);
    }

    @Override
    public void dispatch(UpdateDepartAdminCommand command) {
        command.validate();

        Collection<DepartmentEntity> departmentEntities =
                this.departmentRepository.getByIds(command.getOrganizationId(), command.getDepartIds());
        Collection<String> notExistsDepartmentIds = command.getDepartIds().stream()
                .filter(ii -> !departmentEntities.stream().anyMatch(ix -> ix.getId().equals(ii)))
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(notExistsDepartmentIds)) {
            throw new NotFoundTenantException(String.format("找不到部门(%s)信息",
                    notExistsDepartmentIds.stream().collect(Collectors.joining(","))));
        }

        Optional<EmployeeEntity> employeeEntity = this.employeeRepository.findById(command.getEmployeeId());
        if(employeeEntity.isPresent()){
            this.departmentAdminRepository.update(employeeEntity.get(), departmentEntities);
        }else{
            throw new ArgumentTenantException("职员信息无效!");
        }
    }

    @Override
    public void dispatch(BatchDeleteDepartAdminCommand command) {
        command.validate();

        Collection<DepartmentAdminEntity> departmentAdminEntities =
                this.departmentAdminRepository.getByEmployeeIds(command.getOrganizationId(), command.getEmployeeIds());

        Collection<String> notExistsDepartAdminIds = command.getEmployeeIds().stream().filter(ii ->
                !departmentAdminEntities.stream().anyMatch(ix -> ix.getEmployee().getId().equals(ii))).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(notExistsDepartAdminIds)) {
            throw new NotFoundTenantException(String.format("找不到部门管理员(%s)信息", notExistsDepartAdminIds.stream().collect(Collectors.joining(","))));
        }

        this.departmentAdminRepository.batchDelete(command.getEmployeeIds());
    }
}
