package easydo.technology.system.rest;

import easydo.technology.components.JdbcClient;
import easydo.technology.config.RsaProperties;
import easydo.technology.exception.BadRequestException;
import easydo.technology.exception.BizException;
import easydo.technology.system.model.*;
import easydo.technology.utils.RsaUtils;
import easydo.technology.utils.SecurityUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/sysUser")
public class SysUserController {
    @Resource
    JdbcClient jdbcClient;
    @Resource
    DataSource dataSource;
    @Resource
    PasswordEncoder passwordEncoder;

    @RequestMapping(value = "/getList")
    public Object getList(@RequestBody Map<String, Object> map) throws Exception {
        Connection connection = dataSource.getConnection();
        try {
            Map<String, Object> paramMap = new HashMap<>();
            List<SysUser> list = jdbcClient.getJdbcList(map, SysUser.class);
            for (SysUser model : list) {
                // 1) 二次查询部门详情并回填到返回对象
                SysDept dept = new SysDept();
                dept.setId(model.getDeptId());
                dept = jdbcClient.getJdbcModel(dept, connection);
                model.setDept(dept);

                // 2) 二次查询用户角色并回填 roleList
                SysUsersRoles usersRoles = new SysUsersRoles();
                usersRoles.setUserId(model.getId());
                List<SysUsersRoles> rolesList = jdbcClient.getJdbcList(usersRoles, connection);
                List<Long> roleIdList = rolesList.stream().map(SysUsersRoles::getRoleId).collect(Collectors.toList());

                paramMap.put("idIn", roleIdList);
                List<SysRole> roleList = jdbcClient.getJdbcList(paramMap, SysRole.class, connection);
                model.setRoleList(roleList);

                // 3) 二次查询租户详情并回填 tenant（对齐 Go 版本 userGetList）
                if (model.getTenantId() != null) {
                    Tenant tenant = new Tenant();
                    tenant.setId(model.getTenantId());
                    tenant = jdbcClient.getJdbcModelById(tenant, connection);
                    model.setTenant(tenant);
                }
            }
            return new ResponseEntity<>(list, HttpStatus.OK);
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        } finally {
            connection.close();
        }
    }

    @RequestMapping(value = "/getPage")
    public Object getPage(@RequestBody Map<String, Object> map) throws Exception {
        Connection connection = dataSource.getConnection();
        try {
            Map<String, Object> paramMap = new HashMap<>();
            Map<String, Object> recordsPage = jdbcClient.getJdbcPage(map, SysUser.class, connection);
            List<SysUser> records = (List<SysUser>) recordsPage.get("records");
            for (SysUser model : records) {
                SysDept dept = new SysDept();
                dept.setId(model.getDeptId());
                dept = jdbcClient.getJdbcModel(dept, connection);
                model.setDept(dept);

                SysUsersRoles usersRoles = new SysUsersRoles();
                usersRoles.setUserId(model.getId());
                List<SysUsersRoles> rolesList = jdbcClient.getJdbcList(usersRoles, connection);
                List<Long> roleIdList = rolesList.stream().map(SysUsersRoles::getRoleId).collect(Collectors.toList());
                paramMap.put("idIn", roleIdList);
                List<SysRole> roleList = jdbcClient.getJdbcList(paramMap, SysRole.class, connection);
                model.setRoleList(roleList);

                if (model.getTenantId() != null) {
                    Tenant tenant = new Tenant();
                    tenant.setId(model.getTenantId());
                    tenant = jdbcClient.getJdbcModelById(tenant, connection);
                    model.setTenant(tenant);
                }
            }
            return new ResponseEntity<>(recordsPage, HttpStatus.OK);
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        } finally {
            connection.close();
        }
    }


    @RequestMapping(value = "/save")
    public Object add(@RequestBody SysUser model) throws Exception {
        Connection connection = dataSource.getConnection();
        try {
            connection.setAutoCommit(false);
            SysUser user = new SysUser();
            user.setUsername(model.getUsername());
            int count = jdbcClient.getJdbcCount(user, connection);
            if (count > 0) {
                throw new BizException("用户名已存在");
            }

            model.setPassword(passwordEncoder.encode("123456"));
            jdbcClient.jdbcInsert(model, connection);

            List<SysRole> roleList = model.getRoleList();
            for (SysRole rmodel : roleList) {
                SysUsersRoles usersRoles = new SysUsersRoles();
                usersRoles.setUserId(model.getId());
                usersRoles.setRoleId(rmodel.getId());
                jdbcClient.jdbcInsert(usersRoles, connection);
            }

            connection.commit();
            return new ResponseEntity<>(model, HttpStatus.OK);
        } catch (Exception e) {
            connection.rollback();
            throw new BizException(e.getMessage());
        } finally {
            connection.close();
        }
    }


    @RequestMapping(value = "/update")
    public Object update(@RequestBody SysUser model) throws Exception {
        Connection connection = dataSource.getConnection();
        try {
            connection.setAutoCommit(false);

            jdbcClient.jdbcUpdateById(model, connection);

            SysUsersRoles usersRoles = new SysUsersRoles();
            usersRoles.setUserId(model.getId());
            jdbcClient.jdbcRemove(usersRoles, connection);

            List<SysRole> roleList = model.getRoleList();
            for (SysRole rmodel : roleList) {
                usersRoles = new SysUsersRoles();
                usersRoles.setUserId(model.getId());
                usersRoles.setRoleId(rmodel.getId());
                jdbcClient.jdbcInsert(usersRoles, connection);
            }
            connection.commit();
            return new ResponseEntity<>(HttpStatus.OK);
        } catch (Exception e) {
            connection.rollback();
            throw new BizException(e.getMessage());
        } finally {
            connection.close();
        }
    }

    @RequestMapping(value = "/remove")
    public Object deleteProgram(@RequestBody SysUser model) throws Exception {
        Connection connection = dataSource.getConnection();
        try {
            connection.setAutoCommit(false);
            jdbcClient.jdbcRemoveById(model, connection);

            SysUsersRoles usersRoles = new SysUsersRoles();
            usersRoles.setUserId(model.getId());
            jdbcClient.jdbcRemove(usersRoles, connection);
            connection.commit();
            return new ResponseEntity<>(HttpStatus.OK);
        } catch (Exception e) {
            connection.rollback();
            throw new BizException(e.getMessage());
        } finally {
            connection.close();
        }
    }

    @RequestMapping(value = "/updatePass")
    public ResponseEntity<Object> updatePass(@RequestBody Map<String, Object> map) throws Exception {
        Connection connection = dataSource.getConnection();
        try {
            String oldPass = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, map.get("oldPass").toString());
            String newPass = RsaUtils.decryptByPrivateKey(RsaProperties.privateKey, map.get("newPass").toString());
            SysUser user = new SysUser();
            user.setUsername(SecurityUtils.getCurrentUsername());
            user = jdbcClient.getJdbcModel(user, connection);
            if (!passwordEncoder.matches(oldPass, user.getPassword())) {
                throw new BadRequestException("修改失败，旧密码错误");
            }
            if (passwordEncoder.matches(newPass, user.getPassword())) {
                throw new BadRequestException("新密码不能与旧密码相同");
            }
            user.setPassword(passwordEncoder.encode(newPass));
            jdbcClient.jdbcUpdateById(user, connection);
            return new ResponseEntity<>(HttpStatus.OK);
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        } finally {
            connection.close();
        }
    }

    @RequestMapping(value = "/resetPass")
    public Object resetPass(@RequestBody SysUser model) throws Exception {
        model.setPassword(passwordEncoder.encode("123456"));
        jdbcClient.jdbcUpdateById(model);
        return new ResponseEntity<>(HttpStatus.OK);
    }
}
