package com.usky.data.controller.web;

import com.usky.common.core.bean.ApiResult;
import com.usky.common.core.exception.BusinessException;
import com.usky.data.domain.DataLink;
import com.usky.data.model.DbLinkBaseForm;
import com.usky.data.model.DbLinkCreUpForm;
import com.usky.data.model.PaginationDbLink;
import com.usky.data.service.DataLinkService;
import com.usky.data.vo.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;


import java.util.*;
import java.util.stream.Collectors;

/**
 * 数据源配置控制器
 *
 * @author fyc
 * @since 2026-01-23
 */
@Tag(name = "数据连接", description = "DataSource")
@RestController
@RequestMapping("/dataSource")
public class DataLinkController {

    @Autowired
    private DataLinkService dataLinkService;

    /**
     * 获取数据连接下拉框列表
     */
    @GetMapping("/selector")
    @Operation(summary = "获取数据连接下拉框列表")
    public ApiResult<ListVO<DbLinkSelectorListVO>> selectorList(@RequestParam(value = "dbType") String type) {
        List<DbLinkListVO> modelAll = new LinkedList<>();
        List<DataLink> dbLinkList = dataLinkService.getList();

        // 转换为VO列表
        for (DataLink entity : dbLinkList) {
            DbLinkListVO model = new DbLinkListVO();
            BeanUtils.copyProperties(entity, model);
            modelAll.add(model);
        }

        // 按数据库类型分组
        Map<String, List<DbLinkListVO>> groupByType = modelAll.stream()
                .collect(Collectors.groupingBy(DbLinkListVO::getDbType));

        List<DbLinkSelectorListVO> list = new ArrayList<>();
        // type为空时返回默认库
        if (type == null) {
            DbLinkListVO dbLink = new DbLinkListVO();
            dbLink.setFullName("默认数据库");
            dbLink.setId(0);
            // 默认数据库类型
            dbLink.setDbType("mysql");
            DbLinkSelectorListVO defaultDb = new DbLinkSelectorListVO();
            defaultDb.setFullName("");
            defaultDb.setChildren(Collections.singletonList(dbLink));
            list.add(defaultDb);
        }

        // 添加分组后的数据源
        for (Map.Entry<String, List<DbLinkListVO>> entry : groupByType.entrySet()) {
            DbLinkSelectorListVO selector = new DbLinkSelectorListVO();
            selector.setFullName(entry.getKey());
            selector.setChildren(entry.getValue());
            list.add(selector);
        }

        return ApiResult.success(new ListVO<>(list));
    }

    /**
     * 获取数据连接列表
     */
    @GetMapping
    @Operation(summary = "获取数据连接列表")
    public ApiResult<PageListVO<DbLinkListVO>> getList(@RequestBody PaginationDbLink page) {
        List<DataLink> data = dataLinkService.getList(
                page.getCurrentPage(),
                page.getPageSize(),
                page.getKeyword()
        );

        // 转换为VO列表
        List<DbLinkListVO> jsonToList = new ArrayList<>();
        for (DataLink entity : data) {
            DbLinkListVO vo = new DbLinkListVO();
            BeanUtils.copyProperties(entity, vo);
            jsonToList.add(vo);
        }

        // 构建分页信息
        PaginationVO paginationVO = new PaginationVO();
        paginationVO.setCurrentPage(page.getCurrentPage());
        paginationVO.setPageSize(page.getPageSize());
        paginationVO.setTotalRows(data.size());
        paginationVO.setTotalPages((int) Math.ceil((double) data.size() / page.getPageSize()));

        return ApiResult.success(new PageListVO<>(jsonToList, paginationVO));
    }

    /**
     * 获取数据连接列表分组
     */
    @GetMapping("/getGroup")
    @Operation(summary = "获取数据连接列表分组")
    public ApiResult<List<Map<String, Object>>> getGroup(@RequestBody PaginationDbLink page) {
        ApiResult<PageListVO<DbLinkListVO>> result = getList(page);
        List<DbLinkListVO> voList = result.getData().getList();

        // 按host分组
        Set<String> hostSet = voList.stream()
                .sorted(Comparator.comparing(DbLinkListVO::getHost))
                .map(DbLinkListVO::getHost)
                .collect(Collectors.toSet());

        List<Map<String, Object>> groupList = new ArrayList<>();
        for (String host : hostSet) {
            Map<String, Object> groupMap = new HashMap<>();
            groupMap.put("host", host);
            groupMap.put("options", voList.stream()
                    .filter(vo -> vo.getHost().equals(host))
                    .toArray());
            groupList.add(groupMap);
        }

        return ApiResult.success(groupList);
    }

    /**
     * 获取单条数据连接
     */
    @GetMapping("/{id}")
    @Operation(summary = "获取数据连接")
    @Parameters({
            @Parameter(name = "id", description = "主键")
    })
    public ApiResult<DbLinkInfoVO> get(@PathVariable("id") Integer id) {
        DataLink entity = dataLinkService.getById(id);
        if (entity == null) {
            return ApiResult.error("数据源不存在");
        }
        DbLinkInfoVO vo = new DbLinkInfoVO();
        return ApiResult.success(vo.getDbLinkInfoVO(entity));
    }

    /**
     * 新建数据连接
     */
    @PostMapping
    @Operation(summary = "添加数据连接")
    @Parameters({
            @Parameter(name = "dbLinkCreUpForm", description = "新建数据连接表单对象", required = true)
    })
    public ApiResult<String> create(@RequestBody @Validated DbLinkCreUpForm dbLinkCreUpForm) {
        DataLink entity = dbLinkCreUpForm.getDbLinkEntity(dbLinkCreUpForm);
        if (dataLinkService.isExistByFullName(entity.getFullName(), null)) {
            return ApiResult.error("连接名称已存在");
        }
        return ApiResult.success(dataLinkService.save(entity) ? "新增成功" : "新增失败");
    }

    /**
     * 更新数据连接
     */
    @PutMapping("/{id}")
    @Operation(summary = "修改数据连接")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
            @Parameter(name = "dbLinkCreUpForm", description = "更新数据连接表单对象", required = true)
    })
    public ApiResult<String> update(@PathVariable("id") Integer id, @RequestBody @Validated DbLinkCreUpForm dbLinkCreUpForm) {
        dbLinkCreUpForm.setId(id);
        DataLink entity = dbLinkCreUpForm.getDbLinkEntity(dbLinkCreUpForm);
        if (dataLinkService.isExistByFullName(entity.getFullName(), id)) {
            throw new BusinessException("连接名称已存在");
        }
        if (!dataLinkService.updateById(entity)) {
            return ApiResult.error("更新失败");
        }
        return ApiResult.success("更新成功");
    }

    /**
     * 删除数据连接
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除数据连接")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true)
    })
    public ApiResult<String> delete(@PathVariable("id") Integer id) {
        DataLink entity = dataLinkService.getById(id);
        if (entity != null) {
            dataLinkService.removeById(entity);
            return ApiResult.success("删除成功");
        }
        return ApiResult.error("数据源不存在");
    }

    /**
     * 测试连接
     */
    @PostMapping("/actions/test")
    @Operation(summary = "测试连接")
    @Parameters({
            @Parameter(name = "dbLinkBaseForm", description = "数据连接参数", required = true)
    })
    public ApiResult<String> test(@RequestBody DbLinkBaseForm dbLinkBaseForm) throws Exception {
        boolean data = dataLinkService.testDbConnection(dbLinkBaseForm.getDbLinkEntity(dbLinkBaseForm));
        if (data) {
            return ApiResult.success("连接成功");
        } else {
            return ApiResult.error("连接失败");
        }
    }
}

