package com.gxwebsoft.common.core.controller;

import com.gxwebsoft.common.core.service.CertificateHealthService;
import com.gxwebsoft.common.core.service.CertificateService;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Map;

/**
 * 证书管理控制器
 * 提供证书状态查询、健康检查等功能
 *
 * @author 科技小王子
 * @since 2024-07-26
 */
@Slf4j
@Tag(name = "证书管理")
@RestController
@RequestMapping("/api/system/certificate")
public class CertificateController extends BaseController {

    @Resource
    private CertificateService certificateService;

    @Resource
    private CertificateHealthService certificateHealthService;

    @Operation(summary = "获取所有证书状态")
    @GetMapping("/status")
    @PreAuthorize("hasAuthority('system:certificate:view')")
    public ApiResult<Map<String, Object>> getCertificateStatus() {
        try {
            Map<String, Object> status = certificateService.getAllCertificateStatus();
            return success("获取证书状态成功", status);
        } catch (Exception e) {
            log.error("获取证书状态失败", e);
            return new ApiResult<>(1, "获取证书状态失败: " + e.getMessage());
        }
    }

    @Operation(summary = "证书健康检查")
    @GetMapping("/health")
    @PreAuthorize("hasAuthority('system:certificate:view')")
    public ApiResult<Map<String, Object>> healthCheck() {
        try {
            CertificateHealthService.HealthResult health = certificateHealthService.health();
            Map<String, Object> result = Map.of(
                "status", health.getStatus(),
                "details", health.getDetails()
            );
            return success("证书健康检查完成", result);
        } catch (Exception e) {
            log.error("证书健康检查失败", e);
            return new ApiResult<>(1, "证书健康检查失败: " + e.getMessage());
        }
    }

    @Operation(summary = "获取证书诊断信息")
    @GetMapping("/diagnostic")
    @PreAuthorize("hasAuthority('system:certificate:view')")
    public ApiResult<Map<String, Object>> getDiagnosticInfo() {
        try {
            Map<String, Object> diagnostic = certificateHealthService.getDiagnosticInfo();
            return success("获取证书诊断信息成功", diagnostic);
        } catch (Exception e) {
            log.error("获取证书诊断信息失败", e);
            return new ApiResult<>(1, "获取证书诊断信息失败: " + e.getMessage());
        }
    }

    @Operation(summary = "检查特定证书")
    @GetMapping("/check/{certType}/{fileName}")
    @PreAuthorize("hasAuthority('system:certificate:view')")
    public ApiResult<Map<String, Object>> checkSpecificCertificate(
            @Parameter(description = "证书类型", example = "wechat") @PathVariable String certType,
            @Parameter(description = "文件名", example = "apiclient_key.pem") @PathVariable String fileName) {
        try {
            Map<String, Object> result = certificateHealthService.checkSpecificCertificate(certType, fileName);
            return success("检查证书完成", result);
        } catch (Exception e) {
            log.error("检查证书失败: {}/{}", certType, fileName, e);
            return new ApiResult<>(1, "检查证书失败: " + e.getMessage());
        }
    }

    @Operation(summary = "验证证书文件")
    @GetMapping("/validate/{certType}/{fileName}")
    @PreAuthorize("hasAuthority('system:certificate:view')")
    public ApiResult<CertificateService.CertificateInfo> validateCertificate(
            @Parameter(description = "证书类型", example = "wechat") @PathVariable String certType,
            @Parameter(description = "文件名", example = "apiclient_cert.pem") @PathVariable String fileName) {
        try {
            CertificateService.CertificateInfo certInfo =
                certificateService.validateX509Certificate(certType, fileName);

            if (certInfo != null) {
                return success("证书验证成功", certInfo);
            } else {
                return new ApiResult<>(1, "证书验证失败，可能不是有效的X509证书");
            }
        } catch (Exception e) {
            log.error("验证证书失败: {}/{}", certType, fileName, e);
            return new ApiResult<>(1, "验证证书失败: " + e.getMessage());
        }
    }

    @Operation(summary = "检查证书文件是否存在")
    @GetMapping("/exists/{certType}/{fileName}")
    @PreAuthorize("hasAuthority('system:certificate:view')")
    public ApiResult<Boolean> checkCertificateExists(
            @Parameter(description = "证书类型", example = "alipay") @PathVariable String certType,
            @Parameter(description = "文件名", example = "appCertPublicKey.crt") @PathVariable String fileName) {
        try {
            boolean exists = certificateService.certificateExists(certType, fileName);
            String message = exists ? "证书文件存在" : "证书文件不存在";
            return success(message, exists);
        } catch (Exception e) {
            log.error("检查证书文件存在性失败: {}/{}", certType, fileName, e);
            return new ApiResult<>(1, "检查证书文件存在性失败: " + e.getMessage());
        }
    }

    @Operation(summary = "获取证书文件路径")
    @GetMapping("/path/{certType}/{fileName}")
    @PreAuthorize("hasAuthority('system:certificate:view')")
    public ApiResult<String> getCertificatePath(
            @Parameter(description = "证书类型", example = "wechat") @PathVariable String certType,
            @Parameter(description = "文件名", example = "wechatpay_cert.pem") @PathVariable String fileName) {
        try {
            String path = certificateService.getCertificateFilePath(certType, fileName);
            return success("获取证书路径成功", path);
        } catch (Exception e) {
            log.error("获取证书路径失败: {}/{}", certType, fileName, e);
            return new ApiResult<>(1, "获取证书路径失败: " + e.getMessage());
        }
    }

    @Operation(summary = "获取微信支付证书路径")
    @GetMapping("/wechat-path/{fileName}")
    @PreAuthorize("hasAuthority('system:certificate:view')")
    public ApiResult<String> getWechatPayCertPath(
            @Parameter(description = "文件名", example = "apiclient_key.pem") @PathVariable String fileName) {
        try {
            String path = certificateService.getWechatPayCertPath(fileName);
            return success("获取微信支付证书路径成功", path);
        } catch (Exception e) {
            log.error("获取微信支付证书路径失败: {}", fileName, e);
            return new ApiResult<>(1, "获取微信支付证书路径失败: " + e.getMessage());
        }
    }

    @Operation(summary = "获取支付宝证书路径")
    @GetMapping("/alipay-path/{fileName}")
    @PreAuthorize("hasAuthority('system:certificate:view')")
    public ApiResult<String> getAlipayCertPath(
            @Parameter(description = "文件名", example = "appCertPublicKey.crt") @PathVariable String fileName) {
        try {
            String path = certificateService.getAlipayCertPath(fileName);
            return success("获取支付宝证书路径成功", path);
        } catch (Exception e) {
            log.error("获取支付宝证书路径失败: {}", fileName, e);
            return new ApiResult<>(1, "获取支付宝证书路径失败: " + e.getMessage());
        }
    }

    @Operation(summary = "刷新证书缓存")
    @PostMapping("/refresh")
    @PreAuthorize("hasAuthority('system:certificate:manage')")
    public ApiResult<String> refreshCertificateCache() {
        try {
            // 这里可以添加刷新证书缓存的逻辑
            log.info("证书缓存刷新请求，操作用户: {}", getLoginUser().getUsername());
            return new ApiResult<>(0, "证书缓存刷新成功", "success");
        } catch (Exception e) {
            log.error("刷新证书缓存失败", e);
            return new ApiResult<>(1, "刷新证书缓存失败: " + e.getMessage());
        }
    }
}
