package com.moka.gdtauto.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.moka.gdtauto.annotation.AuthUser;
import com.moka.gdtauto.common.Result;
import com.moka.gdtauto.controller.vo.UserVo;
import com.moka.gdtauto.entity.SysUser;
import com.moka.gdtauto.service.SysUserService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 系统用户管理控制器
 * 
 * @author moka
 * @since 2026-02-07
 */
@Tag(name = "系统用户管理", description = "系统用户的增删改查与实名认证管理")
@Slf4j
@RestController
@RequestMapping("/api/user")
@RequiredArgsConstructor
public class SysUserController {

    private final SysUserService sysUserService;

    private static final String DEFAULT_PASSWORD = "123456";


    @PostMapping("/save")
    public Result<SysUser> saveUser(
            @Parameter(description = "用户名", required = true, example = "张三")
            @RequestParam String name,
            @Parameter(description = "工号", required = true, example = "123456")
            @RequestParam String jobNumber,
            @Parameter(description = "手机号", required = true, example = "12345678901")
            @RequestParam String phone
        ) {
            String pwd = DEFAULT_PASSWORD + "#" + jobNumber;
            System.out.println(pwd);
            String password = DigestUtils.md5DigestAsHex(pwd.getBytes());
            SysUser sysUser = new SysUser();
            sysUser.setPhone(phone);
            sysUser.setJobNumber(jobNumber);
            sysUser.setPassword(password);
            sysUser.setStatus(1);
            sysUser.setDefaultPwd(1);
            sysUser.setName(name);
            sysUserService.save(sysUser);
            return Result.success(sysUser, "保存成功");
    }

    /**
     * 用户登录
     * 
     * @param jobNumber 工号
     * @param password 密码
     * @return 登录结果
     */
    @Operation(
        summary = "用户登录",
        description = "通过工号和密码进行登录，返回用户信息和实名认证状态"
    )
    @PostMapping("/login")
    public Result<Map<String, Object>> login(
            @Parameter(description = "工号", required = true, example = "12458")
            @RequestParam String jobNumber,
            @Parameter(description = "密码", required = true, example = "123456")
            @RequestParam String password) {
        try {
            SysUser user = sysUserService.login(jobNumber, password);
            if (user == null) {
                return Result.fail("工号或密码错误");
            }
            
            // 检查实名认证状态
            boolean isTokenValid = sysUserService.isUserTokenValid(user);
            Map<String, Object> data = new HashMap<>();
            UserVo userVo = buildUserVo(user);
            data.put("user", userVo);
            data.put("loginToken", user.getLoginToken());
            data.put("isAuthenticated", isTokenValid);
            data.put("needAuthentication", !isTokenValid);
            data.put("isDefaultPassword", user.getDefaultPwd() == 1);
            
            String message = "登录成功";
            if (!isTokenValid) {
                message = "登录成功，但未完成实名认证或令牌已过期";
            }
            
            return Result.success(data, message);
        } catch (Exception e) {
            log.error("登录失败", e);
            return Result.fail("登录失败：" + e.getMessage());
        }
    }

    private UserVo buildUserVo(SysUser user) {
        return UserVo.builder()
                .id(user.getId())
                .name(user.getName())
                .jobNumber(user.getJobNumber())
                .status(user.getStatus())
                .defaultPwd(user.getDefaultPwd())
                .userToken(user.getUserToken())
                .userTokenExpiresAt(user.getUserTokenExpiresAt())
                .userStatus(user.getUserStatus())
                .build();
    }

    /**
     * 查询所有用户列表
     * 
     * @return 用户列表
     */
    @Operation(
        summary = "查询用户列表",
        description = "获取所有系统用户列表，包括用户基本信息和实名认证状态"
    )
    @GetMapping("/list")
    public Result<List<SysUser>> listUsers() {
        try {
            LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysUser::getDeleted, 0)
                    .orderByDesc(SysUser::getId);
            List<SysUser> users = sysUserService.list(wrapper);
            return Result.success(users, "查询成功")
                    .withCount(users.size());
        } catch (Exception e) {
            log.error("查询用户列表失败", e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 获取当前登录用户信息（使用 @AuthUser 注解示例）
     * 
     * @param currentUser 当前登录用户，由 AuthUserArgumentResolver 自动注入
     * @return 当前用户信息
     */
    @Operation(
        summary = "获取当前登录用户信息",
        description = "通过 @AuthUser 注解自动获取当前登录用户，无需传递参数"
    )
    @GetMapping("/current")
    public Result<Map<String, Object>> getCurrentUser(@AuthUser SysUser currentUser) {
        try {
            if (currentUser == null) {
                return Result.fail("未获取到当前登录用户信息");
            }
            
            Map<String, Object> data = new HashMap<>();
            data.put("jobNumber", currentUser.getJobNumber());
            data.put("name", currentUser.getName());
            data.put("status", currentUser.getStatus());
            data.put("userStatus", currentUser.getUserStatus());
            data.put("isDefaultPassword", currentUser.getDefaultPwd() == 1);
            
            // 检查实名认证状态
            boolean isAuthenticated = sysUserService.isUserTokenValid(currentUser);
            data.put("isAuthenticated", isAuthenticated);
            
            return Result.success(data, "获取成功");
        } catch (Exception e) {
            log.error("获取当前用户信息失败", e);
            return Result.fail("获取失败：" + e.getMessage());
        }
    }

    /**
     * 根据ID查询用户详情
     * 
     * @param id 用户ID
     * @return 用户详情
     */
    @Operation(
        summary = "查询用户详情",
        description = "根据用户ID查询用户详细信息"
    )
    @GetMapping("/info")
    public Result<UserVo> getUserInfo(
            @Parameter(description = "用户ID", required = true, example = "1")
            @RequestParam Long id) {
        try {
            SysUser user = sysUserService.getById(id);
            if (user != null && user.getDeleted() == 0) {
                UserVo userVo = buildUserVo(user);
                return Result.success(userVo, "查询成功");
            } else {
                return Result.fail("用户不存在");
            }
        } catch (Exception e) {
            log.error("查询用户详情失败", e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 根据工号查询用户
     * 
     * @param jobNumber 工号
     * @return 用户信息
     */
    @Operation(
        summary = "根据工号查询用户",
        description = "通过工号查询用户信息"
    )
    @GetMapping("/by-job-number")
    public Result<UserVo> getUserByJobNumber(
            @Parameter(description = "工号", required = true, example = "12358")
            @RequestParam String jobNumber) {
        try {
            SysUser user = sysUserService.getByJobNumber(jobNumber);
            if (user != null) {
                UserVo userVo = buildUserVo(user);
                return Result.success(userVo, "查询成功");
            } else {
                return Result.fail("用户不存在");
            }
        } catch (Exception e) {
            log.error("查询用户失败", e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 删除用户（逻辑删除）
     * 
     * @param id 用户ID
     * @return 删除结果
     */
    @Operation(
        summary = "删除用户",
        description = "逻辑删除用户，将deleted字段设置为1"
    )
    @PostMapping("/delete")
    public Result<Void> deleteUser(
            @Parameter(description = "用户ID", required = true, example = "1")
            @RequestParam Long id) {
        try {
            SysUser user = sysUserService.getById(id);
            if (user == null || user.getDeleted() == 1) {
                return Result.fail("用户不存在");
            }
            
            user.setDeleted(1);
            boolean success = sysUserService.updateById(user);
            if (success) {
                return Result.success(null, "删除成功");
            } else {
                return Result.fail("删除失败");
            }
        } catch (Exception e) {
            log.error("删除用户失败", e);
            return Result.fail("删除失败：" + e.getMessage());
        }
    }

    /**
     * 获取实名认证令牌授权URL
     * 用于获取user_token，必须在服务商系统或客户工作台完成实名认证后才能使用
     * 
     * @param redirectUri 回调地址
     * @param state 状态参数
     * @return 实名认证授权URL
     */
    @Operation(
        summary = "获取实名认证令牌URL",
        description = "生成腾讯广告平台的实名认证链接，引导用户微信扫码完成实名认证，获取user_token用于调用受限接口"
    )
    @GetMapping("/user-token-url")
    public Result<String> getUserTokenUrl(
            @Parameter(description = "工号", example = "12458")
            @RequestParam(required = true, defaultValue = "") String jobNumber) {
        try {
            String state = jobNumber;
            String userTokenUrl = sysUserService.getUserTokenUrl(state);
            return Result.success(userTokenUrl, "获取实名认证URL成功")
                    .withUsage("请将用户引导到此URL进行微信扫码实名认证")
                    .withNote("用户必须在服务商系统或客户工作台完成实名认证+组织认证");
        } catch (Exception e) {
            log.error("获取实名认证URL失败", e);
            return Result.fail("获取实名认证URL失败：" + e.getMessage());
        }
    }
    
    /**
     * 实名认证回调处理
     * 处理平台通用组件的回调，通过state参数传递手机号
     * 
     * @param userStatus 用户认证状态
     * @param userToken 实名认证令牌
     * @param expireTime 令牌过期时间戳
     * @param state 状态参数（格式：手机号，例如：13800138000）
     * @return 回调处理结果
     */
    @Operation(
        summary = "实名认证回调处理",
        description = "接收腾讯广告平台实名认证组件的回调，通过state参数获取手机号，保存user_token到用户表"
    )
    @GetMapping("/user-token-callback")
    public Result<UserVo> userTokenCallback(
            @Parameter(description = "用户认证状态: 0-未找到账号, 1-未完成实名认证, 2-已完成实名认证", required = true, example = "2")
            @RequestParam("user_status") Integer userStatus,
            @Parameter(description = "实名认证令牌", example = "abcdefghijklmn")
            @RequestParam(value = "user_token", required = false) String userToken,
            @Parameter(description = "令牌失效时间戳（秒）", example = "1748707200")
            @RequestParam(value = "expire_time", required = false) Long expireTime,
            @Parameter(description = "状态参数，用于传递工号", required = true, example = "12458")
            @RequestParam String state) {
        try {
            // state参数就工号
            String jobNumber = state;
            
            SysUser user = sysUserService.saveUserToken(jobNumber, userStatus, userToken, expireTime);
            UserVo userVo = buildUserVo(user);
            return Result.success(userVo, "实名认证令牌保存成功");
        } catch (Exception e) {
            log.error("保存实名认证令牌失败", e);
            return Result.fail("保存失败：" + e.getMessage());
        }
    }

    /**
     * 检查用户令牌是否有效
     * 
     * @param jobNumber 工号
     * @return 令牌有效性信息
     */
    @Operation(
        summary = "检查用户令牌有效性",
        description = "检查指定手机号用户的实名认证令牌是否有效"
    )
    @GetMapping("/token-valid")
    public Result<Boolean> checkTokenValid(
            @Parameter(description = "工号", required = true, example = "13099999999")
            @RequestParam String jobNumber) {
        try {
            SysUser user = sysUserService.getByJobNumber(jobNumber);
            if (user == null) {
                return Result.fail("用户不存在");
            }
            
            boolean isValid = sysUserService.isUserTokenValid(user);
            return Result.success(isValid, isValid ? "令牌有效" : "令牌无效或已过期")
                    .withNote(isValid ? 
                        "用户已完成实名认证且令牌在有效期内" : 
                        "请重新进行实名认证");
        } catch (Exception e) {
            log.error("检查令牌有效性失败", e);
            return Result.fail("检查失败：" + e.getMessage());
        }
    }

    /**
     * 修改密码
     * 
     * @param jobNumber 工号
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @return 修改结果
     */
    @Operation(
        summary = "修改密码",
        description = "用户修改密码，需要验证旧密码"
    )
    @PostMapping("/change-password")
    public Result<Void> changePassword(
            @Parameter(description = "工号", required = true, example = "12458")
            @RequestParam String jobNumber,
            @Parameter(description = "旧密码", required = true, example = "123456")
            @RequestParam String oldPassword,
            @Parameter(description = "新密码", required = true, example = "newPass123")
            @RequestParam String newPassword) {
        try {
            // 先验证旧密码
            SysUser user = sysUserService.login(jobNumber, oldPassword);
            if (user == null) {
                return Result.fail("旧密码错误");
            }
            
            // 修改密码
            boolean success = sysUserService.changePassword(jobNumber, newPassword);
            if (success) {
                return Result.success(null, "密码修改成功");
            } else {
                return Result.fail("密码修改失败");
            }
        } catch (Exception e) {
            log.error("修改密码失败", e);
            return Result.fail("修改密码失败：" + e.getMessage());
        }
    }
}
