package com.zhentao.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zhentao.common.Result;
import com.zhentao.dto.*;
import com.zhentao.pojo.Users;
import com.zhentao.service.SmsService;
import com.zhentao.service.UsersService;
import com.zhentao.service.WeChatService;
import com.zhentao.util.AvatarUploadUtil;
import com.zhentao.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

@RestController
@RequestMapping("/api/login")
//@CrossOrigin
// 在 Redis 启用时加载该控制器；不依赖数据库
@ConditionalOnProperty(prefix = "redis", name = "enabled", havingValue = "true", matchIfMissing = true)
public class AuthCodeController {

    @Autowired
    private SmsService smsService;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private WeChatService weChatService;
    
    @Autowired
    private UsersService usersService;
    
    @Autowired
    private AvatarUploadUtil avatarUploadUtil;
    
    private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    /**
     * 发送登录验证码（不依赖数据库）
     */
    @PostMapping("/send-code")
    public Result<Void> sendCode(@RequestBody SmsSendRequest req) {
        if (req == null || req.getPhone() == null || req.getPhone().trim().isEmpty()) {
            return Result.error(400, "手机号不能为空");
        }
        boolean ok = smsService.sendLoginCode(req.getPhone().trim());
        if (!ok) {
            return Result.error(500, "验证码发送失败");
        }
        return Result.success();
    }

    /**
     * 验证码登录：校验通过后查询或创建用户，签发JWT
     */
    @PostMapping("/sms-login")
    public Result<LoginResponse> smsLogin(@RequestBody SmsLoginRequest req) {
        System.out.println("=== 验证码登录请求 ===");
        if (req == null || req.getPhone() == null || req.getCode() == null) {
            return Result.error(400, "手机号或验证码不能为空");
        }

        System.out.println("手机号: " + req.getPhone());
        boolean passed = smsService.verifyLoginCode(req.getPhone().trim(), req.getCode().trim());
        if (!passed) {
            System.out.println("❌ 验证码验证失败");
            return Result.error(401, "验证码错误或已过期");
        }
        
        System.out.println("✅ 验证码验证成功");

        // 查询数据库中的用户
        Users user = usersService.getOne(new LambdaQueryWrapper<Users>()
                .eq(Users::getPhone, req.getPhone().trim())
                .eq(Users::getStatus, 1), false);
        
        // 如果用户不存在，创建新用户
        if (user == null) {
            System.out.println("⚠️ 用户不存在，创建新用户");
            user = new Users();
            user.setPhone(req.getPhone().trim());
            user.setNickname("用户" + req.getPhone().substring(Math.max(0, req.getPhone().length() - 4)));
            user.setStatus(1);
            user.setPassword(null);
            user.setCreatedAt(new Date());
            user.setUpdatedAt(new Date());
            user.setSourceChannel("sms");
            
            // 保存到数据库，自动生成userId
            usersService.save(user);
            System.out.println("✅ 创建新用户成功，ID: " + user.getUserId());
        } else {
            System.out.println("✅ 找到现有用户，ID: " + user.getUserId());
            // 更新最后登录时间
            user.setLastLoginAt(new Date());
            usersService.updateById(user);
        }

        // 生成JWT令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", user.getUserId());
        claims.put("nickname", user.getNickname());
        claims.put("phone", user.getPhone());
        String token = jwtUtil.generateToken(claims);
        
        System.out.println("✅ JWT token生成成功");

        // 构造响应，避免泄露密码
        user.setPassword(null);
        LoginResponse resp = new LoginResponse();
        resp.setToken(token);
        resp.setUser(user);
        
        System.out.println("✅ 验证码登录成功，返回用户信息");
        System.out.println("返回的用户ID: " + user.getUserId() + " (类型: " + user.getUserId().getClass().getSimpleName() + ")");
        return Result.success(resp);
    }

    /**
     * 微信授权登录：传入 wx.login 的临时 code，后端调用 jscode2session，查询或创建用户并返回 JWT
     */
    @PostMapping("/wechat/login")
    public Result<LoginResponse> wechatLogin(@RequestBody WechatLoginRequest req) {
        System.out.println("=== 微信登录请求 ===");
        if (req == null || req.getCode() == null || req.getCode().trim().isEmpty()) {
            return Result.error(400, "code 不能为空");
        }
        
        Map<String, Object> wx = weChatService.code2Session(req.getCode().trim());
        if (wx == null || (wx.containsKey("errcode") && ((Number) wx.get("errcode")).intValue() != 0)) {
            String msg = wx != null && wx.get("errmsg") != null ? String.valueOf(wx.get("errmsg")) : "微信接口错误";
            System.out.println("❌ 微信接口调用失败: " + msg);
            return Result.error(502, msg);
        }
        
        String openid = String.valueOf(wx.get("openid"));
        String unionid = wx.get("unionid") != null ? String.valueOf(wx.get("unionid")) : null;
        System.out.println("✅ 获取到微信openid: " + openid);
        
        // 根据openid查询用户
        Users user = usersService.getOne(new LambdaQueryWrapper<Users>()
                .eq(Users::getWechatOpenid, openid)
                .eq(Users::getStatus, 1), false);
        
        // 如果用户不存在，创建新用户
        if (user == null) {
            System.out.println("⚠️ 微信用户不存在，创建新用户");
            user = new Users();
            
            // ✅ 使用前端传来的昵称
            user.setNickname(req.getNickname() != null && !req.getNickname().trim().isEmpty()
                ? req.getNickname().trim()
                : "微信用户");
            
            System.out.println("设置用户昵称: " + user.getNickname());
            
            // ✅ 上传头像到MinIO
            if (req.getAvatarUrl() != null && !req.getAvatarUrl().trim().isEmpty()) {
                try {
                    System.out.println("开始上传头像到MinIO...");
                    String avatarUrl = avatarUploadUtil.uploadBase64Avatar(req.getAvatarUrl().trim(), 0); // 临时使用0，保存后会有真实ID
                    if (avatarUrl != null) {
                        user.setAvatarUrl(avatarUrl);
                        System.out.println("✅ 头像上传成功: " + avatarUrl);
                    } else {
                        System.out.println("⚠️ 头像上传失败，使用默认头像");
                        user.setAvatarUrl(null);
                    }
                } catch (Exception e) {
                    System.err.println("⚠️ 头像上传异常: " + e.getMessage());
                    user.setAvatarUrl(null);
                }
            } else {
                System.out.println("⚠️ 未提供头像");
                user.setAvatarUrl(null);
            }
            
            user.setStatus(1);
            // ✅ 设置加密后的默认密码
            user.setPassword(passwordEncoder.encode("123456"));
            user.setSourceChannel("wechat");
            user.setHasWechatLogin(1);
            user.setWechatOpenid(openid);
            if (unionid != null) {
                user.setWechatUnionid(unionid);
            }
            user.setCreatedAt(new Date());
            user.setUpdatedAt(new Date());
            
            // ✅ 如果提供了手机号code，尝试获取手机号
            if (req.getPhoneCode() != null && !req.getPhoneCode().trim().isEmpty()) {
                try {
                    System.out.println("尝试获取手机号，code: " + req.getPhoneCode());
                    String phone = weChatService.getUserPhoneByCode(req.getPhoneCode().trim());
                    if (phone != null && !phone.isEmpty()) {
                        user.setPhone(phone);
                        System.out.println("✅ 成功获取手机号: " + phone);
                    } else {
                        System.out.println("⚠️ 手机号为空");
                    }
                } catch (Exception e) {
                    System.err.println("⚠️ 获取手机号失败: " + e.getMessage());
                }
            } else {
                System.out.println("⚠️ 未提供手机号code");
            }
            
            // 保存到数据库，自动生成userId
            usersService.save(user);
            System.out.println("✅ 创建微信新用户成功，ID: " + user.getUserId() + ", 昵称: " + user.getNickname());
        } else {
            System.out.println("✅ 找到微信用户，ID: " + user.getUserId());
            
            // ✅ 如果是已存在用户，也更新昵称和头像（如果前端提供了新值）
            boolean needUpdate = false;
            if (req.getNickname() != null && !req.getNickname().trim().isEmpty()
                && !req.getNickname().equals(user.getNickname())) {
                System.out.println("更新昵称: " + user.getNickname() + " -> " + req.getNickname());
                user.setNickname(req.getNickname().trim());
                needUpdate = true;
            }
            // ✅ 更新头像（上传到MinIO）
            if (req.getAvatarUrl() != null && !req.getAvatarUrl().trim().isEmpty()) {
                try {
                    System.out.println("用户更新头像，上传到MinIO...");
                    String avatarUrl = avatarUploadUtil.uploadBase64Avatar(req.getAvatarUrl().trim(), user.getUserId());
                    if (avatarUrl != null && !avatarUrl.equals(user.getAvatarUrl())) {
                        System.out.println("更新头像: " + avatarUrl);
                        user.setAvatarUrl(avatarUrl);
                        needUpdate = true;
                    }
                } catch (Exception e) {
                    System.err.println("⚠️ 更新头像失败: " + e.getMessage());
                }
            }
            
            // ✅ 如果提供了手机号code且当前用户没有手机号，尝试获取
            if ((user.getPhone() == null || user.getPhone().isEmpty())
                && req.getPhoneCode() != null && !req.getPhoneCode().trim().isEmpty()) {
                try {
                    System.out.println("用户无手机号，尝试获取，code: " + req.getPhoneCode());
                    String phone = weChatService.getUserPhoneByCode(req.getPhoneCode().trim());
                    if (phone != null && !phone.isEmpty()) {
                        user.setPhone(phone);
                        System.out.println("✅ 成功获取手机号: " + phone);
                        needUpdate = true;
                    }
                } catch (Exception e) {
                    System.err.println("⚠️ 获取手机号失败: " + e.getMessage());
                }
            }
            
            // 更新最后登录时间
            user.setLastLoginAt(new Date());
            needUpdate = true;
            
            if (needUpdate) {
                user.setUpdatedAt(new Date());
                usersService.updateById(user);
                System.out.println("✅ 更新用户信息成功");
            }
        }

        // 生成JWT令牌
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", user.getUserId());
        claims.put("nickname", user.getNickname());
        claims.put("openid", openid);
        if (unionid != null) claims.put("unionid", unionid);
        String token = jwtUtil.generateToken(claims);
        
        System.out.println("✅ JWT token生成成功");

        // 构造响应，避免泄露密码
        user.setPassword(null);
        LoginResponse resp = new LoginResponse();
        resp.setToken(token);
        resp.setUser(user);
        
        System.out.println("✅ 微信登录成功，返回用户信息");
        System.out.println("返回的用户ID: " + user.getUserId() + " (类型: " + user.getUserId().getClass().getSimpleName() + ")");
        return Result.success(resp);
    }

    /**
     * 微信手机号获取（兼容旧版 iv/加密数据；推荐前端走新版 getPhoneNumber 并直接上传手机号）
     */
    @PostMapping("/wechat/phone")
    public Result<Map<String, Object>> wechatPhone(@RequestBody WechatPhoneRequest req) {
        Map<String, Object> data = new HashMap<>();
        data.put("phone", null);
        if (req != null && req.getCode() != null && !req.getCode().trim().isEmpty()) {
            String phone = weChatService.getUserPhoneByCode(req.getCode().trim());
            if (phone != null) {
                data.put("phone", phone);
                return Result.success(data);
            }
            return Result.error(502, "微信返回空手机号或接口错误");
        }
        // 兼容旧版：若提供 iv/encryptedData + 需要 sessionKey（从前面的 /wechat/login 返回中获取并传入）
        if (req != null && req.getIv() != null && req.getEncryptedData() != null && req.getSessionKey() != null) {
            String phone = weChatService.decryptPhone(req.getSessionKey(), req.getIv(), req.getEncryptedData());
            if (phone != null) {
                data.put("phone", phone);
                return Result.success(data);
            }
            return Result.error(501, "暂不支持解密或数据不完整");
        }
        return Result.error(400, "缺少 code 或 iv/encryptedData+sessionKey");
    }
}