package com.izouma.awesomeadmin.web;

import com.izouma.awesomeadmin.constant.AppConstant;
import com.izouma.awesomeadmin.dto.Page;
import com.izouma.awesomeadmin.dto.Result;
import com.izouma.awesomeadmin.dto.TreeNode;
import com.izouma.awesomeadmin.model.DepartInfo;
import com.izouma.awesomeadmin.model.UserInfo;
import com.izouma.awesomeadmin.service.DepartInfoService;
import com.izouma.awesomeadmin.service.PowerInfoService;
import com.izouma.awesomeadmin.service.SysMenuService;
import com.izouma.awesomeadmin.service.UserInfoService;
import com.izouma.awesomeadmin.shiro.PhoneCodeToken;
import com.izouma.awesomeadmin.util.CookieUtil;
import com.izouma.awesomeadmin.util.ExportExcelUtil;
import org.activiti.engine.IdentityService;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

/**
 * user_info controller类
 * Tue Apr 17 10:32:49 CST 2018  Suo Chen Cheng
 */
@Controller
@RequestMapping("/userInfo")
public class UserInfoController extends BaseController {

    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private PowerInfoService powerInfoService;
    @Autowired
    private SysMenuService sysMenuService;
    @Autowired
    private DepartInfoService departInfoService;
    @Autowired
    private IdentityService identityService;

    /**
     * <p>获取全部记录。</p>
     */
    @RequiresAuthentication
    @RequestMapping(value = "/all", method = RequestMethod.GET)
    @ResponseBody
    public Result all(UserInfo record) {

        List<UserInfo> pp = userInfoService.getUserInfoList(record);
        return new Result(true, pp);
    }

    /**
     * <p>根据Id。</p>
     */
    @RequiresAuthentication
    @RequestMapping(value = "/getUserInfo", method = RequestMethod.GET)
    @ResponseBody
    public Result getUserInfo(@RequestParam(required = false, value = "id") String id) {


        try {
            if (StringUtils.isEmpty(id)) {
                Subject subject = SecurityUtils.getSubject();
                UserInfo userInfo = (UserInfo) subject.getPrincipal();
                if (userInfo != null) {
                    id = userInfo.getId().toString();
                } else {
                    return new Result(false, "失败");
                }
            }

            UserInfo data = userInfoService.getUserInfoById(id);
            if (data != null) {
                return new Result(true, data);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return new Result(false, "失败");
    }

    /**
     * <p>根据条件获取。</p>
     */
    @RequiresAuthentication
    @RequestMapping(value = "/getOne", method = RequestMethod.GET)
    @ResponseBody
    public Result getOne(UserInfo record) {

        UserInfo data = userInfoService.getUserInfo(record);
        return new Result(true, data);
    }

    /**
     * <p>分页查询。</p>
     */
    @RequiresAuthentication
    @RequestMapping(value = "/page", method = RequestMethod.GET)
    @ResponseBody
    public Result page(Page page, UserInfo record) {

        Map<String, Object> result = new HashMap<>();

        List<UserInfo> pp = userInfoService.getUserInfoByPage(page, record);

        result.put(AppConstant.PAGE, page);
        result.put("pp", pp);
        return new Result(true, result);
    }

    /**
     * <p>保存。</p>
     */
    @RequiresAuthentication
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    @ResponseBody
    public Result save(UserInfo record) {

        boolean num = userInfoService.createUserInfo(record);
        if (num) {
            return new Result(true, record.getId());
        }
        return new Result(false, "保存异常");
    }

    /**
     * <p>更新信息。</p>
     */
    @RequiresAuthentication
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @ResponseBody
    public Result updateUserInfo(UserInfo record) {

        boolean num = userInfoService.updateUserInfo(record);
        if (num) {
            return new Result(true, "保存成功");
        }
        return new Result(false, "保存异常");
    }

    /**
     * <p>删除。</p>
     */
    @RequiresAuthentication
    @RequestMapping(value = "/del", method = RequestMethod.POST)
    @ResponseBody
    public Result deleteUserInfo(@RequestParam(required = true, value = "id") String id) {

        boolean num = userInfoService.deleteUserInfo(id);
        if (num) {
            return new Result(true, "删除成功");
        }
        return new Result(false, "删除异常");
    }

    @RequiresAuthentication
    @RequestMapping(value = "/exportExcel", method = RequestMethod.GET)
    @ResponseBody
    public void exportExcel(HttpServletRequest request, HttpServletResponse response) throws Exception {

        List<UserInfo> userInfos = userInfoService.getUserInfoList(null);

        String sheetName = "用户信息";
        String titleName = "用户信息数据表";
        String fileName = "用户信息表";
        int columnNumber = 4;
        int[] columnWidth = {20, 20, 10, 20};
        String[] columnName = {"用户名", "昵称", "性别", "电话"};
        String[][] dataList = new String[userInfos.size()][4];

        for (int i = 0; i < userInfos.size(); i++) {
            dataList[i][0] = userInfos.get(i).getUsername();
            dataList[i][1] = userInfos.get(i).getNickname();
            dataList[i][2] = userInfos.get(i).getSex();
            dataList[i][3] = userInfos.get(i).getPhone();
        }

        ExportExcelUtil.ExportWithResponse(sheetName, titleName, fileName,
                columnNumber, columnWidth, columnName, dataList, response);
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ResponseBody
    public Result login(@RequestParam("username") String username, @RequestParam("password") String password,
                        @RequestParam(value = "remember", required = false, defaultValue = "false") boolean remember,
                        HttpServletResponse response, HttpServletRequest request) {
        Subject subject = SecurityUtils.getSubject();//获取当前用户对象
        //生成令牌(传入用户输入的账号和密码)
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        //认证登录
        try {
            //这里会加载自定义的realm
            subject.login(token);//把令牌放到login里面进行查询,如果查询账号和密码时候匹配,如果匹配就把user对象获取出来,失败就抛异常
            UserInfo user = (UserInfo) subject.getPrincipal();//获取登录成功的用户对象(以前是直接去service里面查)
            identityService.setAuthenticatedUserId(user.getId().toString());
            request.getSession(true).setAttribute("superUserId", String.valueOf(user.getId()));
            if (remember) {
                HttpSession session = request.getSession();
                CookieUtil.addCookie(response, "JSESSIONID", session.getId(), 3 * 24 * 60 * 60);
            }
            return new Result(true, "登录成功");
        } catch (AuthenticationException e) {
            e.printStackTrace();
            return new Result(false, "登录失败");
        }
    }

    @RequestMapping(value = "/loginSms", method = RequestMethod.POST)
    @ResponseBody
    public Result loginBySms(@RequestParam("phone") String phone, @RequestParam("code") String code, @RequestParam("sessionId") String sessionId, HttpServletRequest request, HttpServletResponse response) {
        Subject subject = SecurityUtils.getSubject();
        PhoneCodeToken phoneCodeToken = new PhoneCodeToken(phone, code, sessionId);
        try {
            subject.login(phoneCodeToken);
        } catch (AuthenticationException e) {
            e.printStackTrace();
            return new Result(false, e.getMessage());
        }
        UserInfo user = (UserInfo) subject.getPrincipal();
        identityService.setAuthenticatedUserId(user.getId().toString());
        HttpSession session = request.getSession();
        CookieUtil.addCookie(response, "JSESSIONID", session.getId(), 3 * 24 * 60 * 60);
        return new Result(true, user);
    }

    @RequiresAuthentication
    @RequestMapping(value = "/logout", method = RequestMethod.POST)
    @ResponseBody
    public Result logout() {

        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        identityService.setAuthenticatedUserId(null);
        return new Result(true, "已退出登录");
    }


    @RequestMapping(value = "/departInfoTree", method = RequestMethod.GET)
    @ResponseBody
    public Result departInfoTree(HttpServletRequest request, Page page, DepartInfo record, Integer includeParent) {
        Map<String, Object> result = new HashMap<>();
        //根据登录权限查看用户信息
        String userId = (String) request.getSession().getAttribute("superUserId");
        UserInfo userInfo = userInfoService.getUserInfoById(userId);
        String[] deptCodes = userInfo.getDepartId().split(",");
        DepartInfo departInfo = departInfoService.getDepartInfoById(deptCodes[deptCodes.length - 1]);
        List<DepartInfo> pp = departInfoService.getDepartInfoList(record);
        if (includeParent != null && includeParent == 1) {
            pp.addAll(departInfoService.getParentList(departInfo.getId()));
        }

        List<TreeNode> trees = new ArrayList<TreeNode>();
        List<TreeNode> tree = new ArrayList<TreeNode>();
        for (DepartInfo m : pp) {
            String[] leafs;
            if (m.getAllParentId() != null) {
                leafs = m.getAllParentId().split(",");
            } else {
                leafs = new String[0];
            }
            TreeNode treeNode = new TreeNode(m.getId() + "", m.getDepartName(), leafs.length == 0 ? "" : leafs[leafs.length - 1]);
            treeNode.setExtra(m.getId().toString());
            tree.add(treeNode);


        }
        for (TreeNode treeNode : tree) {
            if ("".equals(treeNode.getParentId())
                    || (record.getId().equals(treeNode.getId()) && (includeParent == null || includeParent == 0))) {
                trees.add(treeNode);
            }
            for (TreeNode it : tree) {
                if (it.getParentId().equals(treeNode.getId())) {
                    if (treeNode.getChildren() == null) {
                        treeNode.setChildren(new ArrayList<TreeNode>());
                    }
                    treeNode.getChildren().add(it);
                }
            }
        }

        result.put("pp", trees);
        return new Result(true, result);
    }
}

