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

import com.github.microservice.auth.client.service.OrganizationUserService;
import com.github.microservice.auth.client.service.RoleService;
import com.github.microservice.auth.client.service.UserService;
import com.github.microservice.auth.security.helper.AuthHelper;
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.*;
import com.zhongshu.card.client.model.orgModel.OrgSaveParam;
import com.zhongshu.card.client.type.OrganizationRelationType;
import com.zhongshu.card.server.core.dao.org.*;
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.org.Region;
import com.zhongshu.card.server.core.service.base.SuperService;
import com.zhongshu.card.server.core.service.devices.ProjectSyncIotCenterService;
import com.zhongshu.card.server.core.service.org.OrganizationServiceImpl;
import com.zhongshu.card.server.core.service.org.OrganizationUserServiceImpl;
import com.zhongshu.card.server.core.service.projectAbout.ProjectCommonConfigService;
import com.zhongshu.card.server.core.service.projectAbout.ProjectIotInfoService;
import com.zhongshu.card.server.core.service.projectAbout.ProjectWeChatInfoService;
import com.zhongshu.card.server.core.service.user.DepartmentServiceImpl;
import com.zhongshu.card.server.core.service.user.RoleServiceImpl;
import com.zhongshu.card.server.core.service.user.UserAccountServiceImpl;
import com.zhongshu.card.server.core.util.BeanUtils;
import com.zhongshu.card.server.core.util.NextNoUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
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 java.util.List;
import java.util.stream.Collectors;

/**
 * 机构管理
 *
 * @author TRX
 * @date 2024/5/31
 */
@Slf4j
@Service
public class OrganizationManagerServiceImpl extends SuperService {

    @Autowired
    OrganizationDao organizationDao;

    @Autowired
    com.github.microservice.auth.client.service.OrganizationService organizationService;

    @Autowired
    OrganizationUserService organizationUserService;

    @Autowired
    RoleService roleService;

    @Autowired
    UserService userService;

    @Autowired
    UserCountDao userCountDao;

    @Autowired
    UserAccountServiceImpl userAccountService;

    @Autowired
    private OrganizationUserDao organizationUserDao;

    @Autowired
    RoleDao roleDao;

    @Autowired
    DepartmentServiceImpl departmentService;

    @Autowired
    AuthHelper authHelper;

    @Autowired
    RegionDao regionDao;

    @Autowired
    OrganizationRelationDao organizationRelationDao;

    @Autowired
    ProjectSyncIotCenterService projectSyncIotCenterService;

    @Autowired
    OrganizationUserServiceImpl organizationUserServiceImpl;

    @Autowired
    RoleServiceImpl roleServiceImpl;

    @Autowired
    ProjectIotInfoService projectIotInfoService;

    @Autowired
    ProjectWeChatInfoService projectWeChatInfoService;

    @Autowired
    ProjectCommonConfigService projectCommonConfigService;

    @Autowired
    OrganizationServiceImpl organizationServiceImpl;

    @Autowired
    private ProjectBindOrgServiceImpl projectBindOrgServiceImpl;

    /**
     * 保存项目 下的机构信息
     *
     * @param param
     * @return
     */
    @Transactional
    public ResultContent saveOrgInfo(OrgSaveParam param) {
        AuthType authType = param.getAuthType();
        if (authType == AuthType.User || authType == AuthType.Platform || authType == AuthType.Project) {
            return ResultContent.buildFail("authType 类型错误");
        }
        String name = param.getName();

        Organization organization = null;
        Organization orgCodeOrganization = organizationDao.findTopByOrgCode(param.getOrgCode());

        if (StringUtils.isNotEmpty(param.getId())) {
            organization = organizationDao.findTopById(param.getId());
            if (ObjectUtils.isEmpty(organization)) {
                return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, param.getId()));
            }
            if (ObjectUtils.isNotEmpty(orgCodeOrganization) && !orgCodeOrganization.getId().equals(organization.getId())) {
                return ResultContent.buildFail(String.format(ResultMessage.NAME_EXIST, param.getOrgCode()));
            }
            BeanUtils.copyProperties(param, organization, "code", "oid");
            initUpdateEntity(organization);
            organizationDao.save(organization);

            organizationServiceImpl.authCenterUpdateOrgInfo(organization.getOid(), organization.getName(), organization.getAuthType(), organization.getRemark());
        } else {
            if (ObjectUtils.isNotEmpty(orgCodeOrganization)) {
                return ResultContent.buildFail(String.format(ResultMessage.NAME_EXIST, param.getOrgCode()));
            }
            // 初始权限中心的机构信息
            ResultContent<String> initOrgContent = organizationServiceImpl.authCenterAddOrgInfo(name, authType, param.getRemark());
            if (initOrgContent.isFailed()) {
                return ResultContent.buildFail(initOrgContent.getMsg());
            }
            String oid = initOrgContent.getContent();
            if (StringUtils.isEmpty(param.getCode())) {
                param.setCode(NextNoUtil.getNextNo(authType.getCode().toUpperCase()));
            }
            String code = param.getCode();
            if (StringUtils.isEmpty(code)) {
                code = NextNoUtil.getNextNo(authType.getCode().toUpperCase());
                param.setCode(code);
            }

            organization = new Organization();
            BeanUtils.copyProperties(param, organization);
            initEntityNoCheckOid(organization);
            organization.setIsOrg(Boolean.TRUE);

            // 机构关联的 权限中心的oid
            organization.setOid(oid);

            organizationDao.save(organization);
        }
        return ResultContent.buildSuccess();
    }

    /**
     * 机构列表
     *
     * @param param
     * @param pageable
     * @return
     */
    public ResultContent<Page<OrganizationSimpleModel>> orgPage(OrganizationSearchParam param, Pageable pageable) {
        param.setIsOrg(Boolean.TRUE);
        Page<Organization> page = organizationDao.page(pageable, param);
        return ResultContent.buildSuccess(PageEntityUtil.concurrent2PageModel(page, this::toSimpleModel));
    }

    /**
     * 机构详情
     *
     * @param oid
     * @return
     */
    public ResultContent<OrganizationSimpleModel> getOrgDetail(String oid) {
        Organization organization = organizationDao.findTopByOid(oid);
        if (ObjectUtils.isEmpty(organization)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, oid));
        }
        return ResultContent.buildSuccess(toSimpleModel(organization));
    }

    /**
     * 删除机构
     *
     * @param oid
     * @return
     */
    @Transactional
    public ResultContent deleteOrg(String oid) {
        Organization organization = organizationDao.findTopByOid(oid);
        if (ObjectUtils.isEmpty(organization)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, oid));
        }
        if (organization.getIsOrg() == null || !organization.getIsOrg()) {
            return ResultContent.buildFail("当前不属于结构类型，不能删除");
        }

        //1. 判断机构是否可以删除
        long number = projectBindOrgServiceImpl.countOrgBindNumber(oid);
        if (number > 0) {
            return ResultContent.buildFail(String.format("机构已绑定项目，不能删除"));
        }

        if (organization.getAuthType() == AuthType.Project) {
            long bindOrgNumber = projectBindOrgServiceImpl.countProjectBindNumber(oid);
            if (bindOrgNumber > 0) {
                return ResultContent.buildFail(String.format("项目已绑定机构，不能删除"));
            }
        }

        //2. 删除机构
        organizationDao.delete(organization);

        //3. 删除关联的信息

        return ResultContent.buildSuccess();
    }

    //---------------------------------供其他服务调用接口 start---------------------

    /**
     * 检查项目是否存在  是否是项目类型
     *
     * @param projectOid
     * @return
     */
    public ResultContent<Organization> checkProject(String projectOid) {
        if (StringUtils.isEmpty(projectOid)) {
            return ResultContent.buildFail("projectOid不能为空");
        }
        Organization organization = organizationDao.findTopByOid(projectOid);
        if (ObjectUtils.isEmpty(organization)) {
            return ResultContent.buildFail(String.format("项目不存在：%s", projectOid));
        }
        if (organization.getAuthType() != AuthType.Project) {
            return ResultContent.buildFail(String.format("%s 不属于项目类型", organization.getName()));
        }
        return ResultContent.buildSuccess(organization);
    }

    public OidAboutInfo getOidAboutInfo(String oid) {
        OidAboutInfo aboutInfo = new OidAboutInfo();
        aboutInfo.setOid(oid);
        if (StringUtils.isNotEmpty(oid)) {
            Organization organization = organizationDao.findTopByOid(oid);
            if (ObjectUtils.isNotEmpty(organization)) {
                aboutInfo.setOid(oid);
                aboutInfo.setAuthType(organization.getAuthType());

                AuthType authType = organization.getAuthType();
                if (authType == AuthType.Project) {
                    aboutInfo.setProjectOid(oid);
                } else {
                    // 查询结构绑定的项目 (如果机构绑定多个项目，怎么办)
                    List<OrganizationRelation> list = organizationRelationDao.findByRelOrganizationAndRelationType(organization, OrganizationRelationType.ProjectBindOrg);
                    if (ObjectUtils.isNotEmpty(list)) {
                        aboutInfo.setProjectOid(list.get(0).getMainOrganization().getOid());
                    }
                }
            }
        }
        return aboutInfo;
    }

    public OrganizationSimpleModel toSimpleModel(Organization entity) {
        OrganizationSimpleModel model = new OrganizationSimpleModel();
        if (ObjectUtils.isNotEmpty(entity)) {
            BeanUtils.copyProperties(entity, model);

            // 区域信息
            String adminDivisionItemCode = entity.getAdminDivisionItemCode();
            if (StringUtils.isNotEmpty(adminDivisionItemCode)) {
                List<String> codes = List.of(adminDivisionItemCode.split(","));
                List<Region> regions = regionDao.findByCodeInOrderByIndexAsc(codes);
                List<RegionModel> regionList = regions.stream().map(it -> {
                    RegionModel regionModel = new RegionModel();
                    BeanUtils.copyProperties(it, regionModel);
                    return regionModel;
                }).collect(Collectors.toList());
                model.setRegionList(regionList);
            }

            // 得到绑定的项目信息
            List<Organization> projects = projectBindOrgServiceImpl.getOrgBindProjects(entity.getOid());
            if (ObjectUtils.isNotEmpty(projects)) {
                model.setBindProjects(projects.stream().map(this::toMiniModel).collect(Collectors.toList()));
            }
        }
        return model;
    }

    public OrganizationMiniModel toMiniModel(Organization entity) {
        OrganizationMiniModel model = null;
        if (ObjectUtils.isNotEmpty(entity)) {
            model = new OrganizationMiniModel();
            BeanUtils.copyProperties(entity, model);
        }
        return model;
    }

    public OrganizationRelationModel toRelationModel(Organization entity) {
        OrganizationRelationModel model = null;
        if (ObjectUtils.isNotEmpty(entity)) {
            model = new OrganizationRelationModel();
            BeanUtils.copyProperties(entity, model);
        }
        return model;
    }

}
