package com.zhongshu.card.server.core.service.orgManager;

import com.github.microservice.auth.security.type.AuthType;
import com.github.microservice.components.data.base.util.PageEntityUtil;
import com.github.microservice.net.ResultContent;
import com.github.microservice.net.ResultMessage;
import com.zhongshu.card.client.model.org.OrganizationMiniModel;
import com.zhongshu.card.client.model.org.OrganizationRelationSearch;
import com.zhongshu.card.client.model.orgModel.ProjectBindOrgModel;
import com.zhongshu.card.client.model.orgModel.ProjectBindOrgParam;
import com.zhongshu.card.client.model.orgModel.ProjectBindOrgsParam;
import com.zhongshu.card.client.type.OrganizationRelationType;
import com.zhongshu.card.server.core.dao.org.OrganizationDao;
import com.zhongshu.card.server.core.dao.org.OrganizationRelationDao;
import com.zhongshu.card.server.core.dao.org.OrganizationUserDao;
import com.zhongshu.card.server.core.dao.projectAbout.PayShareListDao;
import com.zhongshu.card.server.core.domain.org.Organization;
import com.zhongshu.card.server.core.domain.org.OrganizationRelation;
import com.zhongshu.card.server.core.domain.paySetting.PayShareList;
import com.zhongshu.card.server.core.service.base.SuperService;
import com.zhongshu.card.server.core.service.projectAbout.PayShareListService;
import com.zhongshu.card.server.core.service.user.UserAccountServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 项目绑定机构管理
 *
 * @author TRX
 * @date 2024/5/31
 */
@Slf4j
@Service
public class ProjectBindOrgServiceImpl extends SuperService {

    @Autowired
    private OrganizationDao organizationDao;

    @Autowired
    private OrganizationManagerServiceImpl organizationManagerService;

    @Autowired
    private OrganizationRelationDao organizationRelationDao;

    @Autowired
    private PayShareListDao payShareListDao;

    @Autowired
    private UserAccountServiceImpl userAccountService;

    @Autowired
    private PayShareListService payShareListService;

    @Autowired
    private OrganizationUserDao organizationUserDao;

    /**
     * 项目绑定机构信息
     *
     * @param param
     * @return
     */
    @Transactional
    public ResultContent projectBindOrg(ProjectBindOrgParam param) {
        String projectOid = param.getProjectOid();
        String orgOid = param.getOrgOid();
        Organization projectInfo = organizationDao.findTopByOid(projectOid);
        if (ObjectUtils.isEmpty(projectInfo)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, projectInfo));
        }
        if (projectInfo.getAuthType() != AuthType.Project) {
            return ResultContent.buildFail(String.format("不属于项目类型：%s", projectOid));
        }

        // 选择的结构信息
        Organization orgInfo = organizationDao.findTopByOid(orgOid);
        if (ObjectUtils.isEmpty(projectInfo)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, orgOid));
        }
        if (orgInfo.getIsOrg() == null || !orgInfo.getIsOrg()) {
            return ResultContent.buildFail(String.format("不属于机构类型：%s", orgOid));
        }

        OrganizationRelation organizationRelation = organizationRelationDao.findTopByMainOrganizationAndRelOrganizationAndRelationType(projectInfo, orgInfo, OrganizationRelationType.ProjectBindOrg);
        if (ObjectUtils.isNotEmpty(organizationRelation)) {
            return ResultContent.buildFail(String.format("项目已绑定机构：%s", orgInfo.getName()));
        }
        PayShareList payShareList = null;
        if (StringUtils.isNotEmpty(param.getPayShareListId())) {
            payShareList = payShareListDao.findTopById(param.getPayShareListId());
            if (ObjectUtils.isEmpty(payShareList)) {
                return ResultContent.buildFail(String.format("分组规则不存在：%s", param.getPayShareListId()));
            }
        }

        organizationRelation = new OrganizationRelation();
        BeanUtils.copyProperties(param, organizationRelation);
        organizationRelation.setMainOrganization(projectInfo);
        organizationRelation.setMainName(projectInfo.getName());
        organizationRelation.setAuthType(projectInfo.getAuthType());
        organizationRelation.setPayShareList(payShareList);

        organizationRelation.setRelOrganization(orgInfo);
        organizationRelation.setRelName(orgInfo.getName());
        organizationRelation.setRelAuthType(orgInfo.getAuthType());
        organizationRelation.setRelationType(OrganizationRelationType.ProjectBindOrg);

        organizationRelation.setAboutOid(projectInfo.getOid());
        organizationRelation.setAboutAuthType(projectInfo.getAuthType());

        organizationRelationDao.save(organizationRelation);
        return ResultContent.buildSuccess();
    }

    public ResultContent projectBindOids(ProjectBindOrgsParam param) {
        String projectOid = param.getProjectOid();
        Organization projectInfo = organizationDao.findTopByOid(projectOid);
        if (ObjectUtils.isEmpty(projectInfo)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, projectInfo));
        }
        if (projectInfo.getAuthType() != AuthType.Project) {
            return ResultContent.buildFail(String.format("不属于项目类型：%s", projectOid));
        }
        if (ObjectUtils.isNotEmpty(param.getOrgOids())) {
            List<OrganizationRelation> list = new ArrayList<>();
            for (String oid : param.getOrgOids()) {
                Organization orgInfo = organizationDao.findTopByOid(oid);
                if (ObjectUtils.isEmpty(orgInfo)) {
                    continue;
                }

                OrganizationRelation orgRelation = null;
                if (ObjectUtils.isNotEmpty(orgInfo)) {
                    orgRelation = organizationRelationDao.findTopByMainOrganizationAndRelOrganizationAndRelationType(projectInfo, orgInfo, OrganizationRelationType.ProjectBindOrg);
                }
                if (ObjectUtils.isEmpty(orgRelation)) {
                    orgRelation = new OrganizationRelation();
                }
                BeanUtils.copyProperties(param, orgRelation);
                orgRelation.setMainOrganization(projectInfo);
                orgRelation.setMainName(projectInfo.getName());
                orgRelation.setAuthType(projectInfo.getAuthType());
                orgRelation.setMainOid(projectInfo.getOid());

                orgRelation.setRelOrganization(orgInfo);
                orgRelation.setRelName(orgInfo.getName());
                orgRelation.setRelAuthType(orgInfo.getAuthType());
                orgRelation.setRelationType(OrganizationRelationType.ProjectBindOrg);
                orgRelation.setRelOid(orgInfo.getOid());

                orgRelation.setAboutOid(projectInfo.getOid());
                orgRelation.setAboutAuthType(projectInfo.getAuthType());
                list.add(orgRelation);
            }
            organizationRelationDao.saveAll(list);
        }
        return ResultContent.buildSuccess();
    }

    /**
     * 项目下的 机构列表
     *
     * @param param
     * @param pageable
     * @return
     */
    public ResultContent<Page<ProjectBindOrgModel>> orgPage(OrganizationRelationSearch param, Pageable pageable) {
        // projectOid
        Assert.hasText(param.getProjectOid(), "projectOid不能为空");
        Organization organization = organizationDao.findTopByOid(param.getProjectOid());
        if (ObjectUtils.isEmpty(organization)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, param.getProjectOid()));
        }
        param.setMainId(organization.getId());
        Page<OrganizationRelation> page = organizationRelationDao.page(pageable, param);
        return ResultContent.buildSuccess(PageEntityUtil.concurrent2PageModel(page, this::toModel));
    }

    /**
     * 查询项目绑定的所有机构
     *
     * @param projectOid
     * @return
     */
    public ResultContent<List<OrganizationMiniModel>> getProjectOrgList(String projectOid) {
        List<OrganizationMiniModel> models = new ArrayList<>();
        Organization projectInfo = organizationDao.findTopByOid(projectOid);
        if (ObjectUtils.isEmpty(projectInfo)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, projectOid));
        }
        // 关系
        List<OrganizationRelation> list = organizationRelationDao.findByMainOrganizationAndRelationType(projectInfo, OrganizationRelationType.ProjectBindOrg);
        if (ObjectUtils.isNotEmpty(list)) {
            models = list.stream().map(it -> {
                return organizationManagerService.toMiniModel(it.getRelOrganization());
            }).collect(Collectors.toList());
        }
        return ResultContent.buildSuccess(models);
    }

    /**
     * 删除关系
     *
     * @param id
     * @return
     */
    public ResultContent deleteRelation(String id) {
        OrganizationRelation relation = organizationRelationDao.findTopById(id);
        if (ObjectUtils.isEmpty(relation)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
        }
        // 判断是否可以删除
        Organization organization = relation.getRelOrganization();
        long count = organizationUserDao.countByOrganization(organization);
        if (count > 0) {
            return ResultContent.buildFail(String.format("%s已绑定用户，不能删除", organization.getName()));
        }
        organizationRelationDao.delete(relation);
        return ResultContent.buildSuccess();
    }

    public ResultContent getDetailRelation(String id) {
        OrganizationRelation relation = organizationRelationDao.findTopById(id);
        if (ObjectUtils.isEmpty(relation)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
        }
        return ResultContent.buildSuccess(toModel(relation));
    }

    /**
     * 统计结构绑定的项目数量
     *
     * @param orgOid
     * @return
     */
    public long countOrgBindNumber(String orgOid) {
        Organization organization = organizationDao.findTopByOid(orgOid);
        if (ObjectUtils.isEmpty(organization)) {
            return 0;
        }
        return organizationRelationDao.countByRelOrganizationAndRelationType(organization, OrganizationRelationType.ProjectBindOrg);
    }

    /**
     * 统计项目绑定的 机构数量
     *
     * @param projectOid
     * @return
     */
    public long countProjectBindNumber(String projectOid) {
        Organization organization = organizationDao.findTopByOid(projectOid);
        if (ObjectUtils.isEmpty(organization)) {
            return 0;
        }
        return organizationRelationDao.countByMainOrganizationAndRelationType(organization, OrganizationRelationType.ProjectBindOrg);
    }

    /**
     * 得到机构绑定的项目列表
     *
     * @param oid
     * @return
     */
    public List<Organization> getOrgBindProjects(String oid) {
        List<Organization> list = new ArrayList<>();
        Organization organization = organizationDao.findTopByOid(oid);
        if (ObjectUtils.isNotEmpty(organization)) {
            List<OrganizationRelation> _list = organizationRelationDao.findByRelOrganizationAndRelationType(organization, OrganizationRelationType.ProjectBindOrg);
            if (ObjectUtils.isNotEmpty(_list)) {
                list = _list.stream().map(it -> it.getMainOrganization()).collect(Collectors.toList());
            }
        }
        return list;
    }

    /**
     * 得到项目绑定的机构列表信息
     *
     * @param projectOid
     * @return
     */
    public List<Organization> getProjectBindOrgs(String projectOid) {
        List<Organization> list = new ArrayList<>();
        Organization organization = organizationDao.findTopByOid(projectOid);
        if (ObjectUtils.isNotEmpty(organization)) {
            List<OrganizationRelation> _list = organizationRelationDao.findByMainOrganizationAndRelationType(organization, OrganizationRelationType.ProjectBindOrg);
            if (ObjectUtils.isNotEmpty(_list)) {
                list = _list.stream().map(it -> it.getRelOrganization()).collect(Collectors.toList());
            }
        }
        return list;
    }

    public ProjectBindOrgModel toModel(OrganizationRelation entity) {
        ProjectBindOrgModel model = null;
        if (ObjectUtils.isNotEmpty(entity)) {
            model = new ProjectBindOrgModel();
            BeanUtils.copyProperties(entity, model);
            if (ObjectUtils.isNotEmpty(entity.getManagerUserIds())) {
                // 负责人信息
                model.setManagerUserList(userAccountService.toListSimpleModel(userAccountService.getUserAccounts(entity.getManagerUserIds())));
            }
            // 分账规则信息
            model.setPayShareList(payShareListService.toModel(entity.getPayShareList()));

            // 主机构信息，如：项目信息
            model.setMainOrganization(organizationManagerService.toRelationModel(entity.getMainOrganization()));
            // 绑定的机构信息，如：机构信息
            model.setRelOrganization(organizationManagerService.toRelationModel(entity.getRelOrganization()));
        }
        return model;
    }

}
