package com.ruoyi.web.controller.system;

import cn.hutool.core.util.DesensitizedUtil;
import com.ruoyi.business.util.StringKit;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.domain.model.LoginBodyByPhone;
import com.ruoyi.common.core.domain.model.LoginUserByPhone;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.database.domain.BaseCustomerInfo;
import com.ruoyi.database.domain.LoginRequest;
import com.ruoyi.database.enums.LoginType;
import com.ruoyi.database.service.AlipayPhoneService;
import com.ruoyi.database.service.BaseCustomerInfoService;
import com.ruoyi.database.service.WechatPhoneService;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.system.service.ISysMenuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;
import java.util.Set;

/**
 * 登录验证
 *
 * @author ruoyi
 */
@Api(tags = "登录验证")
@RestController
public class SysLoginController {
    @Autowired
    private SysLoginService loginService;

    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private BaseCustomerInfoService baseCustomerInfoService;

    @Autowired
    private WechatPhoneService wechatPhoneService;

    @Autowired
    private AlipayPhoneService alipayPhoneService;

    @Value("${wx.pay.mchId}")
    public String wxMchId;

    /**
     * 登录方法
     *
     * @param loginBody 登录信息
     * @return 结果
     */
    @ApiOperation("管理员登录")
    @PostMapping("/login")
    public AjaxResult login(@RequestBody LoginBody loginBody) {
        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
                loginBody.getUuid());
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }

//    @ApiOperation("登录App")
//    @PostMapping("/loginApp")
//    public AjaxResult loginApp(LoginBody loginBody) {
//        AjaxResult ajax = AjaxResult.success();
//        loginBody.setCode("000000");
//        // 生成令牌
//        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
//                loginBody.getUuid());
//        ajax.put(Constants.TOKEN, token);
//        return ajax;
//    }



    @ApiOperation("根据手机号登录（没有的用户会创建）")
    @PostMapping("/loginByPhone")
    public AjaxResult loginByPhone(@Valid @RequestBody LoginRequest request) {

        validateLoginRequest(request);
        String phoneNumber = getPhoneNumberByLoginType(request);
        LoginBodyByPhone loginBodyByPhone = new LoginBodyByPhone();
        loginBodyByPhone.setPhone(phoneNumber);
        String openId = getOpenId(request);

        LoginType loginType = LoginType.getByCode(request.getLoginType());
        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        BaseCustomerInfo one = baseCustomerInfoService.lambdaQuery()
                .eq(BaseCustomerInfo::getPhone, loginBodyByPhone.getPhone())
                .last("limit 1")
                .one();
        switch (loginType) {
            case WECHAT:
                one.setOpenId(openId);
                break;
            case ALIPAY:
                one.setAlipayUserId(openId);
                break;
        }
        if (one == null) {
            BaseCustomerInfo baseCustomerInfo = new BaseCustomerInfo();
            baseCustomerInfo.setPhone(loginBodyByPhone.getPhone());
            baseCustomerInfo.setNickname(loginBodyByPhone.getPhone());
            baseCustomerInfoService.save(baseCustomerInfo);
        }else {
            baseCustomerInfoService.updateById(one);
        }
        String token = loginService.loginByPhone(loginBodyByPhone.getPhone());
        ajax.put(Constants.TOKEN, token);
        return ajax;

    }


    private void validateLoginRequest(LoginRequest request) {
        if (request.getLoginType() == null || request.getLoginType().trim().isEmpty()) {
            throw new IllegalArgumentException("登录方式不能为空");
        }
        if (request.getCode() == null || request.getCode().trim().isEmpty()) {
            throw new IllegalArgumentException("授权code不能为空");
        }

        // 验证登录方式是否支持
        try {
            LoginType.getByCode(request.getLoginType());
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("不支持的登录方式: " + request.getLoginType());
        }
    }

    /**
     * 根据登录方式获取手机号
     */
    private String getPhoneNumberByLoginType(LoginRequest request) {
        LoginType loginType = LoginType.getByCode(request.getLoginType());

        switch (loginType) {
            case WECHAT:
                return wechatPhoneService.getPhoneNumber(request.getCode());

            case ALIPAY:
                return alipayPhoneService.getPhoneNumber(request.getCode());

            default:
                throw new IllegalArgumentException("不支持的登录方式: " + loginType);
        }
    }

    /**
     * 获取用户openid
     * @param request
     * @return
     */
    private String getOpenId(LoginRequest request) {
        LoginType loginType = LoginType.getByCode(request.getLoginType());

        switch (loginType) {
            case WECHAT:
                return wechatPhoneService.getOpenId(request.getAuthCode());

            case ALIPAY:
                return alipayPhoneService.getAlipayUserId(request.getAuthCode());

            default:
                throw new IllegalArgumentException("不支持的登录方式: " + loginType);
        }
    }
    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @ApiOperation("获取管理员信息")
    @GetMapping("getInfo")
    public AjaxResult getInfo() {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        String areaAuthCode = StringKit.toString(user.getAreaAuthCode());
        if (!"".equals(areaAuthCode)) {
            if (!"0".equals(areaAuthCode)) {
                String result = truncateAndPad(areaAuthCode);
                user.setAreaAuthCode(result);
            }
        }

        // 角色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", user);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
    }


    @ApiOperation("获取客户信息")
    @GetMapping("getCustomerInfo")
    public AjaxResult getCustomerInfo(HttpServletRequest request) {
        LoginUserByPhone loginUser = loginService.getLoginUserByPhone(request);
        if (loginUser != null) {
            BaseCustomerInfo one = baseCustomerInfoService.lambdaQuery()
                    .eq(BaseCustomerInfo::getPhone, loginUser.getPhone())
                    .last("limit 1")
                    .one();
            one.setPhone(DesensitizedUtil.mobilePhone(one.getPhone()));
            one.setWxMchId(wxMchId);
            return AjaxResult.success(one);
        }
        return AjaxResult.success(loginUser);
    }



    public static String truncateAndPad(String str) {
        if ("0".equals(StringKit.toString(str))) {
            return str;
        }
        // 去掉后面的所有的0
        String trimmed = str.replaceAll("0*$", "");
        // 如果少于4位，补0到4位
        if (trimmed.length() < 4) {
            trimmed = String.format("%-4s", trimmed).replace(' ', '0');
        }
        return trimmed;
    }

    public static void main(String[] args) {

        String areaAuthCode = "0";
        String result = truncateAndPad(areaAuthCode);
        System.out.println(result);

    }


    /**
     * 获取路由信息
     *
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public AjaxResult getRouters() {
        Long userId = SecurityUtils.getUserId();
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
        return AjaxResult.success(menuService.buildMenus(menus));
    }
}
