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

import com.github.microservice.components.data.base.util.PageEntityUtil;
import com.github.microservice.net.ResultContent;
import com.zhongshu.card.client.model.base.IDsParam;
import com.zhongshu.card.client.model.devices.DeviceInfoSearch;
import com.zhongshu.card.client.model.devices.permiss.DevicePermissParam;
import com.zhongshu.card.client.model.org.OrganizationMiniModel;
import com.zhongshu.card.client.model.school.AreaSimpleModel;
import com.zhongshu.card.client.openApi.model.DeviceInfoOpenApiModel;
import com.zhongshu.card.client.openApi.model.DeviceInfoOpenApiSimpleModel;
import com.zhongshu.card.client.openApi.model.DevicePermissOpenApiModel;
import com.zhongshu.card.client.openApi.params.*;
import com.zhongshu.card.client.type.DataState;
import com.zhongshu.card.server.core.dao.devices.DeviceInfoDao;
import com.zhongshu.card.server.core.dao.devices.DevicePermissDao;
import com.zhongshu.card.server.core.domain.devices.DeviceInfo;
import com.zhongshu.card.server.core.domain.devices.permiss.DevicePermiss;
import com.zhongshu.card.server.core.domain.org.OrganizationUser;
import com.zhongshu.card.server.core.domain.org.UserAccount;
import com.zhongshu.card.server.core.service.base.SuperService;
import com.zhongshu.card.server.core.service.devices.permiss.DevicePermissIotService;
import com.zhongshu.card.server.core.service.devices.permiss.DevicePermissService;
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.orgManager.OrganizationManagerServiceImpl;
import com.zhongshu.card.server.core.service.school.AreaServiceImpl;
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.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

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

/**
 * 设备权限相关的 openAPI
 *
 * @author TRX
 * @date 2024/11/12
 */
@Slf4j
@Service
public class DevicePermissOpenApiService extends SuperService {

    @Autowired
    private OrganizationManagerServiceImpl organizationManagerService;

    @Autowired
    private OrganizationServiceImpl organizationServiceImpl;

    @Autowired
    private AreaServiceImpl areaService;

    @Autowired
    private DeviceInfoDao deviceInfoDao;

    @Autowired
    private DevicePermissDao devicePermissDao;

    @Autowired
    private DevicePermissIotService devicePermissIotService;

    @Autowired
    private DevicePermissService devicePermissService;

    @Autowired
    private OrganizationUserServiceImpl organizationUserService;

    /**
     * 设备列表
     *
     * @param apiSearch
     * @return
     */
    public ResultContent<Page<DeviceInfoOpenApiModel>> page(DeviceInfoOpenApiSearch apiSearch) {
        if (StringUtils.isEmpty(apiSearch.getProjectCode())) {
            return ResultContent.buildFail("projectCode不能为空");
        }
        DeviceInfoSearch param = new DeviceInfoSearch();
        BeanUtils.copyProperties(apiSearch, param);
        param.setProjectInfoCode(apiSearch.getProjectCode());

        Pageable pageable = PageRequest.of(apiSearch.getNumber(), apiSearch.getSize());
        Page<DeviceInfo> page = deviceInfoDao.page(pageable, param);
        return ResultContent.buildSuccess(PageEntityUtil.concurrent2PageModel(page, this::toModel));
    }

    /**
     * 更加设备ID查询设备详情
     *
     * @param param
     * @return
     */
    public ResultContent<DeviceInfoOpenApiModel> getDetailByDeviceId(DeviceIdParam param) {
        DeviceInfo deviceInfo = deviceInfoDao.findTopByDeviceId(param.getDeviceId());
        if (ObjectUtils.isEmpty(deviceInfo)) {
            return ResultContent.buildFail("数据不存在");
        }
        return ResultContent.buildSuccess(toModel(deviceInfo));
    }

    /**
     * 查询设备的权限
     *
     * @param param
     * @return
     */
    public ResultContent<List<DevicePermissOpenApiModel>> getDevicePermissByDeviceId(DeviceIdAndProjectCodeParam param) {
        if (StringUtils.isEmpty(param.getProjectCode())) {
            return ResultContent.buildFail("projectCode不能为空");
        }
        List<DevicePermissOpenApiModel> models = new ArrayList<>();
        String projectOid = getOidByCode(param.getProjectCode());
        if (StringUtils.isNotEmpty(projectOid)) {
            List<DevicePermiss> list = devicePermissDao.findByDeviceIdAndProjectOid(param.getDeviceId(), projectOid);
            if (ObjectUtils.isNotEmpty(list)) {
                models = list.stream().map(this::toDevicePermissModel).collect(Collectors.toUnmodifiableList());
            }
        }
        return ResultContent.buildSuccess(models);
    }

    public ResultContent changePermissState(PermissChangeOpenApiParam param, DataState dataState) {
        if (StringUtils.isEmpty(param.getProjectCode())) {
            return ResultContent.buildFail("projectCode不能为空");
        }
        if (StringUtils.isEmpty(param.getUserId())) {
            return ResultContent.buildFail("userId不能为空");
        }
        if (StringUtils.isEmpty(param.getDeviceId())) {
            return ResultContent.buildFail("deviceId不能为空");
        }
        String projectOid = getOidByCode(param.getProjectCode());
        if (StringUtils.isEmpty(projectOid)) {
            return ResultContent.buildFail("projectCode不存在");
        }
        DevicePermiss entity = devicePermissDao.findTopByUserIdAndDeviceIdAndProjectOid(param.getUserId(), param.getDeviceId(), projectOid);
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail("权限不存在");
        }
        if (dataState == DataState.Disable) {
            // 移除权限
            devicePermissIotService.changeDeviceUser(List.of(entity), 0, "");
        } else {
            // 启用
            devicePermissIotService.changeDeviceUser(List.of(entity), 1, "");
        }
        return ResultContent.buildSuccess();
    }

    /**
     * 移出权限
     *
     * @param param
     * @return
     */
    public ResultContent deletePermiss(PermissChangeOpenApiParam param) {
        if (StringUtils.isEmpty(param.getProjectCode())) {
            return ResultContent.buildFail("projectCode不能为空");
        }
        if (StringUtils.isEmpty(param.getUserId())) {
            return ResultContent.buildFail("userId不能为空");
        }
        if (StringUtils.isEmpty(param.getDeviceId())) {
            return ResultContent.buildFail("deviceId不能为空");
        }
        String projectOid = getOidByCode(param.getProjectCode());
        if (StringUtils.isEmpty(projectOid)) {
            return ResultContent.buildFail("projectCode不存在");
        }
        DevicePermiss entity = devicePermissDao.findTopByUserIdAndDeviceIdAndProjectOid(param.getUserId(), param.getDeviceId(), projectOid);
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail("权限不存在");
        }
        IDsParam iDsParam = new IDsParam();
        iDsParam.setIds(List.of(entity.getId()));
        return devicePermissService.deleteByIds(iDsParam);
    }

    /**
     * 添加权限
     *
     * @param param
     * @return
     */
    public ResultContent addPermiss(PermissChangeOpenApiParam param) {
        if (StringUtils.isEmpty(param.getProjectCode())) {
            return ResultContent.buildFail("projectCode不能为空");
        }
        if (StringUtils.isEmpty(param.getUserId())) {
            return ResultContent.buildFail("userId不能为空");
        }
        if (StringUtils.isEmpty(param.getDeviceId())) {
            return ResultContent.buildFail("deviceId不能为空");
        }
        String projectOid = getOidByCode(param.getProjectCode());
        if (StringUtils.isEmpty(projectOid)) {
            return ResultContent.buildFail("projectCode不存在");
        }
        DevicePermiss entity = devicePermissDao.findTopByUserIdAndDeviceIdAndProjectOid(param.getUserId(), param.getDeviceId(), projectOid);
        if (ObjectUtils.isNotEmpty(entity)) {
            return ResultContent.buildFail("权限已存在");
        }
        List<OrganizationUser> orgUsers = organizationUserService.getUserOrgList(param.getUserId(), projectOid);
        if (ObjectUtils.isEmpty(orgUsers)) {
            return ResultContent.buildFail("用户不属于项目");
        }
        DevicePermissParam saveParam = new DevicePermissParam();
        saveParam.setDeviceIds(List.of(param.getDeviceId()));
        saveParam.setProjectOid(projectOid);
        saveParam.setIds(orgUsers.stream().map(OrganizationUser::getId).collect(Collectors.toList()));
        return devicePermissService.saveBindInfo(saveParam);
    }

    /**
     * 查询用户的设备权限列表
     *
     * @param param
     * @return
     */
    public ResultContent<List<DevicePermissOpenApiModel>> getDevicePermissByUserId(UserOpenApiParam param) {
        if (StringUtils.isEmpty(param.getProjectCode())) {
            return ResultContent.buildFail("projectCode不能为空");
        }
        List<DevicePermissOpenApiModel> models = new ArrayList<>();
        String projectOid = getOidByCode(param.getProjectCode());
        if (StringUtils.isNotEmpty(projectOid)) {
            List<DevicePermiss> list = devicePermissDao.findByUserIdAndProjectOid(param.getUserId(), projectOid);
            if (ObjectUtils.isNotEmpty(list)) {
                models = list.stream().map(this::toDevicePermissModel).collect(Collectors.toUnmodifiableList());
            }
        }
        return ResultContent.buildSuccess(models);
    }

    /**
     * 设备基础信息
     *
     * @param entity
     * @return
     */
    public DeviceInfoOpenApiModel toModel(DeviceInfo entity) {
        DeviceInfoOpenApiModel model = null;
        if (ObjectUtils.isNotEmpty(entity)) {
            model = new DeviceInfoOpenApiModel();
            BeanUtils.copyProperties(entity, model);

            // 所属机构信息
            OrganizationMiniModel miniModel = organizationManagerService.toMiniModel(entity.getOrganization());
            model.setOrganization(miniModel);

            model.setProjectInfoName(organizationServiceImpl.getOrgNameByCode(entity.getProjectInfoCode()));

            // 所属区域信息
            List<AreaSimpleModel> areaModels = areaService.getParents(entity.getArea());
            if (ObjectUtils.isNotEmpty(areaModels)) {
                model.setArea(areaModels.get(0));
                Collections.reverse(areaModels);
                List<String> areaNames = areaModels.stream().map(it -> it.getName()).collect(Collectors.toList());
                model.setAreaAllName(String.join("/", areaNames));
            }
        }
        return model;
    }

    public DeviceInfoOpenApiSimpleModel toDeviceSimpleModel(DeviceInfo entity) {
        DeviceInfoOpenApiSimpleModel model = null;
        if (ObjectUtils.isNotEmpty(entity)) {
            model = new DeviceInfoOpenApiSimpleModel();
            BeanUtils.copyProperties(entity, model);
        }
        return model;
    }

    /**
     * 设备权限
     *
     * @param entity
     * @return
     */
    public DevicePermissOpenApiModel toDevicePermissModel(DevicePermiss entity) {
        DevicePermissOpenApiModel model = new DevicePermissOpenApiModel();
        if (ObjectUtils.isEmpty(entity)) {
            BeanUtils.copyProperties(entity, model);
            DeviceInfo deviceInfo = entity.getDeviceInfo();
            if (ObjectUtils.isNotEmpty(deviceInfo)) {
                model.setDeviceId(deviceInfo.getDeviceId());
                model.setDeviceName(deviceInfo.getDeviceName());
                model.setDeviceType(deviceInfo.getDeviceType());
                model.setProjectInfoCode(deviceInfo.getProjectInfoCode());
            }

            UserAccount user = null;
            OrganizationUser organizationUser = entity.getOrganizationUser();
            if (ObjectUtils.isNotEmpty(organizationUser)) {
                user = organizationUser.getUser();
            }
            if (ObjectUtils.isNotEmpty(user)) {
                model.setCode(organizationUser.getCode());
                model.setUserId(user.getUserId());
                model.setName(user.getName());
                model.setPhone(user.getPhone());
                model.setProfilePic(user.getProfilePic());
                model.setSex(user.getSex());
            }
        }
        return model;
    }

}
