package cn.aqroid.business.auth.controller;

import cn.aqroid.business.auth.domain.ApiLoginUser;
import cn.aqroid.business.auth.domain.WxSession;
import cn.aqroid.business.auth.domain.dto.*;
import cn.aqroid.business.auth.service.ApiTokenService;
import cn.aqroid.business.auth.service.WxAuthService;
import cn.aqroid.business.auth.util.ApiLoginUserHolder;
import cn.aqroid.business.customer.domain.Customer;
import cn.aqroid.business.customer.service.ICustomerService;
import cn.aqroid.common.core.domain.AjaxResult;
import cn.aqroid.common.exception.ServiceException;
import cn.aqroid.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

/**
 * 小程序端认证控制器
 *
 * @author aqroid
 * @date 2026-01-12
 */
@RestController
@RequestMapping("/api/auth")
public class ApiAuthController {

    private static final Logger log = LoggerFactory.getLogger(ApiAuthController.class);

    @Autowired
    private WxAuthService wxAuthService;

    @Autowired
    private ICustomerService customerService;

    @Autowired
    private ApiTokenService apiTokenService;

    /**
     * 微信登录
     */
    @PostMapping("/wx-login")
    public AjaxResult wxLogin(@RequestBody WxLoginRequest request) {
        if (StringUtils.isEmpty(request.getCode())) {
            return AjaxResult.error("登录code不能为空");
        }

        try {
            // 1. 通过code获取openid
            WxSession wxSession = wxAuthService.code2Session(request.getCode());
            
            if (!wxSession.isSuccess() || StringUtils.isEmpty(wxSession.getOpenid())) {
                return AjaxResult.error("微信登录失败");
            }

            // 2. 查询或创建顾客
            Customer existingCustomer = customerService.selectByOpenid(wxSession.getOpenid());
            boolean isNewUser = (existingCustomer == null);
            
            Customer customer = customerService.getOrCreateByOpenid(
                    wxSession.getOpenid(),
                    request.getNickname(),
                    request.getAvatar()
            );

            // 3. 构建登录用户信息
            ApiLoginUser loginUser = new ApiLoginUser();
            loginUser.setUserId(customer.getId());
            loginUser.setOpenid(customer.getOpenid());
            loginUser.setUnionid(wxSession.getUnionid());
            loginUser.setPhone(customer.getPhone());
            loginUser.setNickname(customer.getNickname());
            loginUser.setAvatar(customer.getAvatar());
            loginUser.setUserType("customer");
            loginUser.setCustomerId(customer.getId());
            loginUser.setSessionKey(wxSession.getSessionKey());

            // 4. 生成Token
            String token = apiTokenService.createToken(loginUser);

            // 5. 构建返回结果
            LoginResult result = new LoginResult();
            result.setToken(token);
            result.setUserId(customer.getId());
            result.setOpenid(customer.getOpenid());
            result.setPhone(customer.getPhone());
            result.setUserType("customer");
            result.setNeedBindPhone(StringUtils.isEmpty(customer.getPhone()));
            result.setIsNewUser(isNewUser);
            result.setNickname(customer.getNickname());
            result.setAvatar(customer.getAvatar());

            log.info("用户登录成功: userId={}, openid={}, isNewUser={}", 
                    customer.getId(), customer.getOpenid(), isNewUser);

            return AjaxResult.success(result);
        } catch (ServiceException e) {
            log.error("微信登录失败: {}", e.getMessage());
            return AjaxResult.error(e.getMessage());
        } catch (Exception e) {
            log.error("微信登录异常", e);
            return AjaxResult.error("登录失败，请稍后重试");
        }
    }

    /**
     * 手机号授权登录
     */
    @PostMapping("/phone-login")
    public AjaxResult phoneLogin(@RequestBody PhoneLoginRequest request, HttpServletRequest httpRequest) {
        if (StringUtils.isEmpty(request.getEncryptedData()) || StringUtils.isEmpty(request.getIv())) {
            return AjaxResult.error("手机号授权数据不能为空");
        }

        try {
            // 获取当前登录用户
            ApiLoginUser loginUser = ApiLoginUserHolder.getLoginUser();
            if (loginUser == null) {
                return AjaxResult.error("请先登录");
            }

            // 解密手机号
            String phoneNumber = wxAuthService.decryptPhoneNumber(
                    loginUser.getSessionKey(),
                    request.getEncryptedData(),
                    request.getIv()
            );

            // 更新顾客手机号
            Customer customer = customerService.selectById(loginUser.getCustomerId());
            if (customer != null) {
                customer.setPhone(phoneNumber);
                customerService.updateCustomer(customer);
            }

            // 更新登录用户信息
            loginUser.setPhone(phoneNumber);
            apiTokenService.refreshToken(loginUser);

            // 构建返回结果
            LoginResult result = new LoginResult();
            result.setToken(loginUser.getToken());
            result.setUserId(loginUser.getUserId());
            result.setOpenid(loginUser.getOpenid());
            result.setPhone(phoneNumber);
            result.setUserType(loginUser.getUserType());
            result.setNeedBindPhone(false);
            result.setIsNewUser(false);
            result.setNickname(loginUser.getNickname());
            result.setAvatar(loginUser.getAvatar());

            log.info("用户绑定手机号成功: userId={}, phone={}", loginUser.getUserId(), phoneNumber);

            return AjaxResult.success(result);
        } catch (ServiceException e) {
            log.error("手机号授权失败: {}", e.getMessage());
            return AjaxResult.error(e.getMessage());
        } catch (Exception e) {
            log.error("手机号授权异常", e);
            return AjaxResult.error("授权失败，请稍后重试");
        }
    }

    /**
     * 获取用户信息
     */
    @GetMapping("/user-info")
    public AjaxResult getUserInfo() {
        ApiLoginUser loginUser = ApiLoginUserHolder.getLoginUser();
        if (loginUser == null) {
            return AjaxResult.error(401, "未登录");
        }

        return AjaxResult.success(loginUser);
    }

    /**
     * 更新用户信息
     */
    @PutMapping("/user-info")
    public AjaxResult updateUserInfo(@RequestBody UpdateUserRequest request) {
        ApiLoginUser loginUser = ApiLoginUserHolder.getLoginUser();
        if (loginUser == null) {
            return AjaxResult.error(401, "未登录");
        }

        try {
            // 验证昵称长度
            if (StringUtils.isNotEmpty(request.getNickname())) {
                if (request.getNickname().length() < 2 || request.getNickname().length() > 20) {
                    return AjaxResult.error("昵称长度必须在2-20个字符之间");
                }
            }

            // 更新顾客信息
            Customer customer = customerService.selectById(loginUser.getCustomerId());
            if (customer != null) {
                if (StringUtils.isNotEmpty(request.getNickname())) {
                    customer.setNickname(request.getNickname());
                    loginUser.setNickname(request.getNickname());
                }
                if (StringUtils.isNotEmpty(request.getAvatar())) {
                    customer.setAvatar(request.getAvatar());
                    loginUser.setAvatar(request.getAvatar());
                }
                if (StringUtils.isNotEmpty(request.getPhone())) {
                    customer.setPhone(request.getPhone());
                    loginUser.setPhone(request.getPhone());
                }
                customerService.updateCustomer(customer);
                apiTokenService.refreshToken(loginUser);
            }

            return AjaxResult.success("更新成功");
        } catch (Exception e) {
            log.error("更新用户信息异常", e);
            return AjaxResult.error("更新失败");
        }
    }

    /**
     * 切换角色
     */
    @PostMapping("/switch-role")
    public AjaxResult switchRole(@RequestBody SwitchRoleRequest request) {
        ApiLoginUser loginUser = ApiLoginUserHolder.getLoginUser();
        if (loginUser == null) {
            return AjaxResult.error(401, "未登录");
        }

        if (StringUtils.isEmpty(request.getUserType())) {
            return AjaxResult.error("角色类型不能为空");
        }

        try {
            // 验证角色类型
            String userType = request.getUserType();
            if (!"customer".equals(userType) && !"merchant".equals(userType) && !"player".equals(userType)) {
                return AjaxResult.error("无效的角色类型");
            }

            // TODO: 验证用户是否拥有该角色
            // 这里需要根据实际业务逻辑判断用户是否有权限切换到目标角色

            // 更新登录用户角色
            loginUser.setUserType(userType);
            if (request.getTenantId() != null) {
                loginUser.setTenantId(request.getTenantId());
            }
            
            // 刷新Token
            apiTokenService.refreshToken(loginUser);

            // 生成新Token
            String newToken = apiTokenService.createToken(loginUser);

            LoginResult result = new LoginResult();
            result.setToken(newToken);
            result.setUserId(loginUser.getUserId());
            result.setUserType(userType);
            result.setTenantId(loginUser.getTenantId());

            log.info("用户切换角色成功: userId={}, newRole={}", loginUser.getUserId(), userType);

            return AjaxResult.success(result);
        } catch (Exception e) {
            log.error("切换角色异常", e);
            return AjaxResult.error("切换失败");
        }
    }

    /**
     * 退出登录
     */
    @PostMapping("/logout")
    public AjaxResult logout(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (StringUtils.isNotEmpty(token)) {
            token = apiTokenService.getTokenFromHeader(token);
            apiTokenService.invalidateToken(token);
        }
        ApiLoginUserHolder.clear();
        return AjaxResult.success("退出成功");
    }
}
