package com.propertyManagement.web.controller.business.api;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.propertyManagement.business.domain.WxAccount;
import com.propertyManagement.business.domain.WxUser;
import com.propertyManagement.business.domain.bo.CodeLoginBo;
import com.propertyManagement.business.domain.vo.LoginWxUser;
import com.propertyManagement.business.mapper.WxAccountMapper;
import com.propertyManagement.business.mapper.WxUserMapper;
import com.propertyManagement.business.service.WxUserLoginService;
import com.propertyManagement.business.service.WxUserTokenService;
import com.propertyManagement.business.support.util.AuthUtil;
import com.propertyManagement.business.support.util.SendSms;
import com.propertyManagement.common.annotation.Anonymous;
import com.propertyManagement.common.constant.CacheConstants;
import com.propertyManagement.common.core.domain.LoginResult;
import com.propertyManagement.common.core.domain.R;
import com.propertyManagement.common.utils.VerifyCodeUtils;
import com.propertyManagement.common.utils.redis.RedisUtils;
import com.tencentcloudapi.sms.v20210111.models.SendStatus;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.time.Duration;
import java.util.List;

/**
 * 小程序登录
 *
 * @author liushuai
 * @date 2025-05-14
 */

@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/login")
public class ApiLoginController {

    private final WxUserLoginService wxUserLoginService;

    private final WxAccountMapper accountMapper;

    private final WxUserTokenService wxUserTokenService;

    private final WxUserMapper userMapper;

    private final SendSms sendSms;

    /**
     * 小程序静默授权登录
     *
     * @param bo 登录信息
     * @return 结果
     */
    @Operation(summary = "小程序静默授权登录")
    @Anonymous
    @PostMapping("/code")
    public R<LoginResult<LoginWxUser>> codeLogin(@RequestBody CodeLoginBo bo) {
        // 生成令牌
        LoginResult loginResult =  wxUserLoginService.codeLogin(bo);
        return R.ok(loginResult);
    }

    /**
     * 小程序手机号授权登录
     *
     * @param dto 登录信息
     * @return 结果
     */
    @Operation(summary = "小程序手机号授权登录")
    @Anonymous
    @PostMapping("/mobile")
    public R<LoginResult<LoginWxUser>> codeMobilLogin(@RequestBody CodeLoginBo dto) {
        // 生成令牌
        LoginResult loginResult =  wxUserLoginService.codeMobilLogin(dto);
        return R.ok(loginResult);
    }

    /**
     * 发送短信验证码
     * @param mobile 手机号
     * @return OK
     */
    @GetMapping("/sendSmsCode")
    public R<String> sendSmsCode(@Validated @Parameter(description = "手机号") @NotNull(message = "手机号不能为空") String mobile) {
        String code = VerifyCodeUtils.generateNumberCode(6);
        String[] phoneNumbers = new String[]{"+86" + mobile};  // 中国号码格式
        String[] templateParams = new String[]{code};  // 模板参数
        SendStatus[] sendStatuses = sendSms.send(phoneNumbers, templateParams);
        if (null == sendStatuses) {
            return R.fail("短信发送失败，请联系管理员");
        }
        SendStatus sendStatus = sendStatuses[0];
        if (!sendStatus.getCode().equals("Ok")) {
            return R.fail("短信发送失败,原因：" + sendStatus.getMessage());
        }
        RedisUtils.setCacheObject(CacheConstants.GUEST_PHONE_CODES + mobile, code, Duration.ofMinutes(5));
        return R.ok("短信发送成功，验证码：" + code);
    }

    /**
     * 员工登录
     * @param account 账号
     * @param password 密码
     * @return OK
     */
    @GetMapping("/accountLogin/{account}/{password}")
    public R<LoginWxUser> accountLogin(@NotEmpty(message = "账号不能为空") @PathVariable String account,
                                  @NotEmpty(message = "密码不能为空") @PathVariable String password) {
        LoginWxUser wxUser = AuthUtil.getWxUser();
        LambdaQueryWrapper<WxAccount> accountLambdaQueryWrapper = Wrappers.lambdaQuery();
        accountLambdaQueryWrapper.eq(WxAccount::getAccount, account).eq(WxAccount::getPossword, password);
        WxAccount wxAccount = accountMapper.selectOne(accountLambdaQueryWrapper);
        if (wxAccount == null) {
            return R.fail("登录失败，账号或密码错误");
        }
        wxUser.setAccountId(wxAccount.getAccountId());
        wxUser.setAccount(wxAccount.getAccount());
        wxUser.setAccountName(wxAccount.getName());
        wxUser.setAccountMobile(wxAccount.getMobile());
        wxUser.setAccountType(wxAccount.getType());
        wxUserTokenService.refreshToken(wxUser);
        return R.ok(wxUser);
    }

    /**
     * 用户详情
     * @return OK
     */
    @GetMapping("/userInfo")
    public R<LoginWxUser> userInfo() {
        LoginWxUser wxUser = AuthUtil.getWxUser();
        WxUser user = userMapper.selectById(AuthUtil.getWxUser().getId());
        BeanUtil.copyProperties(user, wxUser);
        wxUserTokenService.refreshToken(wxUser);
        LoginWxUser loginWxUser = RedisUtils.getCacheObject(CacheConstants.LOGIN_MERCHANT_TOKEN_KEY + wxUser.getToken());
        return R.ok(loginWxUser);
    }

    /**
     * 用户性别修改
     * @return OK
     */
    @PostMapping("/updateUserSex/{sex}")
    public R<LoginWxUser> updateUserSex(@PathVariable @NotNull(message = "性别不能为空") Integer sex) {
        LoginWxUser wxUser = AuthUtil.getWxUser();
        WxUser user = userMapper.selectById(AuthUtil.getWxUser().getId());
        user.setSex(sex);
        userMapper.updateById(user);
        BeanUtil.copyProperties(user, wxUser);
        wxUserTokenService.refreshToken(wxUser);
        LoginWxUser loginWxUser = RedisUtils.getCacheObject(CacheConstants.LOGIN_MERCHANT_TOKEN_KEY + wxUser.getToken());
        return R.ok(loginWxUser);
    }

}
