package org.hzhub.erp.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.hzhub.erp.common.core.BaseController;
import org.hzhub.erp.common.domain.R;
import org.hzhub.erp.common.page.TableDataInfo;
import org.hzhub.erp.domain.entity.ErpApiConfig;
import org.hzhub.erp.domain.entity.ErpApiParam;
import org.hzhub.erp.domain.vo.ApiTestResultVO;
import org.hzhub.erp.domain.vo.ErpApiConfigVO;
import org.hzhub.erp.service.IErpApiService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ERP动态API配置Controller
 *
 * @author HZHub Team
 */
@SaIgnore  // 开发阶段暂时跳过认证，生产环境需要移除此注解并启用权限验证
@RestController
@RequestMapping("/erp/api/config")
@RequiredArgsConstructor
public class ErpApiController extends BaseController {

    private final IErpApiService erpApiService;

    /**
     * 分页查询API配置列表
     */
    @GetMapping("/list")
    public TableDataInfo<ErpApiConfigVO> list(ErpApiConfigVO query,
                                               @RequestParam(defaultValue = "1") Integer pageNum,
                                               @RequestParam(defaultValue = "10") Integer pageSize) {
        return erpApiService.queryApiConfigList(query, pageNum, pageSize);
    }

    /**
     * 获取API配置详情（含参数列表）
     */
    @GetMapping("/{apiId}")
    public R<Map<String, Object>> getInfo(@PathVariable Long apiId) {
        ErpApiConfig config = erpApiService.selectApiConfigById(apiId);
        List<ErpApiParam> params = erpApiService.selectApiParamsByApiId(apiId);

        Map<String, Object> result = new HashMap<>();
        result.put("info", config);
        result.put("params", params);

        return R.ok(result);
    }

    /**
     * 新增API配置
     */
    @PostMapping
    public R<Void> add(@RequestBody @Validated ErpApiConfig config) {
        int rows = erpApiService.insertApiConfig(config);
        return rows > 0 ? R.ok() : R.fail("新增失败");
    }

    /**
     * 修改API配置
     */
    @PutMapping
    public R<Void> edit(@RequestBody @Validated ErpApiConfig config) {
        int rows = erpApiService.updateApiConfig(config);
        return rows > 0 ? R.ok() : R.fail("修改失败");
    }

    /**
     * 删除API配置
     */
    @DeleteMapping("/{apiIds}")
    public R<Void> remove(@PathVariable Long[] apiIds) {
        int rows = erpApiService.deleteApiConfigByIds(apiIds);
        return rows > 0 ? R.ok() : R.fail("删除失败");
    }

    /**
     * 启用/禁用API
     */
    @PutMapping("/changeStatus")
    public R<Void> changeStatus(@RequestBody ErpApiConfig config) {
        int rows = erpApiService.updateApiStatus(config);
        return rows > 0 ? R.ok() : R.fail("状态更新失败");
    }

    /**
     * 从数据库表导入生成初始配置
     */
    @PostMapping("/importFromTable")
    public R<Void> importFromTable(@RequestBody Map<String, Object> request) {
        String[] tableNames = ((List<String>) request.get("tableNames")).toArray(new String[0]);
        String dataSource = (String) request.getOrDefault("dataSource", "erp");

        erpApiService.importFromTable(tableNames, dataSource);
        return R.ok();
    }

    /**
     * 同步表结构（更新字段配置）
     */
    @GetMapping("/syncTable/{apiId}")
    public R<Void> syncTable(@PathVariable Long apiId) {
        erpApiService.syncTableStructure(apiId);
        return R.ok();
    }

    /**
     * API测试
     */
    @PostMapping("/test/{apiId}")
    public R<ApiTestResultVO> testApi(@PathVariable Long apiId,
                                      @RequestBody Map<String, Object> testParams,
                                      HttpServletRequest request) {
        // 提取客户端IP和用户ID
        String clientIp = getClientIp(request);
        String userId = getUserId(request);

        ApiTestResultVO result = erpApiService.testApi(apiId, testParams, clientIp, userId);
        return R.ok(result);
    }

    /**
     * 获取客户端IP（考虑代理和网关）
     */
    private String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");

        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }

        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }

        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }

        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }

        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");  // Nginx常用的真实IP头
        }

        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();  // 最后使用直接连接的IP
        }

        // 如果通过了多个代理，第一个IP才是真实IP
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0].trim();
        }

        return ip != null ? ip : "unknown";
    }

    /**
     * 获取用户ID（从网关注入的请求头中获取）
     */
    private String getUserId(HttpServletRequest request) {
        // 网关会在验证JWT后注入用户ID
        String userId = request.getHeader("X-User-Id");

        if (userId == null || userId.isEmpty()) {
            // 如果没有网关头，尝试从Sa-Token获取
            try {
                // StpUtil.getLoginIdAsString();  // 如果已集成Sa-Token
                userId = "test-user";  // 测试环境使用固定标识
            } catch (Exception e) {
                userId = "test-user";
            }
        }

        return userId;
    }

    /**
     * API文档预览
     */
    @GetMapping("/preview/{apiId}")
    public R<Map<String, String>> preview(@PathVariable Long apiId) {
        Map<String, String> docMap = erpApiService.generateApiDoc(apiId);
        return R.ok(docMap);
    }

    /**
     * 查询调用统计
     */
    @GetMapping("/stats/{apiId}")
    public R<Map<String, Object>> getStats(@PathVariable Long apiId,
                                           @RequestParam(required = false) String startTime,
                                           @RequestParam(required = false) String endTime) {
        Map<String, Object> stats = erpApiService.getApiStats(apiId, startTime, endTime);
        return R.ok(stats);
    }

    /**
     * 查询错误日志
     */
    @GetMapping("/errorLog/{apiId}")
    public R<List<Map<String, Object>>> getErrorLog(@PathVariable Long apiId,
                                                    @RequestParam(defaultValue = "10") Integer limit) {
        List<Map<String, Object>> logs = erpApiService.getApiErrorLog(apiId, limit);
        return R.ok(logs);
    }

    /**
     * 清除缓存
     */
    @DeleteMapping("/cache/{apiId}")
    public R<Void> clearCache(@PathVariable Long apiId) {
        erpApiService.clearApiCache(apiId);
        return R.ok();
    }
}