package com.ruoyi.dxp.service.impl;

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.DataIntegrationMapper;
import com.ruoyi.dxp.mapper.DataItemMapper;
import com.ruoyi.dxp.mapper.UserResourceMapper;
import com.ruoyi.dxp.service.IDataItemService;
import com.ruoyi.dxp.service.INoticeService;
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.DataShareMapper;
import com.ruoyi.dxp.service.IDataShareService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 共享数据Service业务层处理
 *
 * @author jy
 * @date 2022-11-21
 */
@Service
public class DataShareServiceImpl implements IDataShareService {
    @Autowired
    private DataShareMapper dataShareMapper;

    @Autowired
    private DataIntegrationMapper dataIntegrationMapper;

    @Autowired
    private DataItemMapper dataItemMapper;

    @Autowired
    private IDataItemService dataItemService;

    @Autowired
    private UserResourceMapper userResourceMapper;

    @Autowired
    private INoticeService noticeService;

    @Autowired
    private IUserResourceService userResourceService;


    /**
     * 查询共享数据
     *
     * @param id 共享数据主键
     * @return 共享数据
     */
    @Override
    public DataShare selectDataShareById(Long id) {
        return dataShareMapper.selectDataShareById(id);
    }

    /**
     * 查询共享数据列表
     *
     * @param dataShare 共享数据
     * @return 共享数据
     */
    @Override
    public List<DataShare> selectDataShareList(DataShare dataShare) {
        return dataShareMapper.selectDataShareList(dataShare);
    }

    /**
     * 查询热门共享数据列表
     *
     * @param dataShare 共享数据
     * @return 共享数据
     */
    @Override
    public List<DataShare> selectHotDataShareList(DataShare dataShare) {
        return dataShareMapper.selectHotDataShareList(dataShare);
    }

    /**
     * 新增共享数据
     *
     * @param dataShare 共享数据
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult insertDataShare(DataShare dataShare) {
        // 检查参数
        if (dataShare.getDataId() == null) {
            return AjaxResult.error("所属整合数据不能为空");
        }

        if (dataShare.getDatabaseId() == null) {
            // 查询数据库
            DataIntegration dataIntegration = dataIntegrationMapper.selectDataIntegrationById(dataShare.getDataId());
            if (dataIntegration == null) {
                return AjaxResult.error("整合数据不存在");
            }

            dataShare.setDatabaseId(dataIntegration.getDatabaseId());
            dataShare.setTableId(dataIntegration.getTableId());
            dataShare.setTableName(dataIntegration.getTableName());
            if (StringUtils.isEmpty(dataShare.getDataName())) {
                dataShare.setDataName(dataIntegration.getDataName());
            }
        }

        LoginUser loginUser = SecurityUtils.getLoginUser();
        dataShare.setStatus(DxpConstants.STATUS_WAIT_APPROVED);
        dataShare.setCreateBy(loginUser.getUsername());
        dataShare.setCreateTime(DateUtils.getNowDate());
        dataShareMapper.insertDataShare(dataShare);

        // 生成共享明细
        DataItem req = new DataItem();
        req.setDataType(DxpConstants.DATA_TYPE_INTEGRATION);
        req.setDataId(dataShare.getDataId());
        List<DataItem> dataItems = dataItemMapper.selectDataItemList(req);
        if (dataItems != null && dataItems.size() > 0) {
            for (DataItem item : dataItems) {
                // 保存共享数据明细
                DataItem shareDataItem = new DataItem();
                shareDataItem.setDataType(DxpConstants.DATA_TYPE_SHARE);
                shareDataItem.setDataId(dataShare.getId());
                shareDataItem.setColumnName(item.getColumnName());
                shareDataItem.setColumnComment(item.getColumnComment());
                shareDataItem.setColumnType(item.getColumnType());
                shareDataItem.setIsPk(item.getIsPk());
                shareDataItem.setIsIncrement(item.getIsIncrement());
                shareDataItem.setIsRequired(item.getIsRequired());
                shareDataItem.setIsVisable(item.getIsVisable());
                shareDataItem.setIsSearchable(DxpConstants.YES);
                shareDataItem.setCreateBy(loginUser.getUsername());
                shareDataItem.setCreateTime(DateUtils.getNowDate());
                shareDataItem.setSort(item.getSort());
                this.dataItemMapper.insertDataItem(shareDataItem);
            }
        }

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

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

    /**
     * 批量添加共享数据
     *
     * @param dataShareBatch 批量对象
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult batchDataShare(DataShareBatch dataShareBatch) {
        if (dataShareBatch == null || dataShareBatch.getDataIds() == null || dataShareBatch.getDataIds().size() == 0) {
            return AjaxResult.error("整合数据不存在");
        }

        for (Long dataId : dataShareBatch.getDataIds()) {
            // 生成共享数据
            DataShare dataShare = new DataShare();
            dataShare.setDataId(dataId);
            this.insertDataShare(dataShare);
        }

        return AjaxResult.success();
    }

    /**
     * 修改共享数据
     *
     * @param dataShare 共享数据
     * @return 结果
     */
    @Override
    public int updateDataShare(DataShare dataShare) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        dataShare.setUpdateBy(loginUser.getUsername());
        dataShare.setUpdateTime(DateUtils.getNowDate());
        return dataShareMapper.updateDataShare(dataShare);
    }

    /**
     * 删除共享数据信息
     *
     * @param id 共享数据主键
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult deleteDataShareById(Long id) {
        // 检查是否有用户订购
        UserResource req = new UserResource();
        req.setResourceType(DxpConstants.DATA_TYPE_SHARE);
        req.setResourceId(id);
        List<UserResource> userResources = userResourceService.selectUserResourceList(req);
        if (userResources != null && userResources.size() > 0) {
            return AjaxResult.error("当前资源已被用户订购");
        }

        // 删除共享数据
        int result = dataShareMapper.deleteDataShareById(id);

        // 删除数据项
        dataItemService.deleteDataItemByTypeAndDataId(DxpConstants.DATA_TYPE_SHARE, id);
        return AjaxResult.success();
    }

    /**
     * 检查共享数据是否有变化
     *
     * @param id 共享数据主键
     * @return
     */
    @Override
    public CompareShareDataResultDto checkChange(Long id) throws Exception {
        CompareShareDataResultDto resultDto = new CompareShareDataResultDto();

        // 检查共享数据
        DataShare dataShare = dataShareMapper.selectDataShareById(id);
        if (dataShare == null) {
            throw new Exception("共享数据不存在");
        }

        // 查询共享数据明细
        DataItem sdReq = new DataItem();
        sdReq.setDataType(DxpConstants.DATA_TYPE_SHARE);
        sdReq.setDataId(id);
        List<DataItem> shareDataItems = dataItemMapper.selectDataItemList(sdReq);
        if (shareDataItems == null || shareDataItems.size() == 0) {
            throw new Exception("共享数据明细不存在");
        }

        // 查询对应的整合数据明细
        DataItem idReq = new DataItem();
        idReq.setDataType(DxpConstants.DATA_TYPE_INTEGRATION);
        idReq.setDataId(dataShare.getDataId());
        List<DataItem> integrationDataItems = dataItemMapper.selectDataItemList(idReq);

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

        // 对比
        for (DataItem shareDataItem : shareDataItems) {
            DataItem findTarget = integrationDataItems.stream().filter(p -> p.getColumnName().equals(shareDataItem.getColumnName())).findAny().orElse(null);

            // 删除的数据
            if (findTarget == null) {
                CompareShareDataDto dto = new CompareShareDataDto();
                BeanUtils.copyProperties(shareDataItem, dto);
                dto.setBusinessType(BusinessType.DELETE);
                resultDataItems.add(dto);
                changed = true;
            } else {
                CompareShareDataDto dto = new CompareShareDataDto();
                if (!StringUtils.equals(shareDataItem.getColumnComment(), findTarget.getColumnComment()) ||
                        !StringUtils.equals(shareDataItem.getColumnType(), findTarget.getColumnType()) ||
                        !StringUtils.equals(shareDataItem.getIsPk(), findTarget.getIsPk()) ||
                        !StringUtils.equals(shareDataItem.getIsIncrement(), findTarget.getIsIncrement())) {
                    // 变换了的数据
                    BeanUtils.copyProperties(shareDataItem, dto); // 数据装入旧数据
                    dto.setBusinessType(BusinessType.UPDATE);
                    dto.setNewData(findTarget); // 新数据放newData
                    resultDataItems.add(dto);
                    changed = true;
                } else {
                    // 没有变化的数据
                    BeanUtils.copyProperties(shareDataItem, dto);
                    dto.setBusinessType(null);
                    resultDataItems.add(dto);
                }
            }
        }

        // 找到新增的
        for (DataItem integrationDataItem : integrationDataItems) {
            DataItem shareTarget = shareDataItems.stream().filter(p -> p.getColumnName().equals(integrationDataItem.getColumnName())).findAny().orElse(null);
            // 新增的数据
            if (shareTarget == null) {
                CompareShareDataDto dto = new CompareShareDataDto();
                BeanUtils.copyProperties(integrationDataItem, dto);
                dto.setBusinessType(BusinessType.INSERT);
                resultDataItems.add(dto);
                changed = true;
            }
        }

        resultDto.setChanged(changed);
        resultDto.setDataItems(resultDataItems);
        return resultDto;
    }

    /**
     * 保存共享数据
     *
     * @param dto 共享数据
     * @return 保存结果
     */
    @Override
    @Transactional
    public AjaxResult save(ShareDataSaveDto dto) {
        // 参数检查
        if (dto.getDataId() == null) {
            return AjaxResult.error("所属整合数据不能为空");
        }

        if (dto.getDatabaseId() == null) {
            // 查询数据库
            DataIntegration dataIntegration = dataIntegrationMapper.selectDataIntegrationById(dto.getDataId());
            if (dataIntegration == null) {
                return AjaxResult.error("整合数据不存在");
            }

            dto.setDatabaseId(dataIntegration.getDatabaseId());
            dto.setTableId(dataIntegration.getTableId());
            dto.setTableName(dataIntegration.getTableName());
            if (StringUtils.isEmpty(dto.getDataName())) {
                dto.setDataName(dataIntegration.getDataName());
            }
        }

        DataShare dataShare = new DataShare();
        BeanUtils.copyProperties(dto, dataShare);
        if (dto.getId() != null) {
            dataShare.setSyncFlag(DxpSyncStatusConstants.WAIT_SYNC);
            dataShare.setStatus(DxpConstants.STATUS_WAIT_APPROVED); // 修改后就需要审核
            this.updateDataShare(dataShare);

            // 删除已有的dataItem
            dataItemService.deleteDataItemByTypeAndDataId(DxpConstants.DATA_TYPE_SHARE, dto.getId());
        } else {
            LoginUser loginUser = SecurityUtils.getLoginUser();
            dataShare.setStatus(DxpConstants.STATUS_WAIT_APPROVED);
            dataShare.setCreateBy(loginUser.getUsername());
            dataShare.setCreateTime(DateUtils.getNowDate());
            dataShareMapper.insertDataShare(dataShare);
        }

        // 新增dataItems
        LoginUser loginUser = SecurityUtils.getLoginUser();
        List<DataItem> dataItems = dto.getDataItems();
        for (DataItem dataItem : dataItems) {
            dataItem.setDataType(DxpConstants.DATA_TYPE_SHARE);
            dataItem.setDataId(dataShare.getId());
            dataItem.setCreateBy(loginUser.getUsername());
            dataItem.setCreateTime(DateUtils.getNowDate());
            dataItem.setUpdateBy(null);
            dataItem.setUpdateTime(null);
            dataItemMapper.insertDataItem(dataItem);
        }

        // 发送通知
        NoticeSendDto sendDto = new NoticeSendDto();
        sendDto.setNoticeType("dataShareAudit");
        noticeService.sendNotice(sendDto);
        return AjaxResult.success(dto.getDataId());
    }

    /**
     * 审核
     * @param auditDto 审核对象
     * @return 审核结果
     */
    @Override
    public AjaxResult audit(AuditDto auditDto) {
        DataShare dataShare = dataShareMapper.selectDataShareById(auditDto.getId());
        if (dataShare == null || !dataShare.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();
        dataShare.setStatus(auditDto.getStatus());
        dataShare.setAuditRemark(auditDto.getAuditRemark());
        dataShare.setAuditBy(loginUser.getUsername());
        dataShare.setAuditTime(DateUtils.getNowDate());
        dataShareMapper.updateDataShare(dataShare);

        // 同步更新用户订购的资源
        UserResource userResource = new UserResource();
        userResource.setResourceId(dataShare.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(dataShare.getDataName());
                uResource.setProvideOrganization(dataShare.getProvideOrganization());
                userResourceMapper.updateUserResource(uResource);
            }
        }

        return AjaxResult.success();
    }

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

        dataShare.setViewCount(viewCount);
        dataShareMapper.updateDataShare(dataShare);
    }
}
