package cn.iocoder.byzs.module.web.controller.admin.login;

import cn.hutool.core.util.StrUtil;
import cn.iocoder.byzs.framework.common.enums.CommonStatusEnum;
import cn.iocoder.byzs.framework.common.pojo.CommonResult;
import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
import cn.iocoder.byzs.framework.security.config.SecurityProperties;
import cn.iocoder.byzs.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.byzs.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.byzs.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.byzs.module.system.controller.admin.auth.vo.AuthLoginReqVO;
import cn.iocoder.byzs.module.system.controller.admin.auth.vo.AuthLoginRespVO;
import cn.iocoder.byzs.module.system.controller.admin.auth.vo.AuthSmsLoginReqVO;
import cn.iocoder.byzs.module.system.controller.admin.auth.vo.AuthSmsSendReqVO;
import cn.iocoder.byzs.module.system.dal.dataobject.permission.RoleDO;
import cn.iocoder.byzs.module.system.dal.dataobject.tenant.TenantDO;
import cn.iocoder.byzs.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.byzs.module.system.enums.logger.LoginLogTypeEnum;
import cn.iocoder.byzs.module.system.service.auth.AdminAuthService;
import cn.iocoder.byzs.module.system.service.permission.PermissionService;
import cn.iocoder.byzs.module.system.service.permission.RoleService;
import cn.iocoder.byzs.module.system.service.tenant.TenantService;
import cn.iocoder.byzs.module.system.service.user.AdminUserService;
import cn.iocoder.byzs.module.web.controller.admin.login.vo.WebLoginVO;
import cn.iocoder.byzs.module.web.controller.admin.login.vo.WebRegisterVO;
import cn.iocoder.byzs.module.web.service.login.WebLoginServiceImpl;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.annotation.security.PermitAll;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.*;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static cn.iocoder.byzs.framework.common.pojo.CommonResult.success;

@Tag(name = "前端")
@RestController
@RequestMapping("/bjdxWeb/web")
public class WebLoginController {

    @Resource
    private TenantService tenantService;
    @Resource
    private AdminAuthService authService;
    @Resource
    private SecurityProperties securityProperties;
    @Resource
    private PermissionService permissionService;
    @Resource
    private RoleService roleService;
    @Resource
    private AdminUserService adminUserService;
    @Resource
    private WebLoginServiceImpl webLoginServiceImpl;


    @GetMapping("/getTenantIdByName")
    @PermitAll
    @TenantIgnore
    @Operation(summary = "使用租户名，获得租户编号", description = "登录界面，根据用户的租户名，获得租户编号")
    @Parameter(name = "name", description = "租户名", required = true, example = "1024")
    public CommonResult<Long> getTenantIdByName(@RequestParam("name") String name) {
        TenantDO tenant = tenantService.getTenantByName(name);
        return success(tenant != null ? tenant.getId() : null);
    }

    @PostMapping("/register")
    @PermitAll
    @Operation(summary = "注册租户")
    public CommonResult<Boolean> register(@RequestBody @Valid WebRegisterVO reqVO) {
        Long userId = webLoginServiceImpl.register(reqVO);
        return success(userId != null);
    }

    @PostMapping("/login")
    @PermitAll
    @TenantIgnore
    @Operation(summary = "使用账号密码登录")
    public CommonResult<WebLoginVO> login(@RequestBody @Valid AuthLoginReqVO reqVO) {
        return success(buildWebLoginVO(authService.login(reqVO)));
    }

    @PostMapping("/sms-login")
    @PermitAll
    @TenantIgnore
    @Operation(summary = "使用短信验证码登录")
    public CommonResult<WebLoginVO> smsLogin(@RequestBody @Valid AuthSmsLoginReqVO reqVO) {
        return success(buildWebLoginVO(authService.smsLogin(reqVO)));
    }

    @PostMapping("/send-sms-code")
    @PermitAll
    @TenantIgnore
    @Operation(summary = "发送手机验证码")
    public CommonResult<Boolean> sendLoginSmsCode(@RequestBody @Valid AuthSmsSendReqVO reqVO) {
        authService.sendSmsCode(reqVO);
        return success(true);
    }

    @PostMapping("/logout")
    @PermitAll
    @Operation(summary = "登出系统")
    public CommonResult<Boolean> logout(HttpServletRequest request) {
        String token = SecurityFrameworkUtils.obtainAuthorization(request,
                securityProperties.getTokenHeader(), securityProperties.getTokenParameter());
        if (StrUtil.isNotBlank(token)) {
            authService.logout(token, LoginLogTypeEnum.LOGOUT_SELF.getType());
        }
        return success(true);
    }

    @GetMapping("/getRoleRoute")
    @Operation(summary = "根据用户ID，取角色路由")
    public CommonResult<Set<String>> getRoleRoute() {
        Set<String> roleRouteSet = webLoginServiceImpl.getRoleRoute(WebFrameworkUtils.getLoginUserId());
        return success(roleRouteSet);
    }

    // 填充租户
    private WebLoginVO buildWebLoginVO(AuthLoginRespVO login) {
        // 转换为 WebLoginVO
        WebLoginVO webLoginVO = BeanUtils.toBean(login, WebLoginVO.class);

        // 确保租户ID存在
        if (webLoginVO.getTenantId() == null) {
            AdminUserDO user = adminUserService.getUser(webLoginVO.getUserId());
            if (user != null) {
                webLoginVO.setTenantId(user.getTenantId());
            }
        }

        // 填充租户名称
        TenantDO tenant = tenantService.getTenant(webLoginVO.getTenantId());
        if (tenant != null) {
            webLoginVO.setTenantName(tenant.getName());
        }

        return webLoginVO;
    }
}