package com.jeesharp.business.member.controller;

import cn.hutool.core.util.DesensitizedUtil;
import com.jeesharp.business.modules.member.application.MobileAuthApplication;
import com.jeesharp.business.modules.member.dto.*;
import com.jeesharp.business.modules.member.entity.LoginResultVO;
import com.jeesharp.business.modules.member.vo.QrLoginTokenVO;
import com.jeesharp.business.modules.member.vo.QrLoginStatusVO;
import com.jeesharp.framework.memberauth.web.BaseMobileController;
import com.jeesharp.framework.pojo.AjaxResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

/**
 * 移动端认证接口
 *
 * @author jeesharp
 */
@Slf4j
@RestController
@RequestMapping("${jeesharp.web.mobilePath}/member/auth")
@Tag(name = "移动端-登录认证", description = "APP/小程序/H5登录认证相关接口")
@AllArgsConstructor
public class AuthMobileController extends BaseMobileController {

    private final MobileAuthApplication mobileAuthService;

    // ==================== 验证码 ====================

    @Operation(summary = "发送短信验证码")
    @PostMapping("/sendSmsCode")
    public AjaxResult<Integer> sendSmsCode(@RequestBody @Valid SendSmsCodeDTO dto) {
        int expireSeconds = mobileAuthService.sendSmsCode(dto.getMobile(), dto.getScene());
        return AjaxResult.ok("验证码已发送", expireSeconds);
    }

    @Operation(summary = "发送邮件验证码")
    @PostMapping("/sendEmailCode")
    public AjaxResult<Integer> sendEmailCode(@RequestBody @Valid SendEmailCodeDTO dto) {
        int expireSeconds = mobileAuthService.sendEmailCode(dto.getEmail(), dto.getScene());
        return AjaxResult.ok("验证码已发送", expireSeconds);
    }

    // ==================== 登录方式 ====================

    @Operation(summary = "手机验证码登录")
    @PostMapping("/loginByMobile")
    public AjaxResult<LoginResultVO> loginByMobile(@RequestBody @Valid LoginByMobileDTO dto,
                                                  @RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
        LoginResultVO result = mobileAuthService.loginByMobile(dto, deviceId);
        return AjaxResult.okData(result);
    }

    @Operation(summary = "邮箱验证码登录")
    @PostMapping("/loginByEmail")
    public AjaxResult<LoginResultVO> loginByEmail(@RequestBody @Valid LoginByEmailDTO dto,
                                                 @RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
        LoginResultVO result = mobileAuthService.loginByEmail(dto, deviceId);
        return AjaxResult.okData(result);
    }

    @Operation(summary = "账号密码登录")
    @PostMapping("/loginByPassword")
    public AjaxResult<LoginResultVO> loginByPassword(@RequestBody @Valid LoginByPasswordDTO dto,
                                                    @RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
        LoginResultVO result = mobileAuthService.loginByPassword(dto, deviceId);
        return AjaxResult.okData(result);
    }

    @Operation(summary = "账号密码注册")
    @PostMapping("/registerByPassword")
    public AjaxResult<LoginResultVO> registerByPassword(@RequestBody @Valid RegisterByPasswordDTO dto,
                                                       @RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
        LoginResultVO result = mobileAuthService.registerByPassword(dto, deviceId);
        return AjaxResult.ok("注册成功", result);
    }

    @Operation(summary = "微信小程序登录")
    @PostMapping("/loginByWechatMini")
    public AjaxResult<LoginResultVO> loginByWechatMini(@RequestBody @Valid LoginByWechatMiniDTO dto,
                                                      @RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
        LoginResultVO result = mobileAuthService.loginByWechatMini(dto, deviceId);
        return AjaxResult.okData(result);
    }

    @Operation(summary = "微信小程序手机号一键登录")
    @PostMapping("/loginByWechatMiniPhone")
    public AjaxResult<LoginResultVO> loginByWechatMiniPhone(@RequestBody @Valid LoginByWechatMiniPhoneDTO dto,
                                                            @RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
        LoginResultVO result = mobileAuthService.loginByWechatMiniPhone(dto, deviceId);
        return AjaxResult.okData(result);
    }

    @Operation(summary = "微信APP登录")
    @PostMapping("/loginByWechatApp")
    public AjaxResult<LoginResultVO> loginByWechatApp(@RequestBody @Valid LoginByWechatDTO dto,
                                                     @RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
        LoginResultVO result = mobileAuthService.loginByWechatApp(dto, deviceId);
        return AjaxResult.okData(result);
    }

    @Operation(summary = "微信公众号登录")
    @PostMapping("/loginByWechatMp")
    public AjaxResult<LoginResultVO> loginByWechatMp(@RequestBody @Valid LoginByWechatDTO dto,
                                                     @RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
        LoginResultVO result = mobileAuthService.loginByWechatMp(dto, deviceId);
        return AjaxResult.okData(result);
    }

    @Operation(summary = "支付宝登录")
    @PostMapping("/loginByAlipay")
    public AjaxResult<LoginResultVO> loginByAlipay(@RequestBody @Valid LoginByAlipayDTO dto,
                                                  @RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
        LoginResultVO result = mobileAuthService.loginByAlipay(dto, deviceId);
        return AjaxResult.okData(result);
    }

    @Operation(summary = "苹果登录")
    @PostMapping("/loginByApple")
    public AjaxResult<LoginResultVO> loginByApple(@RequestBody @Valid LoginByAppleDTO dto,
                                                 @RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
        LoginResultVO result = mobileAuthService.loginByApple(dto, deviceId);
        return AjaxResult.okData(result);
    }

    @Operation(summary = "华为账号登录")
    @PostMapping("/loginByHuawei")
    public AjaxResult<LoginResultVO> loginByHuawei(@RequestBody @Valid LoginByThirdPartyDTO dto,
                                                  @RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
        LoginResultVO result = mobileAuthService.loginByHuawei(dto, deviceId);
        return AjaxResult.okData(result);
    }

    @Operation(summary = "华为原子化服务登录-起身一刻")
    @PostMapping("/loginByHuaweiAtomic")
    public AjaxResult<LoginResultVO> loginByHuaweiAtomic(@RequestBody @Valid LoginByThirdPartyDTO dto,
                                                        @RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
        LoginResultVO result = mobileAuthService.loginByHuaweiAtomic(dto, deviceId);
        return AjaxResult.okData(result);
    }

    @Operation(summary = "QQ登录")
    @PostMapping("/loginByQQ")
    public AjaxResult<LoginResultVO> loginByQQ(@RequestBody @Valid LoginByThirdPartyDTO dto,
                                              @RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
        LoginResultVO result = mobileAuthService.loginByQQ(dto, deviceId);
        return AjaxResult.okData(result);
    }

    @Operation(summary = "微博登录")
    @PostMapping("/loginByWeibo")
    public AjaxResult<LoginResultVO> loginByWeibo(@RequestBody @Valid LoginByThirdPartyDTO dto,
                                                 @RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
        LoginResultVO result = mobileAuthService.loginByWeibo(dto, deviceId);
        return AjaxResult.okData(result);
    }

    @Operation(summary = "抖音登录")
    @PostMapping("/loginByDouyin")
    public AjaxResult<LoginResultVO> loginByDouyin(@RequestBody @Valid LoginByThirdPartyDTO dto,
                                                  @RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
        LoginResultVO result = mobileAuthService.loginByDouyin(dto, deviceId);
        return AjaxResult.okData(result);
    }

    @Operation(summary = "一键登录（本机号码）")
    @PostMapping("/loginByOneClick")
    public AjaxResult<LoginResultVO> loginByOneClick(@RequestBody @Valid LoginByOneClickDTO dto,
                                                    @RequestHeader(value = "X-Device-Id", required = false) String deviceId) {
        LoginResultVO result = mobileAuthService.loginByOneClick(dto, deviceId);
        return AjaxResult.okData(result);
    }

    // ==================== 账号管理 ====================

    @Operation(summary = "绑定手机号")
    @PostMapping("/bindMobile")
    public AjaxResult<String> bindMobile(@RequestBody @Valid BindMobileDTO dto) {
        mobileAuthService.bindMobile(dto);
        return AjaxResult.ok("绑定成功", DesensitizedUtil.mobilePhone(dto.getMobile()));
    }

    @Operation(summary = "通过微信手机号code获取手机号")
    @PostMapping("/getPhoneByCode")
    public AjaxResult<String> getPhoneByCode(@RequestBody @Valid GetPhoneByCodeDTO dto) {
        String phone = mobileAuthService.getPhoneByCode(dto.getPhoneCode());
        return AjaxResult.okData(phone);
    }

    @Operation(summary = "重置密码（忘记密码）")
    @PostMapping("/resetPassword")
    public AjaxResult<Void> resetPassword(@RequestBody @Valid ResetPasswordDTO dto) {
        mobileAuthService.resetPassword(dto);
        return AjaxResult.ok("密码重置成功");
    }

    @Operation(summary = "获取加密公钥")
    @GetMapping("/publicKey")
    public AjaxResult<String> getPublicKey() {
        return AjaxResult.okData(mobileAuthService.getPublicKey());
    }

    // ==================== 二维码登录 ====================

    @Operation(summary = "生成二维码登录Token")
    @PostMapping("/qrLogin/generate")
    public AjaxResult<QrLoginTokenVO> generateQrLoginToken() {
        QrLoginTokenVO token = mobileAuthService.generateQrLoginToken();
        return AjaxResult.okData(token);
    }

    @Operation(summary = "检查二维码登录状态")
    @GetMapping("/qrLogin/check")
    public AjaxResult<QrLoginStatusVO> checkQrLoginStatus(@RequestParam("token") String token) {
        QrLoginStatusVO status = mobileAuthService.checkQrLoginStatus(token);
        return AjaxResult.okData(status);
    }

    @Operation(summary = "标记二维码已扫码（移动端扫码后调用，在确认登录之前）")
    @PostMapping("/qrLogin/scanned")
    public AjaxResult<Void> markQrCodeScanned(@RequestBody @Valid QrLoginConfirmDTO dto) {
        mobileAuthService.markQrCodeScanned(dto.getToken());
        return AjaxResult.ok("已标记为已扫码");
    }

    @Operation(summary = "确认二维码登录（移动端扫码后调用）")
    @PostMapping("/qrLogin/confirm")
    public AjaxResult<Void> confirmQrLogin(@RequestBody @Valid QrLoginConfirmDTO dto) {
        mobileAuthService.confirmQrLogin(dto.getToken());
        return AjaxResult.ok("登录成功");
    }
}
