package org.xyzh.workcase.service;

import com.alibaba.fastjson2.JSONObject;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.xyzh.api.workcase.service.JitsiTokenService;
import org.xyzh.workcase.config.JitsiProperties;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @description    Jitsi Meet JWT Token服务实现类
 * @filename    JitsiTokenServiceImpl.java
 * @author    claude
 * @copyright xyzh
 * @since 2025-12-25
 */
@DubboService(version = "1.0.0", group = "workcase", timeout = 30000, retries = 0)
public class JitsiTokenServiceImpl implements JitsiTokenService {
    private static final Logger logger = LoggerFactory.getLogger(JitsiTokenServiceImpl.class);

    @Autowired
    private JitsiProperties jitsiProperties;

    @Override
    public String generateJwtToken(String roomName, String userId, String userName, boolean isModerator) {
        logger.info("生成Jitsi JWT Token: roomName={}, userId={}, userName={}, isModerator={}",
            roomName, userId, userName, isModerator);

        try {
            long now = System.currentTimeMillis();
            long exp = now + jitsiProperties.getToken().getExpiration();

            // 构建用户上下文
            Map<String, Object> userContext = new HashMap<>();
            userContext.put("id", userId);
            userContext.put("name", userName);
            userContext.put("moderator", isModerator);

            // 构建affiliation (这是Jitsi识别主持人的关键字段)
            Map<String, Object> user = new HashMap<>();
            user.put("id", userId);
            user.put("name", userName);
            user.put("moderator", isModerator);
            user.put("affiliation", isModerator ? "owner" : "member");  // owner=主持人, member=普通成员

            // 构建context
            Map<String, Object> context = new HashMap<>();
            context.put("user", user);

            // 【调试日志】打印用户上下文
            logger.info("【JWT用户上下文】roomName={}, userId={}, userName={}, isModerator={}, affiliation={}, user={}",
                roomName, userId, userName, isModerator, isModerator ? "owner" : "member", user);

            // 构建JWT claims
            Map<String, Object> claims = new HashMap<>();
            claims.put("context", context);
            claims.put("room", roomName);
            claims.put("iss", jitsiProperties.getApp().getId());
            claims.put("aud", "jitsi");
            claims.put("sub", jitsiProperties.getServer().getUrl());
            claims.put("exp", exp / 1000); // 秒级时间戳
            claims.put("nbf", now / 1000);
            claims.put("moderator", isModerator);  // 在顶层也添加moderator字段

            // 【调试日志】打印完整claims
            logger.info("【JWT Claims】roomName={}, claims={}", roomName, claims);

            // 构建JWT Header，必须包含 typ: JWT
            Map<String, Object> header = new HashMap<>();
            header.put("alg", "HS256");
            header.put("typ", "JWT");

            // 生成JWT Token
            String token = Jwts.builder()
                .setHeader(header)
                .setClaims(claims)
                .setIssuedAt(new Date(now))
                .setExpiration(new Date(exp))
                .signWith(SignatureAlgorithm.HS256, jitsiProperties.getApp().getSecret().getBytes())
                .compact();

            logger.info("JWT Token生成成功: roomName={}", roomName);
            return token;
        } catch (Exception e) {
            logger.error("生成JWT Token失败: roomName={}, error={}", roomName, e.getMessage(), e);
            throw new RuntimeException("生成JWT Token失败: " + e.getMessage());
        }
    }

    @Override
    public boolean validateJwtToken(String token) {
        try {
            Claims claims = Jwts.parser()
                .setSigningKey(jitsiProperties.getApp().getSecret().getBytes())
                .parseClaimsJws(token)
                .getBody();

            // 检查过期时间
            Date expiration = claims.getExpiration();
            return expiration.after(new Date());
        } catch (Exception e) {
            logger.warn("JWT Token验证失败: error={}", e.getMessage());
            return false;
        }
    }

    @Override
    public String buildIframeUrl(String roomName, String jwtToken, JSONObject config) {
        logger.info("构建Jitsi iframe URL: roomName={}", roomName);

        StringBuilder url = new StringBuilder();
        url.append(jitsiProperties.getServer().getUrl()).append("/").append(roomName);

        // 添加JWT Token
        url.append("?jwt=").append(jwtToken);

        // 添加默认配置
        url.append("&config.startWithAudioMuted=false");
        url.append("&config.startWithVideoMuted=false");
        url.append("&config.enableWelcomePage=false");
        url.append("&config.prejoinPageEnabled=false");
        url.append("&config.disableDeepLinking=true");
        url.append("&config.enableChat=true");
        url.append("&config.enableScreenSharing=true");

        // 界面配置
        url.append("&interfaceConfig.SHOW_JITSI_WATERMARK=false");
        url.append("&interfaceConfig.SHOW_WATERMARK_FOR_GUESTS=false");
        url.append("&interfaceConfig.DISABLE_JOIN_LEAVE_NOTIFICATIONS=false");
        url.append("&interfaceConfig.DEFAULT_BACKGROUND=#474747");

        // 添加自定义配置
        if (config != null && !config.isEmpty()) {
            config.forEach((key, value) -> {
                url.append("&config.").append(key).append("=").append(value);
            });
        }

        String iframeUrl = url.toString();
        logger.info("iframe URL构建成功: url={}", iframeUrl);
        return iframeUrl;
    }

    @Override
    public String generateRoomName(String workcaseId) {
        // 格式: workcase_{workcaseId}_{timestamp}
        String roomName = String.format("workcase_%s_%d",
            workcaseId != null ? workcaseId : "default",
            System.currentTimeMillis());

        logger.info("生成Jitsi房间名: roomName={}", roomName);
        return roomName;
    }
}
