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

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.scene.ProjectBindSceneParam;
import com.zhongshu.card.client.model.scene.ProjectSceneInfoModel;
import com.zhongshu.card.client.model.scene.ProjectSceneInfoSearch;
import com.zhongshu.card.client.type.DataState;
import com.zhongshu.card.server.core.dao.org.OrganizationDao;
import com.zhongshu.card.server.core.dao.scene.ProjectSceneInfoDao;
import com.zhongshu.card.server.core.dao.scene.SceneInfoDao;
import com.zhongshu.card.server.core.domain.org.Organization;
import com.zhongshu.card.server.core.domain.scene.ProjectSceneInfo;
import com.zhongshu.card.server.core.domain.scene.SceneInfo;
import com.zhongshu.card.server.core.service.base.CommonService;
import com.zhongshu.card.server.core.service.base.SuperService;
import com.zhongshu.card.server.core.util.BeanUtils;
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 java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author TRX
 * @date 2024/11/22
 */
@Slf4j
@Service
public class ProjectSceneInfoService extends SuperService {

    @Autowired
    private SceneInfoDao sceneInfoDao;

    @Autowired
    private ProjectSceneInfoDao projectSceneInfoDao;

    @Autowired
    private OrganizationDao organizationDao;

    @Autowired
    private SceneInfoService sceneInfoService;

    @Autowired
    private RoleSceneInfoService roleSceneInfoService;

    @Autowired
    private CommonService commonService;

    public ResultContent bindScene(ProjectBindSceneParam param) {
        SceneInfo entity = sceneInfoDao.findTopById(param.getId());
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, param.getId()));
        }
        Organization organization = organizationDao.findTopByOid(param.getProjectOid());
        if (ObjectUtils.isEmpty(organization)) {
            return ResultContent.buildFail("项目不存在");
        }
        ProjectSceneInfo projectSceneInfo = buildProjectScene(entity, organization);
        if (ObjectUtils.isNotEmpty(projectSceneInfo)) {
            projectSceneInfoDao.save(projectSceneInfo);
        }
        return ResultContent.buildSuccess();
    }

    /**
     * 绑定多个
     *
     * @param param
     * @return
     */
    public ResultContent bindScenes(ProjectBindSceneParam param) {
        List<String> ids = param.getIds();
        if (ObjectUtils.isEmpty(ids)) {
            return ResultContent.buildFail("ids不能为空");
        }
        Organization organization = organizationDao.findTopByOid(param.getProjectOid());
        if (ObjectUtils.isEmpty(organization)) {
            return ResultContent.buildFail("项目不存在");
        }
        List<ProjectSceneInfo> list = new ArrayList<>();
        for (String id : ids) {
            SceneInfo entity = sceneInfoDao.findTopById(id);
            if (ObjectUtils.isNotEmpty(entity)) {
                ProjectSceneInfo projectSceneInfo = buildProjectScene(entity, organization);
                if (ObjectUtils.isNotEmpty(projectSceneInfo)) {
                    list.add(projectSceneInfo);
                }
            }
        }
        if (ObjectUtils.isNotEmpty(list)) {
            projectSceneInfoDao.saveAll(list);
        }
        return ResultContent.buildSuccess();
    }

    private ProjectSceneInfo buildProjectScene(SceneInfo entity, Organization projectInfo) {
        ProjectSceneInfo projectSceneInfo = projectSceneInfoDao.findTopBySceneInfoAndProjectOid(entity, projectInfo.getOid());
        if (ObjectUtils.isEmpty(projectSceneInfo)) {
            projectSceneInfo = new ProjectSceneInfo();
        }
        projectSceneInfo.setSceneInfo(entity);
        projectSceneInfo.setSceneInfoId(entity.getId());
        projectSceneInfo.setName(entity.getName());
        projectSceneInfo.setSceneType(entity.getSceneType());
        projectSceneInfo.setSceneState(entity.getState());
        projectSceneInfo.setState(entity.getState());
        projectSceneInfo.setProjectOid(projectInfo.getOid());
        return projectSceneInfo;
    }

    public ResultContent<Page<ProjectSceneInfoModel>> page(ProjectSceneInfoSearch param, Pageable pageable) {
        Page<ProjectSceneInfo> page = projectSceneInfoDao.page(pageable, param);
        return ResultContent.buildSuccess(PageEntityUtil.concurrent2PageModel(page, this::toModel));
    }

    public ResultContent<ProjectSceneInfoModel> getDetailById(String id) {
        ProjectSceneInfo entity = projectSceneInfoDao.findTopById(id);
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
        }
        return ResultContent.buildSuccess(toModel(entity));
    }

    public ResultContent deleteById(String id) {
        ProjectSceneInfo entity = projectSceneInfoDao.findTopById(id);
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
        }
        // 判断是否可以删除
        projectSceneInfoDao.delete(entity);

        // 删除关联的信息
        roleSceneInfoService.deleteByProjectSceneId(entity.getId());
        return ResultContent.buildSuccess();
    }

    public ResultContent changeState(String id, DataState state) {
        ProjectSceneInfo entity = projectSceneInfoDao.findTopById(id);
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail(String.format(ResultMessage.DATA_NOT_EXIST, id));
        }
        if (state == DataState.Enable) {
            DataState sceneState = entity.getSceneInfo().getState();
            if (sceneState == DataState.Disable) {
                return ResultContent.buildFail("平台上的场景已禁用，不能启用");
            }
        }
        entity.setState(state);
        projectSceneInfoDao.save(entity);
        return ResultContent.buildSuccess();
    }

    public ResultContent changeStateBySceneInfoId(String sceneInfoId, DataState state) {
        if (StringUtils.isNotEmpty(sceneInfoId)) {
            Map<String, Object> where = new HashMap<>();
            where.put("sceneInfoId", sceneInfoId);

            Map<String, Object> standardData = new HashMap<>();
            standardData.put("sceneState", state);

            commonService.updateData(where, standardData, ProjectSceneInfo.class.getSimpleName());
        }
        return ResultContent.buildSuccess();
    }

    /**
     * 场景信息发送变化，编辑项目上的关联数据
     *
     * @param sceneInfo
     * @return
     */
    public ResultContent updateAllSceneInfo(SceneInfo sceneInfo) {
        if (ObjectUtils.isNotEmpty(sceneInfo)) {
            Map<String, Object> where = new HashMap<>();
            where.put("sceneInfoId", sceneInfo.getId());

            Map<String, Object> standardData = new HashMap<>();
            standardData.put("name", sceneInfo.getName());
            standardData.put("sceneType", sceneInfo.getSceneType());
            standardData.put("sceneState", sceneInfo.getState());

            commonService.updateData(where, standardData, ProjectSceneInfo.class.getSimpleName());
        }
        return ResultContent.buildSuccess();
    }

    /**
     * 删除平台的场景数据时，关联删除项目上的数据
     *
     * @param sceneInfoId
     * @return
     */
    public ResultContent deleteBySceneInfoId(String sceneInfoId) {
        if (ObjectUtils.isNotEmpty(sceneInfoId)) {
            projectSceneInfoDao.deleteBySceneInfoId(sceneInfoId);
        }
        return ResultContent.buildSuccess();
    }

    public ProjectSceneInfoModel toModel(ProjectSceneInfo entity) {
        ProjectSceneInfoModel model = new ProjectSceneInfoModel();
        if (ObjectUtils.isNotEmpty(entity)) {
            BeanUtils.copyProperties(entity, model);
            model.setSceneInfo(sceneInfoService.toModel(entity.getSceneInfo()));
        }
        return model;
    }

}
