package com.erp.user.service.auth.impl;

import com.erp.user.service.auth.WechatService;
import com.erp.user.dto.auth.WechatQrResponse;
import com.erp.user.dto.auth.WechatCheckResponse;
import com.erp.user.dto.auth.AuthResponse;
import com.erp.user.entity.auth.WechatSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 微信服务实现
 */
@Slf4j
@Service
public class WechatServiceImpl implements WechatService {
    
    private static final String WECHAT_QR_PREFIX = "wechat:qr:";
    private static final int QR_EXPIRY_MINUTES = 5;
    
    private final RedisTemplate<String, Object> redisTemplate;
    
    @Value("${wechat.app-id:}")
    private String appId;
    
    @Value("${wechat.app-secret:}")
    private String appSecret;
    
    @Value("${wechat.callback-url:}")
    private String callbackUrl;
    
    // 内存中存储待处理的回调（生产环境应使用数据库）
    private final Map<String, WechatSession> pendingCallbacks = new ConcurrentHashMap<>();
    
    public WechatServiceImpl(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    
    @Override
    public WechatQrResponse getQrCode() {
        String qrId = UUID.randomUUID().toString();
        String state = UUID.randomUUID().toString();
        
        // 存储二维码会话
        WechatSession session = WechatSession.builder()
                .qrId(qrId)
                .state(state)
                .status("pending")
                .createdAt(LocalDateTime.now())
                .expiresAt(LocalDateTime.now().plusMinutes(QR_EXPIRY_MINUTES))
                .build();
        
        String key = WECHAT_QR_PREFIX + qrId;
        redisTemplate.opsForValue().set(key, session, Duration.ofMinutes(QR_EXPIRY_MINUTES));
        
        // 构建微信授权URL
        String authUrl = buildWechatAuthUrl(appId, callbackUrl, state);
        
        log.info("生成微信二维码: qrId={}, state={}", qrId, state);
        
        return WechatQrResponse.builder()
                .authUrl(authUrl)
                .state(state)
                .qrId(qrId)
                .build();
    }
    
    @Override
    public WechatCheckResponse checkScan(String qrId) {
        String key = WECHAT_QR_PREFIX + qrId;
        Object value = redisTemplate.opsForValue().get(key);
        
        if (!(value instanceof WechatSession session)) {
            return WechatCheckResponse.builder()
                    .status("expired")
                    .build();
        }
        
        if (session.getExpiresAt().isBefore(LocalDateTime.now())) {
            session.setStatus("expired");
            return WechatCheckResponse.builder()
                    .status("expired")
                    .build();
        }
        
        return WechatCheckResponse.builder()
                .status(session.getStatus())
                .build();
    }
    
    @Override
    public void handleCallback(String code, String state) {
        log.info("微信回调: code={}, state={}", code, state);
        
        // 根据state找到对应的session
        WechatSession session = findSessionByState(state);
        if (session == null) {
            log.warn("微信回调未找到session: state={}", state);
            return;
        }
        
        try {
            // 调用微信接口获取openid
            String openId = getOpenIdFromCode(code);
            
            session.setOpenId(openId);
            session.setStatus("confirmed");
            session.setConfirmedAt(LocalDateTime.now());
            
            // 更新session
            String key = WECHAT_QR_PREFIX + session.getQrId();
            redisTemplate.opsForValue().set(key, session, Duration.ofMinutes(QR_EXPIRY_MINUTES));
            
            log.info("微信回调处理成功: qrId={}, openId={}", session.getQrId(), openId);
        } catch (Exception e) {
            log.error("微信回调处理失败: state={}", state, e);
        }
    }
    
    private String buildWechatAuthUrl(String appId, String redirectUri, String state) {
        return String.format(
                "https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_login&state=%s#wechat_redirect",
                appId, redirectUri, state
        );
    }
    
    private WechatSession findSessionByState(String state) {
        // 从Redis中查找
        var keys = redisTemplate.keys(WECHAT_QR_PREFIX + "*");
        if (keys != null) {
            for (String key : keys) {
                Object value = redisTemplate.opsForValue().get(key);
                if (value instanceof WechatSession session && state.equals(session.getState())) {
                    return session;
                }
            }
        }
        return null;
    }
    
    private String getOpenIdFromCode(String code) {
        // TODO: 调用微信接口获取openid
        // 实际实现需要调用: https://api.weixin.qq.com/sns/oauth2/access_token
        log.info("获取OpenID: code={}", code);
        return "mock_openid_" + code;
    }
}
