package com.yice.webadmin.app.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.page.PageMethod;
import com.yice.common.core.annotation.MyRequestBody;
import com.yice.common.core.constant.ErrorCodeEnum;
import com.yice.common.core.object.MyPageData;
import com.yice.common.core.object.MyPageParam;
import com.yice.common.core.object.ResponseResult;
import com.yice.common.core.util.MyCommonUtil;
import com.yice.common.core.util.MyModelUtil;
import com.yice.common.core.util.MyPageUtil;
import com.yice.common.log.annotation.OperationLog;
import com.yice.common.log.model.constant.SysOperationLogType;
import com.yice.webadmin.app.constant.DatasetConstant;
import com.yice.webadmin.app.data.DatasetData;
import com.yice.webadmin.app.dto.DatasetDataDto;
import com.yice.webadmin.app.dto.DatasetDataSummaryDto;
import com.yice.webadmin.app.model.DatasetVersion;
import com.yice.webadmin.app.service.DatasetDataService;
import com.yice.webadmin.app.service.DatasetVersionService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;

/**
 * 数据集版本操作控制器类。
 *
 * @author linking
 * @date 2023-04-13
 */
@Api(tags = "数据集版本详情管理接口")
@Slf4j
@RestController
@RequestMapping("/admin/app/datasetData")
public class DatasetDataController {

    @Autowired
    private DatasetDataService datasetDataService;
    @Autowired
    private DatasetVersionService datasetVersionService;

    /**
     * 更新数据集版本数据。
     *
     * @param datasetMongoDto 更新对象。
     * @return 应答结果对象。
     */
    @OperationLog(type = SysOperationLogType.UPDATE)
    @PostMapping("/update")
    public ResponseResult<Void> update(@MyRequestBody DatasetDataDto datasetMongoDto) throws Exception{
        String errorMessage = MyCommonUtil.getModelValidationError(datasetMongoDto, true);
        if (errorMessage != null) {
            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
        }
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode rootNode = objectMapper.readTree(datasetMongoDto.getData());
        String output = rootNode.get(DatasetConstant.OUTPUT).textValue();
        DatasetData datasetData = MyModelUtil.copyTo(datasetMongoDto, DatasetData.class);
        datasetData.setMarkStatus(StringUtils.isNotBlank(output) ? DatasetConstant.MARK : DatasetConstant.UNMARK);
        datasetDataService.update(datasetData);
        return ResponseResult.success();
    }

    /**
     * 更新数据集版本数据。
     *
     * @param datasetMongoDto 更新对象。
     * @return 应答结果对象。
     */
    @OperationLog(type = SysOperationLogType.UPDATE)
    @PostMapping("/add")
    public ResponseResult<Void> add(@MyRequestBody DatasetDataDto datasetMongoDto) throws Exception{
        String errorMessage = MyCommonUtil.getModelValidationError(datasetMongoDto, true);
        if (errorMessage != null) {
            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
        }
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode rootNode = objectMapper.readTree(datasetMongoDto.getData());
        String output = rootNode.get(DatasetConstant.OUTPUT).textValue();
        DatasetData datasetData = MyModelUtil.copyTo(datasetMongoDto, DatasetData.class);
        datasetData.setMarkStatus(StringUtils.isNotBlank(output) ? DatasetConstant.MARK : DatasetConstant.UNMARK);
        datasetDataService.update(datasetData);

        DatasetVersion datasetVersion = datasetVersionService.getById(datasetMongoDto.getVersionId());
        if(null != datasetVersion) {
            datasetVersion.setUpdateTime(new Date());
            datasetVersion.setDataVolume(datasetVersion.getDataVolume() + 1);
            datasetVersionService.updateById(datasetVersion);
        }
        return ResponseResult.success();
    }


    /**
     * 删除数据集版本数据。
     *
     * @param id 删除对象主键Id。
     * @return 应答结果对象。
     */
    @OperationLog(type = SysOperationLogType.DELETE)
    @PostMapping("/delete")
    public ResponseResult<Void> delete(
            @MyRequestBody String id,
            @MyRequestBody Long versionId) {
        if (MyCommonUtil.existBlankArgument(id)) {
            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_ID_EXIST);
        }
        if (MyCommonUtil.existBlankArgument(versionId)) {
            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_VERSION_EXIST);
        }
        Long result = datasetDataService.remove(id,versionId);
        if(result == 0) {
            return ResponseResult.error(ErrorCodeEnum.INVALID_DELETE_ARGUMENT);
        }
        DatasetVersion datasetVersion = datasetVersionService.getById(versionId);
        if(null != datasetVersion) {
            datasetVersion.setUpdateTime(new Date());
            datasetVersion.setDataVolume(datasetVersion.getDataVolume() - 1);
            datasetVersionService.updateById(datasetVersion);
        }
        return ResponseResult.success();
    }

    /**
     * 根据版本id，查询该数据集列表
     * @param versionId 版本标识
     * @param pageParam 分页参数
     * @return
     */
    @PostMapping("/list")
    public ResponseResult<MyPageData<DatasetData>> list(
            @MyRequestBody Long versionId,
            @MyRequestBody MyPageParam pageParam) {
        if (MyCommonUtil.existBlankArgument(versionId)) {
            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_VERSION_EXIST);
        }
        if (pageParam != null) {
            PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
        }
        List<DatasetData> datasetDataList = datasetDataService.list(versionId, pageParam);
        Long count = datasetDataService.count(versionId);
        return ResponseResult.success(MyPageUtil.makeResponseData(datasetDataList, count));
    }

    /**
     * 根据版本id，查询该数据集列表
     * @param datasetDataDtoFilter 数据集对象
     * @param pageParam 分页参数
     * @return
     */
    @PostMapping("/load")
    public ResponseResult<MyPageData<DatasetData>> load(
            @MyRequestBody DatasetDataDto datasetDataDtoFilter,
            @MyRequestBody MyPageParam pageParam) {
        if (pageParam != null) {
            PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
        }
        DatasetData datasetDataFilter = MyModelUtil.copyTo(datasetDataDtoFilter, DatasetData.class);
        List<DatasetData> datasetDataList = datasetDataService.list(datasetDataFilter,pageParam);
        Long count = datasetDataService.count(datasetDataFilter);
        return ResponseResult.success(MyPageUtil.makeResponseData(datasetDataList, count));
    }

    /**
     * 查看指定数据集版本对象详情。
     * @param id 主键标识。
     * @param versionId 指定对象主键Id。
     * @return 应答结果对象，包含对象详情。
     */
    @GetMapping("/view")
    public ResponseResult<DatasetData> view(
            @RequestParam String id,
            @RequestParam Long versionId) {
        if (MyCommonUtil.existBlankArgument(id)) {
            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_ID_EXIST);
        }
        if (MyCommonUtil.existBlankArgument(versionId)) {
            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_VERSION_EXIST);
        }
        DatasetData datasetData = datasetDataService.view(id, versionId);
        if (datasetData == null) {
            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
        }
        return ResponseResult.success(datasetData);
    }

    /**
     * 统计总个数
     * @param versionId 版本标识
     * @return
     */
    @GetMapping("/summaryCount")
    public ResponseResult<DatasetDataSummaryDto> summaryCount(@RequestParam Long versionId) {
        if (MyCommonUtil.existBlankArgument(versionId)) {
            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_ID_EXIST);
        }
        DatasetDataSummaryDto summaryDto = new DatasetDataSummaryDto();
        DatasetData datasetDataFilter = new DatasetData();
        datasetDataFilter.setVersionId(versionId);
        Long allMarkCount = datasetDataService.count(datasetDataFilter);
        summaryDto.setAllMarkCount(allMarkCount);

        datasetDataFilter.setMarkStatus(DatasetConstant.STATUS_UNPUBLISHED);
        Long unMarkCount = datasetDataService.count(datasetDataFilter);
        summaryDto.setUnMarkCount(unMarkCount);

        summaryDto.setMarkCount(allMarkCount - unMarkCount);
        return ResponseResult.success(summaryDto);
    }

}
