package com.cxyxiaomo.epp.user.controller;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.cxyxiaomo.epp.PageTable.enums.AddType;
import com.cxyxiaomo.epp.PageTable.enums.EditType;
import com.cxyxiaomo.epp.PageTable.enums.FieldType;
import com.cxyxiaomo.epp.PageTable.enums.SearchType;
import com.cxyxiaomo.epp.PageTable.query.PageQuery;
import com.cxyxiaomo.epp.PageTable.utils.FieldBuilder;
import com.cxyxiaomo.epp.PageTable.utils.FieldMapperBuilder;
import com.cxyxiaomo.epp.PageTable.utils.FieldRuleBuilder;
import com.cxyxiaomo.epp.PageTable.utils.FieldRuleListBuilder;
import com.cxyxiaomo.epp.common.pojo.Role;
import com.cxyxiaomo.epp.common.pojo.User;
import com.cxyxiaomo.epp.common.response.Res;
import com.cxyxiaomo.epp.common.vo.UserVO;
import com.cxyxiaomo.epp.user.rpc.WeChatTokenServiceFeign;
import com.cxyxiaomo.epp.user.service.RoleService;
import com.cxyxiaomo.epp.user.service.UserService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private RoleService roleService;

    @Resource
    private WeChatTokenServiceFeign weChatTokenService;

    /**
     * 用户登录
     *
     * @param username
     * @param password
     * @return
     */
    @PostMapping("/login")
    @ResponseBody
    public Res login(@RequestParam("username") String username, @RequestParam("password") String password) {
        // 微信小程序 随便看看
        if (Objects.equals(username, "#fastLogin#") && Objects.equals(password, "#fastLogin#")) {
            username = "user";
            password = "user";
        }

        User user = userService.getUserByUsername(username);
        if (user != null) {
            String passwordHash = DigestUtils.sha512Hex(password);
            if (passwordHash.equals(user.getPassword())) {
                HashMap<String, Object> map = new HashMap<>();
                map.put("userInfo", UserVO.convertFrom(user));
                return Res.success(map);
            } else {
                return Res.error("用户名或密码不正确");
            }
        } else {
            return Res.error("用户不存在");
        }
    }

    /**
     * 微信小程序用户登录
     *
     * @param code
     * @return
     */
    @PostMapping("/wxlogin")
    @ResponseBody
    public Res wxlogin(@RequestParam("code") String code) {
        // 微信小程序 登录页面 随便看看
        if (Objects.isNull(code)) {
            return Res.error("参数错误");
        }

        String jsonString = weChatTokenService.getOpenIdFromApi(code);
        JSONObject jsonObject = JSONObject.parseObject(jsonString);
        String openId = jsonObject.getString("data");
        if (Objects.isNull(openId) || "".equals(openId)) {
            return Res.error("微信接口异常，请重试");
        }

        User user = userService.getUserByWxcode(openId);
        if (user == null) {
            // 创建一个新用户
            user = new User();
            user.setId(null);
            user.setUsername(UUID.randomUUID().toString().replace("-", "").substring(0, 10));
            user.setPassword("");
            user.setRealname("微信用户" + user.getUsername().substring(0, 5));
            user.setRoleId(3);
            user.setPermission("1");
            user.setWxcode(openId);
            userService.addUser(user);
            // 添加之后 user.getId() 可以获取到用户id
            // System.out.println("userId: " + user.getId());
        }

        // 完成登录
        HashMap<String, Object> map = new HashMap<>();
        map.put("userInfo", UserVO.convertFrom(user));
        return Res.success(map);
    }

    /**
     * 通过用户ID获取用户信息
     *
     * @param id
     * @return
     */
    @PostMapping("/rpc/getUserById")
    @ResponseBody
    public User getUserById(Integer id) {
        return userService.getUserById(id);
    }

    /**
     * 修改密码的接口
     *
     * @param oldpwd
     * @param newpwd
     * @return
     */
    @PostMapping("/updatePwd")
    @ResponseBody
    public Res updatePwd(@RequestParam("userId") Integer userId,
                         @RequestParam("oldpwd") String oldpwd,
                         @RequestParam("newpwd") String newpwd) {
        if (newpwd == null || Objects.equals(newpwd, "")) {
            return Res.error("新密码不能为空");
        }
        if (oldpwd == null) {
            oldpwd = "";
        }
        // 调用Service层的方法，传入旧密码和新密码
        boolean result = userService.updatePwd(userId, oldpwd, newpwd);
        // 根据结果返回响应
        if (result) {
            return Res.success("修改成功");
        } else {
            return Res.error("旧密码不正确，修改失败");
        }
    }

    /**
     * 获取用户列表
     *
     * @return
     */
    @GetMapping("/manage/getUserList")
    @ResponseBody
    public Res getUserList(PageQuery pageQuery, UserVO userVO) {
        // 查询分页数据
        PageHelper.startPage(pageQuery.getPageIndex(), pageQuery.getPageSize());
        List<User> userList = userService.getUserList(userVO);
        PageInfo<User> userPageInfo = new PageInfo<>(userList);
        List<User> list = userPageInfo.getList();
        List<UserVO> voList = UserVO.convertFrom(list);

        // id列 字段名（区分大小写；以VO中的变量名为准）
        // 新增、修改弹窗时，使用该列作为主键列进行操作
        String idFieldName = "id";

        // 当前管理页面
        String pageName = "用户管理";

        // 指定前端表格显示列
        JSONArray columns = FieldBuilder.create()
                .add("username", "username", "账号", "",
                        FieldType.TEXT, SearchType.INPUT, AddType.INPUT, EditType.CAN_NOT_EDIT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        "用户名", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("用户名").required())
                                .add(FieldRuleBuilder.create("用户名").minMax(2, 10)),
                        "DPD @word(2, 10)"
                )
                .add("password", "password", "密码", "",
                        FieldType.HIDDEN, SearchType.CAN_NOT_SEARCH, AddType.INPUT, EditType.INPUT,
                        null,
                        "必填", "若不修改则留空",
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("用户密码").minMax(2, 10)),
                        "DPD @word(2, 10)"
                )
                .add("roleId", "roleName", "角色", "",
                        FieldType.TEXT, SearchType.SELECT, AddType.SELECT, EditType.SELECT,
                        "用户角色",
                        "用户的角色", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("角色").required()),
                        "DPD @pick([\"1\", \"2\", \"3\", \"4\", \"5\", \"6\"])"
                )
                .add("realname", "realname", "真实姓名", "",
                        FieldType.TEXT, SearchType.INPUT, AddType.INPUT, EditType.INPUT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        "用户的真实姓名", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("真实姓名").required())
                                .add(FieldRuleBuilder.create("真实姓名").minMax(2, 15)),
                        "DPD @cword(2, 8)"
                )
                .add("phoneNumber", "phoneNumber", "电话", "",
                        FieldType.TEXT, SearchType.INPUT, AddType.INPUT, EditType.INPUT,
                        "电话号码",
                        "支持11位手机号码、区号-7/8位座机号码", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("电话").required())
                                .add(FieldRuleBuilder.create("电话").pattern("^(1[3-9]\\d{9})$|^(0\\d{2,3}-?\\d{7,8})$")),
                        "DTD /^(1[3-9]\\d{9})$|^(0\\d{2,3}-?\\d{7,8})$/"
                )
                .add("idNumber", "idNumber", "身份证号", "",
                        FieldType.TEXT, SearchType.INPUT, AddType.INPUT, EditType.INPUT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        "支持15位、18位数字、17位数字+X格式", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("身份证号").required())
                                .add(FieldRuleBuilder.create("身份证号").min(15))
                                .add(FieldRuleBuilder.create("身份证号").max(18))
                                .add(FieldRuleBuilder.create("身份证号").pattern("^(\\d{15})$|^(\\d{18})$|^(\\d{17}(\\d|X|x))$")),
                        "DTD /^(\\d{15})$|^(\\d{18})$|^(\\d{17}(\\d|X|x))$/"
                )
                .add("buildingId", "buildingId", "门栋单元", "",
                        FieldType.TEXT, SearchType.INPUT, AddType.INPUT, EditType.INPUT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        "门栋及单元号，例如：11-05（11栋05单元）", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("门栋/单元号").minMax(2, 10)),
                        "DTD /^\\d{2}-\\d{2}$/"
                )
                .add("doorplate", "doorplate", "门牌号", "",
                        FieldType.TEXT, SearchType.INPUT, AddType.INPUT, EditType.INPUT,
                        FieldBuilder.SEARCH_PLACEHOLDER_SAME_AS_FIELDNAME,
                        "门牌号，例如：2003（20楼03户）", FieldBuilder.EDIT_PLACEHOLDER_SAME_AS_ADD_PLACEHOLDER,
                        FieldRuleListBuilder.create()
                                .add(FieldRuleBuilder.create("门牌号").minMax(1, 10)),
                        "DTD /^\\d{4}$/"
                )
                .build();

        // 指定需要翻译的字段
        // role -> roleName
        List<Role> roleList = roleService.getRoleList();
        HashMap roleMap = new HashMap();
        for (Role role : roleList) {
            roleMap.put(role.getId(), role.getRoleName());
        }
        // build
        JSONArray fieldMapper = FieldMapperBuilder.create()
                .add("roleId", "roleName", roleMap)
                .build();

        // 拼装返回结果
        JSONObject map = new JSONObject(6);
        map.put("total", userPageInfo.getTotal());
        map.put("list", voList);
        map.put("columns", columns);
        map.put("fieldMapper", fieldMapper);
        map.put("idFieldName", idFieldName);
        map.put("pageName", pageName);

        // 返回结果
        return Res.success(map);
    }

    /**
     * 新增 / 编辑用户
     *
     * @return
     */
    @PostMapping("/manage/editUser")
    @ResponseBody
    public Res editUser(@ModelAttribute UserVO userVO, String password) {
        User user = UserVO.convertTo(userVO);

        // 先查询用户名是否存在
        User existUser = userService.getUserByUsername(user.getUsername());

        if (user.getId() == null || user.getId() < 1) {
            // 新增用户
            if (existUser != null) {
                return Res.error("用户名已存在，操作失败");
            }
            if (password == null || "".equals(password)) {
                return Res.error("密码不能为空");
            }
            String passwordHash = DigestUtils.sha512Hex(password);
            user.setPassword(passwordHash);
            user.setId(null);
            userService.addUser(user);
        } else {
            // 修改用户
            if (existUser == null) {
                return Res.error("用户不存在，操作失败");
            }
            if (password == null || "".equals(password)) {
                user.setPassword(null);
            } else {
                String passwordHash = DigestUtils.sha512Hex(password);
                user.setPassword(passwordHash);
            }
            userService.updateUser(user);
        }
        return Res.success(true);
    }

    /**
     * 删除用户
     *
     * @param id
     * @return
     */
    @PostMapping("/manage/deleteUser")
    @ResponseBody
    public Res deleteUser(Integer id) {
        if (id == null || id <= 0) {
            return Res.error("用户不存在，删除失败");
        }
        // 先查询用户名是否存在
        User existUser = userService.getUserById(id);
        if (existUser == null) {
            return Res.error("用户不存在，删除失败");
        }
        boolean b = userService.deleteUser(existUser.getId());
        return Res.success(b);
    }

    /**
     * 导出用户列表
     *
     * @return
     */
    @GetMapping("/manage/exportUserList")
    @ResponseBody
    public Res exportUserList(UserVO userVO) {
        List<User> userList = userService.getUserList(userVO);
        List<UserVO> userVOList = UserVO.convertFrom(userList);

        // 当前时间
        Date now = Calendar.getInstance().getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd_HHmmss");
        String dateTime = format.format(now);

        HashMap<String, Object> map = new HashMap<>();
        map.put("list", userVOList);
        map.put("sheetName", "用户表-" + System.currentTimeMillis());
        map.put("fileName", "用户表_导出时间_" + dateTime);

        return Res.success(map);
    }
}
