package com.ruoyi.dxp.service.impl;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.Seq;
import com.ruoyi.dxp.constant.DxpConstants;
import com.ruoyi.dxp.domain.*;
import com.ruoyi.dxp.dto.CustomerServiceCallDto;
import com.ruoyi.dxp.dto.NoticeSendDto;
import com.ruoyi.dxp.dto.ResApiPageDto;
import com.ruoyi.dxp.dto.customer.MyShareResourceDto;
import com.ruoyi.dxp.dto.customer.ShareResourceDto;
import com.ruoyi.dxp.dto.customer.ShareResourceParam;
import com.ruoyi.dxp.dto.database.DatabaseUtilsDbQueryParam;
import com.ruoyi.dxp.dto.database.DatabaseUtilsQueryCondDto;
import com.ruoyi.dxp.mapper.*;
import com.ruoyi.dxp.service.*;
import com.ruoyi.dxp.utils.DatabaseUtils;
import com.ruoyi.dxp.utils.ServiceUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class ResourceShareServiceImpl implements IResourceShareService {

    @Autowired
    private ResourceShareMapper resourceShareMapper;

    @Autowired
    private UserResourceMapper userResourceMapper;

    @Autowired
    private DataShareMapper dataShareMapper;

    @Autowired
    private ServiceShareMapper serviceShareMapper;

    @Autowired
    private ApplicationMapper applicationMapper;

    @Autowired
    private UserResourceItemMapper userResourceItemMapper;

    @Autowired
    private IDataItemService dataItemService;

    @Autowired
    private IServiceItemService serviceItemService;

    @Autowired
    private IUserResourceService userResourceService;

    @Autowired
    private INoticeService noticeService;

    @Autowired
    private ILiteratureService literatureService;

    /**
     * 查询资源列表
     *
     * @param param
     * @return
     */
    @Override
    public List<ShareResourceDto> selectList(ShareResourceParam param) {
        return resourceShareMapper.selectList(param);
    }

    /**
     * 查询我的资源列表
     *
     * @param param
     * @return
     */
    @Override
    public List<MyShareResourceDto> selectMyList(ShareResourceParam param) {
        return resourceShareMapper.selectMyList(param);
    }

    /**
     * 申请资源
     *
     * @param param 申请对象
     * @return 申请结果
     */
    @Override
    @Transactional
    public AjaxResult apply(UserResource param) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser == null) {
            return AjaxResult.error("当前用户未登录");
        }

        if (StringUtils.isEmpty(param.getResourceType())) {
            return AjaxResult.error("资源类型不能为空");
        }

        if (!param.getResourceType().equals(DxpConstants.RESOURCE_TYPE_DATA) && !param.getResourceType().equals(DxpConstants.RESOURCE_TYPE_SERVICE) && !param.getResourceType().equals(DxpConstants.RESOURCE_TYPE_LITERATURE)) {
            return AjaxResult.error("资源类型错误");
        }

        if (param.getResourceId() == null) {
            return AjaxResult.error("资源id不能为空");
        }

        if (!param.getResourceType().equals(DxpConstants.RESOURCE_TYPE_LITERATURE)) {
            if (param.getApplicationId() == null) {
                return AjaxResult.error("申请应用不能为空");
            }
        }

        UserResource req = new UserResource();
        req.setResourceType(param.getResourceType());
        req.setResourceId(param.getResourceId());
        req.setUserId(loginUser.getUserId());

        if (!param.getResourceType().equals(DxpConstants.RESOURCE_TYPE_LITERATURE)) {
            req.setApplicationId(param.getApplicationId());
        }

        List<UserResource> userResources = userResourceMapper.selectUserResourceList(req);
        if (userResources != null && userResources.size() > 0) {
            if (userResources.get(0).getStatus().equals("2")) {
                userResourceMapper.deleteUserResourceById(userResources.get(0).getId());
            } else {
                return AjaxResult.error("当前用户当前应用已经申请当前资源");
            }
        }

        String publishType = null;
        String resourceName = null;
        String provideOrganization = null;
        if (param.getResourceType().equals(DxpConstants.RESOURCE_TYPE_DATA)) {
            DataShare dataShare = dataShareMapper.selectDataShareById(param.getResourceId());
            if (dataShare == null) {
                return AjaxResult.error("申请资源不存在或状态异常");
            }

            if (!dataShare.getStatus().equals(DxpConstants.STATUS_VALID)) {
                return AjaxResult.error("申请资源不存在或状态异常");
            }

            if (dataShare.getPublishType().equals("close")) {
                return AjaxResult.error("申请资源未开放");
            }

            publishType = dataShare.getPublishType();
            resourceName = dataShare.getDataName();
            provideOrganization = dataShare.getProvideOrganization();
        }

        if (param.getResourceType().equals(DxpConstants.RESOURCE_TYPE_SERVICE)) {
            ServiceShare serviceShare = serviceShareMapper.selectServiceShareById(param.getResourceId());
            if (serviceShare == null) {
                return AjaxResult.error("申请资源不存在或状态异常");
            }

            if (!serviceShare.getStatus().equals(DxpConstants.STATUS_VALID)) {
                return AjaxResult.error("申请资源不存在或状态异常");
            }

            if (serviceShare.getPublishType().equals("close")) {
                return AjaxResult.error("申请资源未开放");
            }

            publishType = serviceShare.getPublishType();
            resourceName = serviceShare.getServiceName();
            provideOrganization = serviceShare.getProvideOrganization();
        }

        if (param.getResourceType().equals(DxpConstants.RESOURCE_TYPE_LITERATURE)) {
            Literature literature = literatureService.selectLiteratureById(param.getResourceId());
            if (literature == null) {
                return AjaxResult.error("申请的文献不存在或状态异常");
            }

            if (literature.getPublishType().equals("close")) {
                return AjaxResult.error("申请的文献未开放");
            }

            publishType = literature.getPublishType();
            resourceName = literature.getLiteratureName();
            provideOrganization = literature.getPublishOrganization();
        }

        if (StringUtils.isEmpty(param.getRemark())) {
            return AjaxResult.error("申请说明不能为空");
        }

        String applicationName = "";
        if (!param.getResourceType().equals(DxpConstants.RESOURCE_TYPE_LITERATURE)) {
            Application application = applicationMapper.selectApplicationById(param.getApplicationId());
            if (application == null || !application.getStatus().equals(DxpConstants.STATUS_VALID)) {
                return AjaxResult.error("申请应用不存在或状态异常");
            }

            if (!application.getUserId().equals(loginUser.getUserId())) {
                return AjaxResult.error("申请应用不属于当前用户");
            }

            if (StringUtils.isEmpty(param.getFormat())) {
                return AjaxResult.error("数据格式不能为空");
            }

            if (!param.getFormat().equals("XML") && !param.getFormat().equals("JSON")) {
                return AjaxResult.error("数据格式错误");
            }

            if (param.getDayLimit() == null) {
                param.setDayLimit(0L);
            }

            if (param.getIsSubscribe().equals(DxpConstants.YES) && StringUtils.isEmpty(param.getSubscribeUrl())) {
                return AjaxResult.error("订阅地址不能为空");
            }

            applicationName = application.getAppName();
        }

        UserResource userResource = new UserResource();
        BeanUtils.copyProperties(param, userResource);
        if (publishType.equals("open")) {
            userResource.setStatus(DxpConstants.STATUS_VALID);
        } else if (publishType.equals("condition")) {
            userResource.setStatus(DxpConstants.STATUS_WAIT_APPROVED);
        }

        // 访问ID
        userResource.setCallId(Seq.getId());
        userResource.setResourceName(resourceName);
        userResource.setProvideOrganization(provideOrganization);
        userResource.setCreateBy(loginUser.getUsername());
        userResource.setCreateTime(DateUtils.getNowDate());
        userResource.setUserId(loginUser.getUserId());
        userResource.setApplicationName(applicationName);
        userResourceMapper.insertUserResource(userResource);

        // 更新资源申请数
        if (param.getResourceType().equals(DxpConstants.RESOURCE_TYPE_DATA)) {
            DataShare dataShare = dataShareMapper.selectDataShareById(param.getResourceId());
            if (dataShare.getApplyCount() == null) {
                dataShare.setApplyCount(1L);
            } else {
                dataShare.setApplyCount(dataShare.getApplyCount() + 1);
            }

            dataShareMapper.updateDataShare(dataShare);
        } else if (param.getResourceType().equals(DxpConstants.RESOURCE_TYPE_SERVICE)) {
            ServiceShare serviceShare = serviceShareMapper.selectServiceShareById(param.getResourceId());
            if (serviceShare.getApplyCount() == null) {
                serviceShare.setApplyCount(1L);
            } else {
                serviceShare.setApplyCount(serviceShare.getApplyCount() + 1);
            }
            serviceShareMapper.updateServiceShare(serviceShare);
        }

        if (userResource.getStatus().equals(DxpConstants.STATUS_VALID)) {
            if (!param.getResourceType().equals(DxpConstants.RESOURCE_TYPE_LITERATURE)) {
                // 写入user_resource_item
                UserResourceItem userResourceItem = new UserResourceItem();
                userResourceItem.setUserResourceId(userResource.getId());

                // 读取数据/服务对应的数据项
                if (param.getResourceType().equals(DxpConstants.RESOURCE_TYPE_DATA)) {
                    DataItem dReq = new DataItem();
                    dReq.setDataType(DxpConstants.DATA_TYPE_SHARE);
                    dReq.setDataId(param.getResourceId());
                    List<DataItem> dataItems = dataItemService.selectDataItemList(dReq);
                    userResourceItem.setResourceItem(JSON.toJSONString(dataItems));
                } else if (param.getResourceType().equals(DxpConstants.RESOURCE_TYPE_SERVICE)) {
                    ServiceItem sReq = new ServiceItem();
                    sReq.setServiceType(DxpConstants.DATA_TYPE_SHARE);
                    sReq.setServiceId(param.getResourceId());
                    sReq.setParamType(DxpConstants.PARAM_TYPE_OUT);
                    List<ServiceItem> serviceItems = serviceItemService.selectServiceItemList(sReq);
                    userResourceItem.setResourceItem(JSON.toJSONString(serviceItems));
                }

                userResourceItem.setCreateBy(loginUser.getUsername());
                userResourceItem.setCreateTime(DateUtils.getNowDate());
                userResourceItemMapper.insertUserResourceItem(userResourceItem);

                // 写入redis
                userResourceService.writeToRedis(userResource, userResourceItem);
                userResourceService.writeToSubscribeRedis();

                // 发送通知
                NoticeSendDto sendDto = new NoticeSendDto();
                sendDto.setNoticeType("auditResult");
                sendDto.setUserId(userResource.getUserId());
                sendDto.setContennt("您申请的资源【" + userResource.getResourceName() + "】，已审核通过");
                noticeService.sendNotice(sendDto);
            }
        } else {
            // 发送审核通知
            NoticeSendDto sendDto = new NoticeSendDto();
            if (param.getResourceType().equals(DxpConstants.RESOURCE_TYPE_DATA)) {
                sendDto.setNoticeType("resourceDataAudit");
            } else if (param.getResourceType().equals(DxpConstants.RESOURCE_TYPE_SERVICE)) {
                sendDto.setNoticeType("resourceServiceAudit");
            } else if (param.getResourceType().equals(DxpConstants.RESOURCE_TYPE_LITERATURE)) {
                sendDto.setNoticeType("resourceLiterureAudit");
            }
            noticeService.sendNotice(sendDto);
        }
        return AjaxResult.success(publishType);
    }

    /**
     * 查询数据库数据（用户身份）
     *
     * @param accessId 资源接入id
     * @param page     当前页
     * @param pageSize 页大小
     * @param query
     * @return
     */
    @Override
    public AjaxResult queryData(String accessId, Integer page, Integer pageSize, List<DatabaseUtilsQueryCondDto> query) {
        UserResource req = new UserResource();
        req.setCallId(accessId);
        req.setStatus(DxpConstants.STATUS_VALID);
        List<UserResource> userResources = userResourceService.selectUserResourceList(req);
        if (userResources == null || userResources.size() == 0) {
            return AjaxResult.error("订阅资源不存在或非正常状态");
        }

        DataShare dataShare = dataShareMapper.selectDataShareById(userResources.get(0).getResourceId());
        if (dataShare == null) {
            return AjaxResult.error("数据不存在");
        }

        // 获取远程数据
        DatabaseUtilsDbQueryParam queryParam = new DatabaseUtilsDbQueryParam();
        queryParam.setId(dataShare.getDatabaseId());
        queryParam.setTbName(dataShare.getTableName());
        queryParam.setPageNo(page);
        queryParam.setPageSize(pageSize);
        queryParam.setQuery(query);
        R<ResApiPageDto<List<Object>>> resApiPageDtoR = DatabaseUtils.queryCustomerTable(accessId, queryParam);
        if (resApiPageDtoR.getCode() != HttpStatus.SUCCESS) {
            return AjaxResult.error(resApiPageDtoR.getMsg());
        }

        return AjaxResult.success(resApiPageDtoR.getData());
    }

    @Override
    public AjaxResult queryService(CustomerServiceCallDto dto) {
        UserResource req = new UserResource();
        req.setCallId(dto.getCallId());
        req.setStatus(DxpConstants.STATUS_VALID);
        List<UserResource> userResources = userResourceService.selectUserResourceList(req);
        if (userResources == null || userResources.size() == 0) {
            return AjaxResult.error("订阅资源不存在或非正常状态");
        }

        R<ResApiPageDto<List<Object>>> resApiPageDtoR = ServiceUtils.customerApiCall(dto.getCallId(), dto.getParam());
        if (resApiPageDtoR.getCode() != HttpStatus.SUCCESS) {
            return AjaxResult.error(resApiPageDtoR.getMsg());
        }

        return AjaxResult.success(resApiPageDtoR.getData());
    }
}
