/**
 * 请勿将俱乐部专享资源复制给其他人，保护知识产权即是保护我们所在的行业，进而保护我们自己的利益
 * 即便是公司的同事，也请尊重 JFinal 作者的努力与付出，不要复制给同事
 * <p>
 * 如果你尚未加入俱乐部，请立即删除该项目，或者现在加入俱乐部：http://jfinal.com/club
 * <p>
 * 俱乐部将提供 jfinal-club 项目文档与设计资源、专用 QQ 群，以及作者在俱乐部定期的分享与答疑，
 * 价值远比仅仅拥有 jfinal club 项目源代码要大得多
 * <p>
 * JFinal 俱乐部是五年以来首次寻求外部资源的尝试，以便于有资源创建更加
 * 高品质的产品与服务，为大家带来更大的价值，所以请大家多多支持，不要将
 * 首次的尝试扼杀在了摇篮之中
 */

package com.jfinal.club.login;

import com.jfinal.aop.Before;
import com.jfinal.aop.Clear;
import com.jfinal.aop.Inject;
import com.jfinal.club.common.kit.IpKit;
import com.jfinal.club.common.model.Users;
import com.jfinal.club.util.Cons;
import com.jfinal.core.ActionKey;
import com.jfinal.core.Controller;
import com.jfinal.kit.Ret;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 登录控制器
 */
public class LoginController extends Controller {

    @Inject
    LoginService srv;

    /**
     * 显示登录界面
     */
    public void index( ) {
        keepPara("returnUrl");  // 保持住 returnUrl 这个参数，以便在登录成功后跳转到该参数指向的页面
        render("login.html");
    }

    /**
     * 登录
     */
    @Before(LoginValidator.class)
    public void doLogin( ) {
        boolean keepLogin = getParaToBoolean("keepLogin", false);


        Users users = new Users( ).dao( ).findFirst("select * from users where phone=? and pwds = ?", getPara("phone"), getPara("pwds"));
        if (users == null) {
            renderJson(Ret.fail("msg", "用户或密码输入有误,请核对后提交!"));
            return;
        }
        Integer lock = Optional.ofNullable(users.getLock( )).orElse(0);
        if (lock == Cons.ONE) {
            renderJson(Ret.fail("msg", "该号已被上锁,请联系管理员解锁!"));
        } else {
            String loginIp = IpKit.getRealIp(getRequest( ));
            Map< String, String > map = getSessionAttr(getPara("phone"));
            Ret ret = srv.login(getPara("phone"), getPara("pwds"), keepLogin, loginIp, getPara("type"), map);
            if (ret.isOk( )) {
                String sessionId = ret.getStr(LoginService.sessionIdName);
                int maxAgeInSeconds = ret.getInt("maxAgeInSeconds");
                setCookie(LoginService.sessionIdName, sessionId, maxAgeInSeconds, true);
                setAttr(LoginService.loginUsersCacheName, ret.get(LoginService.loginUsersCacheName));
                ret.set("returnUrl", getPara("returnUrl", "/"));    // 如果 returnUrl 存在则跳过去，否则跳去首页
            }
            renderJson(ret);
        }
    }

    /**
     * 前台页面登录
     */
    public void hmLogin( ) {
        String phone = get("phone");
        String pwds = get("pwds");

        if (StringUtils.isBlank(phone)) {
            renderJson(Ret.fail("msg", "用户名不能为空!"));
            return;
        }
        if (StringUtils.isBlank(pwds)) {
            renderJson(Ret.fail("msg", "请输入密码!"));
            return;
        }

        Users users = new Users( ).dao( ).findFirst("select * from users where phone=? and pwds = ?", phone, pwds);
        if (users == null) {
            renderJson(Ret.fail("msg", "用户或密码输入有误,请核对后提交!"));
            return;
        }
        Integer lock = Optional.ofNullable(users.getLock( )).orElse(0);
        if (lock == Cons.ONE) {
            renderJson(Ret.fail("msg", "该号已被上锁,请联系管理员解锁!"));
        } else {
            Ret ret = srv.login(phone, pwds, true, IpKit.getRealIp(getRequest( )), "1", null);
            if (ret.isOk( )) {
                String sessionId = ret.getStr(LoginService.sessionIdName);
                int maxAgeInSeconds = ret.getInt("maxAgeInSeconds");
                setCookie(LoginService.sessionIdName, sessionId, maxAgeInSeconds, true);
                setAttr(LoginService.loginUsersCacheName, ret.get(LoginService.loginUsersCacheName));
                ret.set("returnUrl", getPara("returnUrl", "/"));    // 如果 returnUrl 存在则跳过去，否则跳去首页
            }
            renderJson(ret);
        }
    }

    /**
     * 退出登录
     */
    @Clear
    @ActionKey("/logout")
    public void logout( ) {
        srv.logout(getCookie(LoginService.sessionIdName));
        removeCookie(LoginService.sessionIdName);
        redirect("/");
    }

    /**
     * 显示忘记密码页面
     */
    public void forgetPassword( ) {
        render("forget_password.html");
    }

    public void tellogin( ) {
        render("tel_login.html");
    }


    /**
     * 1：keepPara("authCode") 将密码找回链接中问号挂参的 authCode 传递到页面
     * 2：在密码找回页面中与用户输入的新密码一起传回给 doPassReturn 进行密码修改
     */
    public void retrievePassword( ) {
        keepPara("authCode");
        render("retrieve_password.html");
    }

    /**
     * ajax 密码找回
     * 1：判断 authCode 是否有效
     * 2：有效则更新密码
     */
    public void doRetrievePassword( ) {
        Ret ret = srv.retrievePassword(getPara("authCode"), getPara("newPassword"));
        renderJson(ret);
    }

    public void captcha( ) {
        renderCaptcha( );
    }

    @Before(UpdatePasswordValidator.class)
    public void update( ) {
        String phone = get("phone");
        String pwds = get("pwds");
        Users users = srv.getByPhone(phone);
        users.setPwds(pwds);
        boolean update = users.removeNullValueAttrs( ).update( );
        if (update) {
            renderJson(Ret.ok("msg", "修改成功!"));
        } else {
            renderJson(Ret.fail("msg", "密码修改失败"));
        }
    }

}

