package com.ruoyi.dxp.service.impl;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.dxp.constant.DxpConstants;
import com.ruoyi.dxp.constant.DxpSyncStatusConstants;
import com.ruoyi.dxp.domain.*;
import com.ruoyi.dxp.dto.*;
import com.ruoyi.dxp.mapper.ServiceIntegrationMapper;
import com.ruoyi.dxp.mapper.UserResourceMapper;
import com.ruoyi.dxp.service.INoticeService;
import com.ruoyi.dxp.service.IServiceItemService;
import com.ruoyi.dxp.service.IUserResourceService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.dxp.mapper.ServiceShareMapper;
import com.ruoyi.dxp.service.IServiceShareService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 服务共享Service业务层处理
 *
 * @author jy
 * @date 2022-11-29
 */
@Service
public class ServiceShareServiceImpl implements IServiceShareService {
    @Autowired
    private ServiceShareMapper serviceShareMapper;

    @Autowired
    private ServiceIntegrationMapper serviceIntegrationMapper;

    @Autowired
    private IServiceItemService serviceItemService;

    @Autowired
    private UserResourceMapper userResourceMapper;

    @Autowired
    private INoticeService noticeService;

    /**
     * 查询服务共享
     *
     * @param id 服务共享主键
     * @return 服务共享
     */
    @Override
    public ServiceShare selectServiceShareById(Long id) {
        return serviceShareMapper.selectServiceShareById(id);
    }

    /**
     * 查询服务共享列表
     *
     * @param serviceShare 服务共享
     * @return 服务共享
     */
    @Override
    public List<ServiceShare> selectServiceShareList(ServiceShare serviceShare) {
        return serviceShareMapper.selectServiceShareList(serviceShare);
    }

    /**
     * 查询热门服务共享列表
     *
     * @param serviceShare 服务共享
     * @return 服务共享
     */
    @Override
    public List<ServiceShare> selectHotServiceShareList(ServiceShare serviceShare) {
        return serviceShareMapper.selectHotServiceShareList(serviceShare);
    }

    /**
     * 新增服务共享
     *
     * @param serviceShare 服务共享
     * @return 结果
     */
    @Override
    public int insertServiceShare(ServiceShare serviceShare) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        serviceShare.setCreateBy(loginUser.getUsername());
        serviceShare.setCreateTime(DateUtils.getNowDate());
        return serviceShareMapper.insertServiceShare(serviceShare);
    }

    /**
     * 修改服务共享
     *
     * @param serviceShare 服务共享
     * @return 结果
     */
    @Override
    public int updateServiceShare(ServiceShare serviceShare) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        serviceShare.setUpdateBy(loginUser.getUsername());
        serviceShare.setUpdateTime(DateUtils.getNowDate());
        return serviceShareMapper.updateServiceShare(serviceShare);
    }

    /**
     * 删除服务共享信息
     *
     * @param id 服务共享主键
     * @return 结果
     */
    @Override
    public AjaxResult deleteServiceShareById(Long id) {
        // TO-DO
        // 是否有用户订阅，有订阅不能删除

        // 删除明细
        ServiceShare serviceShare = serviceShareMapper.selectServiceShareById(id);
        if (serviceShare == null) {
            return AjaxResult.error("服务不存在");
        }

        // 删除服务
        serviceShareMapper.deleteServiceShareById(id);

        // 删除明细
        serviceItemService.deleteServiceItemByTypeAndDataId(DxpConstants.DATA_TYPE_SHARE, serviceShare.getId());
        return AjaxResult.success();
    }

    /**
     * 检查共享服务是否存在变化
     *
     * @param id 共享服务id
     * @return 变化结果
     */
    @Override
    public CompareShareServiceResultDto checkChange(Long id) throws Exception {
        CompareShareServiceResultDto resultDto = new CompareShareServiceResultDto();

        // 检查共享数据
        ServiceShare serviceShare = serviceShareMapper.selectServiceShareById(id);
        if (serviceShare == null) {
            throw new Exception("共享服务不存在");
        }

        // 查询共享数据明细
        ServiceItem sdReq = new ServiceItem();
        sdReq.setServiceType(DxpConstants.DATA_TYPE_SHARE);
        sdReq.setServiceId(id);
        List<ServiceItem> shareServiceItems = serviceItemService.selectServiceItemList(sdReq);
        if (shareServiceItems == null || shareServiceItems.size() == 0) {
            throw new Exception("共享服务参数不存在");
        }

        // 查询对应的整合数据明细
        ServiceItem idReq = new ServiceItem();
        idReq.setServiceType(DxpConstants.DATA_TYPE_INTEGRATION);
        idReq.setServiceId(serviceShare.getServiceId());
        List<ServiceItem> integrationServiceItems = serviceItemService.selectServiceItemList(idReq);

        // 对比结果
        List<CompareShareServiceDto> resultServiceItems = new ArrayList<>();
        Boolean changed = false;

        // 对比
        for (ServiceItem shareServiceItem : shareServiceItems) {
            ServiceItem findTarget = integrationServiceItems.stream().filter(p -> p.getId().equals(shareServiceItem.getRelationId())).findAny().orElse(null);

            // 删除的数据
            if (findTarget == null) {
                CompareShareServiceDto dto = new CompareShareServiceDto();
                BeanUtils.copyProperties(shareServiceItem, dto);
                dto.setBusinessType(BusinessType.DELETE);
                resultServiceItems.add(dto);
                changed = true;
            } else {
                CompareShareServiceDto dto = new CompareShareServiceDto();
                if (!StringUtils.equals(shareServiceItem.getParamName(), findTarget.getParamName()) ||
                        !StringUtils.equals(shareServiceItem.getDataType(), findTarget.getDataType()) ||
                        !StringUtils.equals(shareServiceItem.getRemark(), findTarget.getRemark()) ||
                        !StringUtils.equals(shareServiceItem.getMapColumnName(), findTarget.getMapColumnName())) {
                    // 变换了的服务（数据类型，是否必填变了）
                    BeanUtils.copyProperties(shareServiceItem, dto); // 服务装入旧服务
                    dto.setBusinessType(BusinessType.UPDATE);
                    dto.setNewService(findTarget); // 新服务放newData
                    resultServiceItems.add(dto);
                    changed = true;
                } else {
                    // 没有变化的数据
                    BeanUtils.copyProperties(shareServiceItem, dto);
                    dto.setBusinessType(null);
                    resultServiceItems.add(dto);
                }
            }
        }

        // 找到新增的
        for (ServiceItem integrationServiceItem : integrationServiceItems) {
            ServiceItem shareTarget = shareServiceItems.stream().filter(p -> p.getRelationId() != null && p.getRelationId().equals(integrationServiceItem.getId())).findAny().orElse(null);
            // 新增的数据
            if (shareTarget == null) {
                CompareShareServiceDto dto = new CompareShareServiceDto();
                BeanUtils.copyProperties(integrationServiceItem, dto);
                dto.setBusinessType(BusinessType.INSERT);
                resultServiceItems.add(dto);
                changed = true;
            }
        }

        resultDto.setChanged(changed);
        resultDto.setServiceItems(resultServiceItems);
        return resultDto;
    }

    /**
     * 保存共享服务
     *
     * @param serviceShareSave 保存对象
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult save(ServiceShareSave serviceShareSave) {
        Boolean isAdd = serviceShareSave.getId() == null;
//        if (serviceShareSave.getCatalogueId() == null) {
//            return AjaxResult.error("共享目录不能为空");
//        }

        if (serviceShareSave.getServiceId() == null) {
            return AjaxResult.error("整合服务不能为空");
        }

        ServiceIntegration serviceIntegration = serviceIntegrationMapper.selectServiceIntegrationById(serviceShareSave.getServiceId());
        if (serviceIntegration == null) {
            return AjaxResult.error("整合服务不存在");
        }

        if (serviceShareSave.getPublishType() == null) {
            return AjaxResult.error("开放类型不能为空");
        }

        List<ServiceItem> paramServiceItems = serviceShareSave.getServiceItems();
        if (paramServiceItems == null || paramServiceItems.size() == 0) {
            return AjaxResult.error("参数配置不能为空");
        }

        List<ServiceItem> integrationItems = new ArrayList<>();
        List<ServiceItem> shareItems = new ArrayList<>();

        if (isAdd) {
            // 新增检查整合服务参数
            ServiceItem req = new ServiceItem();
            req.setServiceType(DxpConstants.DATA_TYPE_INTEGRATION);
            req.setServiceId(serviceShareSave.getServiceId());
            integrationItems = serviceItemService.selectServiceItemList(req);
            if (integrationItems == null || integrationItems.size() == 0) {
                return AjaxResult.error("整合服务没有配置参数");
            }

            // 提交的明细必须和整合服务明细一致
            if (paramServiceItems.size() != integrationItems.size()) {
                return AjaxResult.error("提交参数与整合服务参数不一致");
            }

            for (ServiceItem iItem : integrationItems) {
                ServiceItem paramServiceItem = paramServiceItems.stream().filter(x -> x.getParamName().equals(iItem.getParamName())).findFirst().get();
                if (paramServiceItem == null) {
                    return AjaxResult.error("提交参数与整合服务参数不一致");
                }
            }
        }

        LoginUser loginUser = SecurityUtils.getLoginUser();
        ServiceShare serviceShare = new ServiceShare();
        if (isAdd) {
            // 保存共享服务
            BeanUtils.copyProperties(serviceIntegration, serviceShare);
            serviceShare.setPublishType(serviceShareSave.getPublishType());
            serviceShare.setServiceId(serviceShareSave.getServiceId());
            serviceShare.setServiceName(serviceShareSave.getServiceName());
            serviceShare.setAddField(serviceShareSave.getAddField());
            serviceShare.setPageField(serviceShareSave.getPageField());
            serviceShare.setPageSizeField(serviceShareSave.getPageSizeField());
            serviceShare.setSearchField(serviceShareSave.getSearchField());
            serviceShare.setServiceUrl(serviceIntegration.getServiceUrl());
            serviceShare.setCatalogueId(serviceShareSave.getCatalogueId());
            serviceShare.setStatus(DxpConstants.STATUS_WAIT_APPROVED);
            serviceShare.setSyncFlag(DxpSyncStatusConstants.NONE_NEW_UPDATE);
            serviceShare.setCreateBy(loginUser.getUsername());
            serviceShare.setCreateTime(DateUtils.getNowDate());
            serviceShare.setCatalogueId(serviceShareSave.getCatalogueId());
            serviceShare.setViewCount(0L);
            serviceShare.setApplyCount(0L);
            serviceShare.setUpdateBy(null);
            serviceShare.setUpdateTime(null);
            serviceShareMapper.insertServiceShare(serviceShare);

            // 从所属整合服务明细中生成
            for (ServiceItem sItem : integrationItems) {
                ServiceItem shareItem = new ServiceItem();
                BeanUtils.copyProperties(sItem, shareItem);
                shareItem.setServiceType(DxpConstants.DATA_TYPE_SHARE);
                shareItem.setServiceId(serviceShare.getId());

                // 找到提交参数中匹配的
                ServiceItem paramServiceItem = paramServiceItems.stream().filter(x -> x.getParamName().equals(sItem.getParamName())).findFirst().get();
                shareItem.setRelationId(paramServiceItem.getId());
                shareItem.setIsVisable(paramServiceItem.getIsVisable());
                shareItem.setIsSearchable(paramServiceItem.getIsVisable()); // 服务可见即可搜索
                shareItem.setDesensitizationRuleId(paramServiceItem.getDesensitizationRuleId());
                shareItem.setParentId(paramServiceItem.getParentId());
                shareItem.setCreateBy(loginUser.getUsername());
                shareItem.setCreateTime(DateUtils.getNowDate());
                serviceItemService.insertServiceItem(shareItem);
            }
        } else {
            serviceShare = serviceShareMapper.selectServiceShareById(serviceShareSave.getId());
            if (serviceShare == null) {
                return AjaxResult.error("待编辑共享服务不存在");
            }
            serviceShare.setServiceName(serviceShareSave.getServiceName());
            serviceShare.setCatalogueId(serviceShareSave.getCatalogueId());
            serviceShare.setPublishType(serviceShareSave.getPublishType());
            serviceShare.setInfoId(serviceShareSave.getInfoId());
            serviceShare.setAddField(serviceShareSave.getAddField());
            serviceShare.setPageField(serviceShareSave.getPageField());
            serviceShare.setPageSizeField(serviceShareSave.getPageSizeField());
            serviceShare.setSearchField(serviceShareSave.getSearchField());
            serviceShare.setProvideOrganization(serviceShareSave.getProvideOrganization());
            serviceShare.setTag(serviceShareSave.getTag());
            serviceShare.setRemark(serviceShare.getRemark());
            serviceShare.setStatus(DxpConstants.STATUS_WAIT_APPROVED);
            serviceShare.setSyncFlag(DxpSyncStatusConstants.NONE_NEW_UPDATE);
            serviceShare.setUpdateBy(loginUser.getUsername());
            serviceShare.setUpdateTime(DateUtils.getNowDate());
            serviceShareMapper.updateServiceShare(serviceShare);

            // 处理已删除的
            ServiceItem reqShare = new ServiceItem();
            reqShare.setServiceType(DxpConstants.DATA_TYPE_SHARE);
            reqShare.setServiceId(serviceShareSave.getId());
            List<ServiceItem> existItems = serviceItemService.selectServiceItemList(reqShare);
            if (existItems != null && existItems.size() > 0) {
                for (ServiceItem existServiceItem : existItems) {
                    // 已经存在的明细是否在本次提交内
                    long count = paramServiceItems.stream().filter(p -> p.getId() != null && p.getId().equals(existServiceItem.getId())).count();
                    if (count == 0) {
                        // 删除该serviceItem
                        this.serviceItemService.deleteServiceItemById(existServiceItem.getId());
                    }
                }
            }

            // 保存共享明细
            for (ServiceItem sItem : paramServiceItems) {
                if (sItem.getId() != null) {
                    sItem.setUpdateBy(loginUser.getUsername());
                    sItem.setUpdateTime(DateUtils.getNowDate());
                    serviceItemService.updateServiceItem(sItem);
                } else {
                    sItem.setServiceType(DxpConstants.DATA_TYPE_SHARE);
                    sItem.setServiceId(serviceShare.getId());
                    sItem.setCreateBy(loginUser.getUsername());
                    sItem.setCreateTime(DateUtils.getNowDate());
                    sItem.setUpdateTime(null);
                    sItem.setUpdateBy(null);
                    serviceItemService.insertServiceItem(sItem);
                }
            }
        }

        // 发送通知
        NoticeSendDto sendDto = new NoticeSendDto();
        sendDto.setNoticeType("serviceShareAudit");
        noticeService.sendNotice(sendDto);

        return AjaxResult.success(serviceShare.getId());
    }

    /**
     * 挂载
     *
     * @param serviceIds 整合服务id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void mount(List<Long> serviceIds) throws Exception {
        for (Long serviceId : serviceIds) {
            this.saveMount(serviceId);
        }
    }

    /**
     * 保存挂载数据
     */
    private void saveMount(Long serviceId) throws Exception {
        ServiceIntegration serviceIntegration = serviceIntegrationMapper.selectServiceIntegrationById(serviceId);
        if (serviceIntegration == null) {
            throw new SQLException("整合服务不存在");
        }

        ServiceShareSave serviceShareSave = new ServiceShareSave();
        serviceShareSave.setServiceId(serviceId);
        serviceShareSave.setServiceName(serviceIntegration.getServiceName());
        serviceShareSave.setServiceUrl(serviceIntegration.getServiceUrl());
        serviceShareSave.setNeedAuth(serviceIntegration.getNeedAuth());
        serviceShareSave.setAuthWay(serviceIntegration.getAuthWay());
        serviceShareSave.setRequestMethod(serviceIntegration.getRequestMethod());
        serviceShareSave.setParamForm(serviceIntegration.getParamForm());
        serviceShareSave.setInfoId(serviceIntegration.getInfoId());
        serviceShareSave.setTag(serviceIntegration.getTag());
        serviceShareSave.setProvideOrganization(serviceIntegration.getProvideOrganization());
        serviceShareSave.setPublishType("close");

        ServiceItem req = new ServiceItem();
        req.setServiceType(DxpConstants.DATA_TYPE_INTEGRATION);
        req.setServiceId(serviceShareSave.getServiceId());
        List<ServiceItem> integrationItems = serviceItemService.selectServiceItemList(req);
        serviceShareSave.setServiceItems(integrationItems);
        this.save(serviceShareSave);
    }

    /**
     * 审核
     *
     * @param auditDto 审核对象
     * @return 审核结果
     */
    @Override
    public AjaxResult audit(AuditDto auditDto) {
        ServiceShare serviceShare = serviceShareMapper.selectServiceShareById(auditDto.getId());
        if (serviceShare == null || !serviceShare.getStatus().equals(DxpConstants.STATUS_WAIT_APPROVED)) {
            return AjaxResult.error("待审核服务不存在或不是待审核状态");
        }

        if (!auditDto.getStatus().equals(DxpConstants.STATUS_VALID) && !auditDto.getStatus().equals(DxpConstants.STATUS_REJECT)) {
            return AjaxResult.error("审核状态错误");
        }

        if (StringUtils.isEmpty(auditDto.getAuditRemark())) {
            return AjaxResult.error("审核原因不能为空");
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        serviceShare.setStatus(auditDto.getStatus());
        serviceShare.setAuditRemark(auditDto.getAuditRemark());
        serviceShare.setAuditBy(loginUser.getUsername());
        serviceShare.setAuditTime(DateUtils.getNowDate());
        serviceShareMapper.updateServiceShare(serviceShare);

        // 同步更新用户订购的资源
        UserResource userResource = new UserResource();
        userResource.setResourceId(serviceShare.getId());
        userResource.setResourceType(DxpConstants.RESOURCE_TYPE_SERVICE);
        List<UserResource> userResources = userResourceMapper.selectUserResourceList(userResource);
        if (userResources != null && userResources.size() > 0) {
            for (UserResource uResource : userResources) {
                uResource.setResourceName(serviceShare.getServiceName());
                uResource.setProvideOrganization(serviceShare.getProvideOrganization());
                userResourceMapper.updateUserResource(uResource);
            }
        }

        return AjaxResult.success();
    }

    /**
     * 增加浏览次数
     *
     * @param id 文献id
     */
    @Override
    public void addViewCount(Long id) {
        ServiceShare serviceShare = serviceShareMapper.selectServiceShareById(id);
        Long viewCount = serviceShare.getViewCount();
        if (viewCount == null) {
            viewCount = 1L;
        } else {
            viewCount++;
        }

        serviceShare.setViewCount(viewCount);
        serviceShareMapper.updateServiceShare(serviceShare);
    }
}
