package com.yice.webadmin.app.controller;

import com.github.pagehelper.page.PageMethod;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.yice.common.core.annotation.MyRequestBody;
import com.yice.common.core.constant.ErrorCodeEnum;
import com.yice.common.core.object.*;
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.dto.KGManageDto;
import com.yice.webadmin.app.model.KGManage;
import com.yice.webadmin.app.service.KGManageService;
import com.yice.webadmin.app.vo.KGManageVo;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.neo4j.driver.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 知识图谱管理操作控制器类。
 *
 * @author linking
 * @date 2023-04-13
 */
@Api(tags = "知识图谱管理管理接口")
@Slf4j
@RestController
@RequestMapping("/admin/app/kGManage")
public class KGManageController {

    @Autowired
    private KGManageService kGManageService;

    /**
     * 新增知识图谱管理数据。
     *
     * @param kGManageDto 新增对象。
     * @return 应答结果对象，包含新增对象主键Id。
     */
    @ApiOperationSupport(ignoreParameters = {"kGManageDto.kgId"})
    @OperationLog(type = SysOperationLogType.ADD)
    @PostMapping("/add")
    public ResponseResult<Long> add(@MyRequestBody KGManageDto kGManageDto) {
        String errorMessage = MyCommonUtil.getModelValidationError(kGManageDto, false);
        if (errorMessage != null) {
            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
        }
        KGManage kGManage = MyModelUtil.copyTo(kGManageDto, KGManage.class);
        kGManage = kGManageService.saveNew(kGManage);
        return ResponseResult.success(kGManage.getKgId());
    }

    /**
     * 更新知识图谱管理数据。
     *
     * @param kGManageDto 更新对象。
     * @return 应答结果对象。
     */
    @OperationLog(type = SysOperationLogType.UPDATE)
    @PostMapping("/update")
    public ResponseResult<Void> update(@MyRequestBody KGManageDto kGManageDto) {
        String errorMessage = MyCommonUtil.getModelValidationError(kGManageDto, true);
        if (errorMessage != null) {
            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
        }
        KGManage kGManage = MyModelUtil.copyTo(kGManageDto, KGManage.class);
        KGManage originalKGManage = kGManageService.getById(kGManage.getKgId());
        if (originalKGManage == null) {
            // NOTE: 修改下面方括号中的话述
            errorMessage = "数据验证失败，当前 [数据] 并不存在，请刷新后重试！";
            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
        }
        if (!kGManageService.update(kGManage, originalKGManage)) {
            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
        }
        return ResponseResult.success();
    }

    /**
     * 列出符合过滤条件的知识图谱列表。
     *
     * @return 应答结果对象，包含查询结果集。
     */
    @PostMapping("/listForSelect")
    public ResponseResult<List<KGManageVo>> listForSelect(@MyRequestBody KGManageDto kGManageDtoFilter) {
        KGManage kGManageFilter = MyModelUtil.copyTo(kGManageDtoFilter, KGManage.class);
        List<KGManage> kGManageList =
                kGManageService.getKGManageListWithRelation(kGManageFilter, "");
        return ResponseResult.success(KGManage.INSTANCE.fromModelList(kGManageList));
    }

    /**
     * 删除知识图谱管理数据。
     *
     * @param kgId 删除对象主键Id。
     * @return 应答结果对象。
     */
    @OperationLog(type = SysOperationLogType.DELETE)
    @PostMapping("/delete")
    public ResponseResult<Void> delete(@MyRequestBody Long kgId) {
        if (MyCommonUtil.existBlankArgument(kgId)) {
            return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
        }
        return this.doDelete(kgId);
    }

    /**
     * 列出符合过滤条件的知识图谱管理列表。
     *
     * @param kGManageDtoFilter 过滤对象。
     * @param orderParam        排序参数。
     * @param pageParam         分页参数。
     * @return 应答结果对象，包含查询结果集。
     */
    @PostMapping("/list")
    public ResponseResult<MyPageData<KGManageVo>> list(
            @MyRequestBody KGManageDto kGManageDtoFilter,
            @MyRequestBody MyOrderParam orderParam,
            @MyRequestBody MyPageParam pageParam) {
        if (pageParam != null) {
            PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
        }
        KGManage kGManageFilter = MyModelUtil.copyTo(kGManageDtoFilter, KGManage.class);
        String orderBy = MyOrderParam.buildOrderBy(orderParam, KGManage.class);
        List<KGManage> kGManageList = kGManageService.getKGManageListWithRelation(kGManageFilter, orderBy);
        return ResponseResult.success(MyPageUtil.makeResponseData(kGManageList, KGManage.INSTANCE));
    }

    /**
     * 测试知识图谱是否连接。
     *
     * @param kgId 知识图谱配置ID。
     * @return 应答结果对象，包含查询结果集。
     */
    @PostMapping("/connectionTest")
    public ResponseResult<Long> connectionTest(@MyRequestBody Long kgId) {
        String errorMessage;
        // 验证关联Id的数据合法性
        KGManage KGManage = kGManageService.getById(kgId);
        if (KGManage == null) {
            // NOTE: 修改下面方括号中的话述
            errorMessage = "数据验证失败，当前 [对象] 并不存在，请刷新后重试！";
            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
        }
        try {
            Driver driver = GraphDatabase.driver(KGManage.getKgUrl(), AuthTokens.basic(KGManage.getKgUserName(), KGManage.getKgPassword()));
            Session session = driver.session();
            String cypher = "MATCH (n) RETURN count(n)";
            Result result = session.run(cypher);
            long count = result.single().get("count(n)").asLong();
            System.out.println("Neo4j连接成功，数据库中共有 " + count + " 个节点。");
            driver.close();
            return ResponseResult.success(count);
        } catch (Exception e) {
            return ResponseResult.error(ErrorCodeEnum.DATA_ACCESS_FAILED, "Neo4j连接失败: " + e.getMessage());
        }
    }

    /**
     * 查看指定知识图谱管理对象详情。
     *
     * @param kgId 指定对象主键Id。
     * @return 应答结果对象，包含对象详情。
     */
    @GetMapping("/view")
    public ResponseResult<KGManageVo> view(@RequestParam Long kgId) {
        KGManage kGManage = kGManageService.getByIdWithRelation(kgId, MyRelationParam.full());
        if (kGManage == null) {
            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
        }
        KGManageVo kGManageVo = KGManage.INSTANCE.fromModel(kGManage);
        return ResponseResult.success(kGManageVo);
    }

    private ResponseResult<Void> doDelete(Long kgId) {
        String errorMessage;
        // 验证关联Id的数据合法性
        KGManage originalKGManage = kGManageService.getById(kgId);
        if (originalKGManage == null) {
            // NOTE: 修改下面方括号中的话述
            errorMessage = "数据验证失败，当前 [对象] 并不存在，请刷新后重试！";
            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
        }
        if (!kGManageService.remove(kgId)) {
            errorMessage = "数据操作失败，删除的对象不存在，请刷新后重试！";
            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage);
        }
        return ResponseResult.success();
    }
}
