package top.octopusyan.controller;

import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXCheckBox;
import com.jfoenix.controls.JFXPasswordField;
import com.jfoenix.controls.JFXTextField;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextInputDialog;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.kordamp.ikonli.javafx.FontIcon;
import top.octopusyan.base.BaseController;
import top.octopusyan.config.TextValidate;
import top.octopusyan.http.EasyHttp;
import top.octopusyan.http.api.NotParamApi;
import top.octopusyan.http.config.HttpConstant;
import top.octopusyan.http.listener.OnHttpListener;
import top.octopusyan.manager.ProxyManager;
import top.octopusyan.manager.http.Api;
import top.octopusyan.manager.http.request.FindPassParam;
import top.octopusyan.manager.http.request.LoginParam;
import top.octopusyan.model.ApplicatonStore;
import top.octopusyan.utils.AlertUtil;
import top.octopusyan.utils.JsoupUtil;

import java.io.IOException;

/**
 * @author : octopus yan
 * @email : octopus_yan@foxmail.com
 * @description : Login 控制器
 * @create : 2022-3-30 16:06
 */
public class LoginController extends BaseController<StackPane> implements Initializable {

    @FXML
    public StackPane root;

    @FXML
    public JFXButton closeBtn, minimizeBtn, loginBtn;
    @FXML
    public AnchorPane loginBottomPane;
    @FXML
    public ImageView loginBkgPane;
    @FXML
    public JFXButton registerBtn;
    @FXML
    public JFXTextField accountTextField;
    @FXML
    public JFXPasswordField passwordTextField;
    @FXML
    public JFXTextField seePwdTextField;
    @FXML
    public JFXButton accountIconBtn;
    @FXML
    public FontIcon accountIcon;
    @FXML
    public JFXButton pwdIconBtn;
    @FXML
    public FontIcon pwdIcon;
    @FXML
    public JFXButton seePwdIconBtn;
    @FXML
    public FontIcon seePwdIcon;
    @FXML
    public JFXCheckBox autoLoginCBox;
    @FXML
    public JFXCheckBox rememberCBox;
    @FXML
    public JFXButton findpassBtn;
    @FXML
    public Label appVersionLabel;

    private final SimpleStringProperty tmpPwd = new SimpleStringProperty();

    @Override
    public boolean dragWindow() {
        return true;
    }

    @Override
    public StackPane getRootPanel() {
        return root;
    }

    @NotNull
    @Override
    public String getRootFxmlPath() {
        return "/fxml/login.fxml";
    }

    @Override
    public Label getAppVersionLabel() {
        return appVersionLabel;
    }

    @Override
    public Button getClooseBtn() {
        return closeBtn;
    }

    @Override
    public Button getMinimizeBtn() {
        return minimizeBtn;
    }

    @Override
    public JFXButton getFirstBtn() {
        return minimizeBtn;
    }

    @Override
    public void initData() {
        // 数据绑定
        // 账号
        accountTextField.textProperty().bindBidirectional(ApplicatonStore.accountProperty());
        // 密码
        if (ApplicatonStore.isRememberMe()) tmpPwd.set(ApplicatonStore.getPassword());
        // 自动登录
        autoLoginCBox.selectedProperty().bindBidirectional(ApplicatonStore.autoLoginProperty());
        // 记住我
        rememberCBox.selectedProperty().bindBidirectional(ApplicatonStore.rememberMeProperty());


        passwordTextField.textProperty().bindBidirectional(tmpPwd);
        seePwdTextField.textProperty().bindBidirectional(tmpPwd);

    }

    // 隐藏展示密码框
    private AnchorPane pwdParent;

    private AlertUtil.Builder<TextInputDialog> findpassAlert;

    @Override
    public void initViewStyle() {

        // 文本框焦点状态监听
        accountTextField.focusedProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue) accountTextField.resetValidation();
        });
        passwordTextField.focusedProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue) passwordTextField.resetValidation();
        });
        seePwdTextField.focusedProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue) seePwdTextField.resetValidation();
        });

        // 隐藏展示密码框
        pwdParent = (AnchorPane) passwordTextField.getParent();
        pwdParent.getChildren().remove(seePwdTextField);

        // 添加文本校验
        accountTextField.getValidators().add(TextValidate.AccoountRequired);
        accountTextField.getValidators().add(TextValidate.AccoountValidator);
        accountTextField.getValidators().add(TextValidate.getLengthValidator(6, 18, "账号"));
        passwordTextField.getValidators().add(TextValidate.PasswordRequired);
        seePwdTextField.getValidators().add(TextValidate.PasswordRequired);

        // 自动登录
        autoLoginCBox.selectedProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue) ApplicatonStore.setRememberMe(true);
        });
    }

    @Override
    public void initViewAction() {

        // 注册
        registerBtn.setOnMouseClicked(event -> {
            ApplicatonStore.setPassword(tmpPwd.get());
            try {
                jumpTo(new RegisterController());
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        // 查看密码
        seePwdIconBtn.setOnMouseClicked(event -> {
            boolean isHide = pwdParent.getChildren().contains(passwordTextField);

            pwdParent.getChildren().remove(isHide ? passwordTextField : seePwdTextField);
            pwdParent.getChildren().add(1, isHide ? seePwdTextField : passwordTextField);
            (isHide ? seePwdTextField : passwordTextField).setText(tmpPwd.get());
            seePwdIcon.setIconColor(isHide ? Color.BLUE : Color.BLACK);
        });

        // 登录
        loginBtn.setOnMouseClicked(event -> login());
        accountTextField.setOnKeyPressed(event -> {
            if (event.getCode() == KeyCode.ENTER) login();
        });
        passwordTextField.setOnKeyPressed(event -> {
            if (event.getCode() == KeyCode.ENTER) login();
        });

        // 找回密码
        findpassBtn.setOnMouseClicked(event -> {
            findpassAlert = AlertUtil.input("请输入您的账号或邮箱")
                    .title("找回密码")
                    .header(null);
            findpass(findpassAlert.getInput());
        });

        // 自动登录
        if ((ApplicatonStore.isAutoLogin() || ApplicatonStore.isRegisterSuccess()) &&
                StringUtils.isNotEmpty(ApplicatonStore.getAccount()) &&
                StringUtils.isNotEmpty(ApplicatonStore.getPassword())
        ) {
            login();
        }
    }

    /**
     * 找回密码
     */
    private void findpass(String input) {
        if (StringUtils.isNotEmpty(input))
            EasyHttp.builder()
                    .api(Api.findpass)
                    .param(new FindPassParam(input))
                    .request(new OnHttpListener<String>() {
                        @Override
                        public void onSucceed(String result) {
                            Platform.runLater(() -> {
                                if (JsoupUtil.isAlertSuccess(result)) {
                                    AlertUtil.info(JsoupUtil.getSuccessMessage(result)).show();
                                } else {
                                    AlertUtil.error(JsoupUtil.getErrorMessage(result)).show();
                                }
                            });
                        }

                        @Override
                        public void onFail(Exception e) {
                            Platform.runLater(() -> AlertUtil.exceptionAlert(e).show());
                        }
                    });
    }

    private void login() {

        // 获取文本校验结果
        boolean pwdValidate = pwdParent.getChildren().contains(passwordTextField) ?
                passwordTextField.validate() : seePwdTextField.validate();
        boolean accountValidate = accountTextField.validate();

        if (pwdValidate && accountValidate)
            EasyHttp.builder()
                    .api(Api.Login)
                    .param(new LoginParam(accountTextField.getText(), tmpPwd.get()))
                    .request(new OnHttpListener<String>() {
                        @Override
                        public void onSucceed(String result) {
                            // 登录出错
                            if (!JsoupUtil.isAlertSuccess(result)) {
                                Platform.runLater(() -> AlertUtil.error(JsoupUtil.getErrorMessage(result)).show());
                                return;
                            }
                            // 登录成功
                            setCsrf();
                            // 用户token
                            setUSerToken();
                            // 记住我
                            ApplicatonStore.rememberMe(tmpPwd.get());
                            // 跳转
                            Platform.runLater(() -> {
                                try {
                                    jumpTo(new MainController());
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            });
                        }

                        @Override
                        public void onFail(Exception e) {

                        }
                    });
    }

    private void setUSerToken() {
        EasyHttp.builder()
                .api(Api.getServerConfiguration(1))
                .request(new OnHttpListener<String>() {
                    @Override
                    public void onSucceed(String result) {
                        String config = JsoupUtil.getServerConfiguration(result);
                        int start = config.indexOf("user = ");
                        String userToken = config.substring(start + 7, config.indexOf("\n", start));
                        Platform.runLater(() -> ApplicatonStore.setUserToken(userToken));
                    }

                    @Override
                    public void onFail(Exception e) {

                    }
                });
    }

    private void setCsrf() {
        EasyHttp.builder()
                .api(new NotParamApi<String>(
                        "/?page=panel&module=addproxy",
                        HttpConstant.Method.GET
                ))
                .request(new OnHttpListener<String>() {
                    @Override
                    public void onSucceed(String result) {
                        ProxyManager.setCsrf(result);
                    }

                    @Override
                    public void onFail(Exception e) {

                    }
                });
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}
