package cn.com.qmth.stmms.ms.admin.service;

import cn.com.qmth.stmms.ms.admin.utils.RandomUtils;
import cn.com.qmth.stmms.ms.core.domain.MarkLog;
import cn.com.qmth.stmms.ms.core.domain.Organization;
import cn.com.qmth.stmms.ms.core.domain.Paper;
import cn.com.qmth.stmms.ms.core.domain.user.MarkUser;
import cn.com.qmth.stmms.ms.core.domain.user.Role;
import cn.com.qmth.stmms.ms.core.repository.MarkUserRepo;
import cn.com.qmth.stmms.ms.core.repository.OrganizationRepo;
import cn.com.qmth.stmms.ms.core.repository.PaperRepo;
import cn.com.qmth.stmms.ms.core.vo.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 机构
 */
@Service
public class OrganizationService {

    @Autowired
    private OrganizationRepo organizationRepo;

    @Autowired
    private MarkUserRepo markUserRepo;

    @Autowired
    private PaperRepo paperRepo;

    @Autowired
    RandomUtils randomUtils;

    public Page<Organization> findAll(Specification<Organization> specification, Pageable pageable) {
        return organizationRepo.findAll(specification, pageable);
    }

    @Transactional
    public Organization save(Organization organization) {
        //机构
        MarkUser markUser = organization.getMarkUsers().stream().filter(m -> Objects.equals(m.getUserType(), "1")).findFirst().get();
        if (markUser == null) {
            throw new RuntimeException("机构信息有误");
        }
        Organization organization1 = organizationRepo.findByName(organization.getName());
        if (organization1 != null) {
            throw new RuntimeException("机构名称已存在");
        }
        //机构名称
        organization.setName(markUser.getName());
        //默认启用
        organization.setEnabled(true);
        organization.setCreatedOn(new Date());
        //机构id号
        String abbreviation = randomUtils.organAbbreviation();
        organization.setAbbreviation(abbreviation);
        organizationRepo.save(organization);

        //保存用户
        List<MarkUser> markUsers = organization.getMarkUsers().stream().map(m -> {
            //账号(机构id-账号)
            m.setLoginName(abbreviation.toLowerCase() + "-" + m.getLoginName());
            //密码
            m.setPassword(randomUtils.alphanumericPassword());
            m.setEnabled(true);
            m.setOrganizationId(organization.getId());
            m.setRole(Role.ADMIN);
            m.setWorkId(0l);
            m.setSubject(Subject.SC);
            return m;
        }).collect(Collectors.toList());
        markUserRepo.save(markUsers);
        return organization;
    }

    @Transactional
    public void delete(Long organizationId) {
        //机构下有采集数据，不允许删除
        Paper paper = paperRepo.findOneByOrganizationId(organizationId);
        if (paper != null) {
            throw new RuntimeException("机构下有采集数据，不允许删除");
        }
        //删除机构
        organizationRepo.delete(organizationId);
        //删除机构用户
        markUserRepo.deleteByOrganizationIdAndRole(organizationId, Role.ADMIN);
    }

    @Transactional
    public MarkUser updateOne(MarkUser markUser) {
        MarkUser markUser1 = markUserRepo.findOne(markUser.getId());
        Organization organization = organizationRepo.findByName(markUser1.getName());
        if (organization != null && Objects.equals(markUser1.getUserType(), "1")) {
            //机构名称不能重复
            Organization organization1 = organizationRepo.findByName(markUser.getName());
            if (organization1 != null && organization.getId() != organization1.getId()) {
                throw new RuntimeException("机构名称已存在");
            }
            organization.setName(markUser.getName());
            organizationRepo.save(organization);
        }

        if (!Objects.equals(markUser.getLoginName(), markUser1.getLoginName())) {
            throw new RuntimeException("账号不允许修改");
        }
        markUser1.setName(markUser.getName());
        markUser1.setPassword(markUser.getPassword());
        return markUserRepo.save(markUser1);
    }
}
