package com.stdproject.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.stdproject.common.OperationLog;
import com.stdproject.common.PageRequest;
import com.stdproject.common.Result;
import com.stdproject.entity.AppUser;
import com.stdproject.service.IAppUserService;
import com.stdproject.utils.PasswordUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 应用-用户表 前端控制器
 * </p>
 *
 * @author StdProject
 * @since 2023-12-07
 */
@Tag(name = "用户管理", description = "用户信息维护、用户角色分配、用户登录、用户修改密码、用户修改个人信息等功能")
@RestController
@RequestMapping("/app-user")
public class AppUserController {

    @Autowired
    private IAppUserService appUserService;

    @Operation(summary = "分页查询用户列表")
    @PostMapping("/page")
    @OperationLog(type = "06", module = "用户管理", description = "分页查询用户列表")
    public Result<IPage<AppUser>> page(@RequestBody @Valid PageRequest pageRequest) {
        Page<AppUser> page = new Page<>(pageRequest.getCurrent(), pageRequest.getSize());
        QueryWrapper<AppUser> queryWrapper = new QueryWrapper<>();
        
        // 关键字搜索
        if (StringUtils.hasText(pageRequest.getKeyword())) {
            queryWrapper.and(wrapper -> wrapper
                .like("username", pageRequest.getKeyword())
                .or().like("nickname", pageRequest.getKeyword())
                .or().like("email", pageRequest.getKeyword())
                .or().like("phone", pageRequest.getKeyword())
            );
        }
        
        // 排序
        if (StringUtils.hasText(pageRequest.getOrderBy())) {
            if ("asc".equalsIgnoreCase(pageRequest.getOrderDirection())) {
                queryWrapper.orderByAsc(pageRequest.getOrderBy());
            } else {
                queryWrapper.orderByDesc(pageRequest.getOrderBy());
            }
        } else {
            queryWrapper.orderByDesc("lastmodifydate");
        }
        
        IPage<AppUser> result = appUserService.page(page, queryWrapper);
        return Result.success(result);
    }

    @Operation(summary = "根据ID查询用户详情")
    @GetMapping("/{id}")
    @OperationLog(type = "06", module = "用户管理", description = "查询用户详情")
    public Result<AppUser> getById(@Parameter(description = "用户ID") @PathVariable String id) {
        AppUser user = appUserService.getById(id);
        if (user != null) {
            // 不返回密码信息
            user.setPassword(null);
        }
        return Result.success(user);
    }

    @Operation(summary = "根据用户名查询用户")
    @GetMapping("/username/{username}")
    @OperationLog(type = "06", module = "用户管理", description = "根据用户名查询用户")
    public Result<AppUser> getByUsername(@Parameter(description = "用户名") @PathVariable String username) {
        AppUser user = appUserService.findByUsername(username);
        if (user != null) {
            // 不返回密码信息
            user.setPassword(null);
        }
        return Result.success(user);
    }

    @Operation(summary = "新增用户")
    @PostMapping
    @OperationLog(type = "01", module = "用户管理", description = "新增用户")
    public Result<String> save(@RequestBody @Valid AppUser appUser) {
        // 检查用户名是否已存在
        AppUser existUser = appUserService.findByUsername(appUser.getUsername());
        if (existUser != null) {
            return Result.error("用户名已存在");
        }
        
        // 设置默认值
        if (!StringUtils.hasText(appUser.getStatus())) {
            appUser.setStatus("1"); // 默认有效
        }
        if (appUser.getPwdvalidperiod() == null) {
            appUser.setPwdvalidperiod(90); // 默认90天
        }
        if (appUser.getFailednum() == null) {
            appUser.setFailednum(0);
        }
        
        // 密码加密
        if (StringUtils.hasText(appUser.getPassword())) {
            appUser.setPassword(PasswordUtils.encodePassword(appUser.getPassword()));
        }
        
        appUser.setLastmodifydate(LocalDateTime.now());
        boolean success = appUserService.save(appUser);
        return success ? Result.success("新增成功") : Result.error("新增失败");
    }

    @Operation(summary = "修改用户")
    @PutMapping
    @OperationLog(type = "02", module = "用户管理", description = "修改用户")
    public Result<String> update(@RequestBody @Valid AppUser appUser) {
        // 检查用户是否存在
        AppUser existUser = appUserService.getById(appUser.getId());
        if (existUser == null) {
            return Result.error("用户不存在");
        }
        
        // 如果修改了用户名，检查新用户名是否已被其他用户使用
        if (!existUser.getUsername().equals(appUser.getUsername())) {
            AppUser userWithSameName = appUserService.findByUsername(appUser.getUsername());
            if (userWithSameName != null && !userWithSameName.getId().equals(appUser.getId())) {
                return Result.error("用户名已被其他用户使用");
            }
        }
        
        // 如果传入了新密码，进行加密
        if (StringUtils.hasText(appUser.getPassword())) {
            appUser.setPassword(PasswordUtils.encodePassword(appUser.getPassword()));
            appUser.setPwdresettime(LocalDateTime.now());
        } else {
            // 如果没有传入密码，保持原密码不变
            appUser.setPassword(existUser.getPassword());
        }
        
        appUser.setLastmodifydate(LocalDateTime.now());
        boolean success = appUserService.updateById(appUser);
        return success ? Result.success("修改成功") : Result.error("修改失败");
    }

    @Operation(summary = "删除用户")
    @DeleteMapping("/{id}")
    @OperationLog(type = "03", module = "用户管理", description = "删除用户")
    public Result<String> delete(@Parameter(description = "用户ID") @PathVariable String id) {
        boolean success = appUserService.removeById(id);
        return success ? Result.success("删除成功") : Result.error("删除失败");
    }

    @Operation(summary = "批量删除用户")
    @DeleteMapping("/batch")
    @OperationLog(type = "03", module = "用户管理", description = "批量删除用户")
    public Result<String> deleteBatch(@RequestBody List<String> ids) {
        boolean success = appUserService.removeByIds(ids);
        return success ? Result.success("批量删除成功") : Result.error("批量删除失败");
    }

    @Operation(summary = "修改用户密码")
    @PutMapping("/password/{id}")
    @OperationLog(type = "02", module = "用户管理", description = "修改用户密码")
    public Result<String> updatePassword(
            @Parameter(description = "用户ID") @PathVariable String id,
            @RequestBody PasswordUpdateRequest request) {
        AppUser user = appUserService.getById(id);
        if (user == null) {
            return Result.error("用户不存在");
        }
        
        // 验证旧密码
        if (!PasswordUtils.matches(request.getOldPassword(), user.getPassword())) {
            return Result.error("原密码错误");
        }
        
        // 更新新密码
        user.setPassword(PasswordUtils.encodePassword(request.getNewPassword()));
        user.setPwdresettime(LocalDateTime.now());
        user.setLastmodifydate(LocalDateTime.now());
        
        boolean success = appUserService.updateById(user);
        return success ? Result.success("密码修改成功") : Result.error("密码修改失败");
    }

    @Operation(summary = "重置用户密码")
    @PutMapping("/reset-password/{id}")
    @OperationLog(type = "02", module = "用户管理", description = "重置用户密码")
    public Result<String> resetPassword(
            @Parameter(description = "用户ID") @PathVariable String id,
            @RequestBody PasswordResetRequest request) {
        AppUser user = appUserService.getById(id);
        if (user == null) {
            return Result.error("用户不存在");
        }
        
        // 重置密码
        user.setPassword(PasswordUtils.encodePassword(request.getNewPassword()));
        user.setPwdresettime(LocalDateTime.now());
        user.setLastmodifydate(LocalDateTime.now());
        
        boolean success = appUserService.updateById(user);
        return success ? Result.success("密码重置成功") : Result.error("密码重置失败");
    }

    @Operation(summary = "启用/禁用用户")
    @PutMapping("/status/{id}")
    @OperationLog(type = "02", module = "用户管理", description = "启用/禁用用户")
    public Result<String> updateStatus(
            @Parameter(description = "用户ID") @PathVariable String id,
            @RequestParam String status) {
        AppUser user = appUserService.getById(id);
        if (user == null) {
            return Result.error("用户不存在");
        }
        
        user.setStatus(status);
        user.setLastmodifydate(LocalDateTime.now());
        
        boolean success = appUserService.updateById(user);
        String message = "1".equals(status) ? "启用成功" : "禁用成功";
        return success ? Result.success(message) : Result.error("操作失败");
    }

    @Operation(summary = "根据组织ID查询用户列表")
    @GetMapping("/org/{orgId}")
    @OperationLog(type = "06", module = "用户管理", description = "根据组织ID查询用户列表")
    public Result<List<AppUser>> getByOrgId(@Parameter(description = "组织ID") @PathVariable String orgId) {
        QueryWrapper<AppUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("orgid", orgId);
        queryWrapper.orderByDesc("lastmodifydate");
        
        List<AppUser> users = appUserService.list(queryWrapper);
        // 不返回密码信息
        users.forEach(user -> user.setPassword(null));
        
        return Result.success(users);
    }

    /**
     * 密码修改请求类
     */
    public static class PasswordUpdateRequest {
        private String oldPassword;
        private String newPassword;
        
        // getters and setters
        public String getOldPassword() { return oldPassword; }
        public void setOldPassword(String oldPassword) { this.oldPassword = oldPassword; }
        public String getNewPassword() { return newPassword; }
        public void setNewPassword(String newPassword) { this.newPassword = newPassword; }
    }

    /**
     * 密码重置请求类
     */
    public static class PasswordResetRequest {
        private String newPassword;
        
        // getters and setters
        public String getNewPassword() { return newPassword; }
        public void setNewPassword(String newPassword) { this.newPassword = newPassword; }
    }
}