package com.application.tak.takapplication;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.media.Image;
import android.net.sip.SipSession;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Base64;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import com.application.tak.takapplication.adapters.RVAdapterTaskNotSelected;
import com.application.tak.takapplication.data_access.CheckPassword;
import com.application.tak.takapplication.data_access.CheckUsernameExists;
import com.application.tak.takapplication.data_access.Config;
import com.application.tak.takapplication.data_access.GetUserById;
import com.application.tak.takapplication.data_access.GetUserByUsername;
import com.application.tak.takapplication.data_model.User;
import com.application.tak.takapplication.interfaces.OnDBRequestFinished;
import com.application.tak.takapplication.local_db.LocalDB;
import com.application.tak.takapplication.services.LoginStatus;
import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.GraphRequest;
import com.facebook.GraphResponse;
import com.facebook.Profile;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.tasks.Task;

import org.json.JSONException;
import org.json.JSONObject;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Signature;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

import static android.content.ContentValues.TAG;

public class actFirstUsage extends AppCompatActivity {


    Button btnClient;
    Button btnStudent;
    Context ctx;

    private EditText email;
    private EditText password;
    private Button btnLogin;
    private Button btnRegister;
    private Switch switchLoginModel;
    private ImageView imgclient;
    private ImageView imgstudent;
    private RadioButton rbFace;
    private RadioButton rbGoogle;
    private TextView mode;

    private static final int RC_SIGN_IN = 9001;
    GoogleSignInClient mGoogleSignInClient;
    CallbackManager callbackManager;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_act_first_usage);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        ctx = this.getApplicationContext();



        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .build();
        mGoogleSignInClient = GoogleSignIn.getClient(ctx, gso);
        callbackManager = CallbackManager.Factory.create();

        email = (EditText) findViewById(R.id.tbEmail) ;
        password = (EditText) findViewById(R.id.tbPassword);
        btnLogin = (Button) findViewById(R.id.btnLogin);
        btnRegister = (Button) findViewById(R.id.btnRegister);
        switchLoginModel = (Switch) findViewById(R.id.switchLoginType);
        imgclient = (ImageView) findViewById(R.id.imgClientMode);
        imgclient.setVisibility(View.INVISIBLE);
        imgstudent = (ImageView) findViewById(R.id.imgStudentMode);
        mode = (TextView) findViewById(R.id.lbMode);
        LoginButton fbloginButton = (LoginButton) findViewById(R.id.fblogin_button);

        rbGoogle = (RadioButton) findViewById(R.id.rbGoogle);
        rbFace = (RadioButton) findViewById(R.id.rbFacebook);


        password.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE))
                {
                    if(mode.getText() == "Klient" &&
                            !password.getText().toString().isEmpty() &&
                            !email.getText().toString().isEmpty())
                    {
                        btnLogin.performClick();
                    }
                }
                return false;
            }
        });

        btnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (mode.getText() == "Klient")
                {
                    CheckClientAuthentication(email.getText().toString(),password.getText().toString());
                }
                else if (mode.getText() == "Uczeń")
                {
                    if(rbFace.isChecked() || rbGoogle.isChecked())
                    {
                        if(rbFace.isChecked())
                        {
                            Profile profile = Profile.getCurrentProfile().getCurrentProfile();
                            if (profile != null) {
                                getFbInfo();
                            } else {
                                fbloginButton.performClick();
                            }
                        }
                        else if(rbGoogle.isChecked())
                        {
                            GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(ctx);
                            if (account != null) {
                                GoogleLogIn(account.getId());
                            }
                            else{
                                SignInGoogle();
                            }


                        }

                    }
                    else{
                        Toast.makeText(ctx,"Wybierz sposób logowania.", Toast.LENGTH_LONG).show();
                    }
                }
            }
        });

        btnRegister.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mode.getText() == "Klient"){

                    if(CanRegisterAs("Klient"))
                    {
                        Intent i = new Intent(ctx,actClientLogin.class);
                        startActivity(i);
                    }
                    else
                    {
                        Toast.makeText(ctx,"Na tym urządzeniu są zarejestrowani już uczniowie.\nNie można zarejestrować klienta.",Toast.LENGTH_LONG).show();
                    }
                }
                else if (mode.getText() == "Uczeń")
                {
                    if(CanRegisterAs("Student")) {
                        Intent i = new Intent(ctx, actStudentLogin.class);
                        startActivity(i);
                    }
                    else {
                        Toast.makeText(ctx, "Na tym urządzeniu są zarejestrowani już klienci.\nNie można zarejestrować ucznia.", Toast.LENGTH_LONG).show();
                    }
                }

            }
        });

        switchLoginModel.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                Animation slideDown = AnimationUtils.loadAnimation(ctx, R.anim.anim_slide_out_right);

                if(!isChecked) // klient
                {
                    //  imgstudent.setAnimation(slideDown);
                    imgclient.setVisibility(View.VISIBLE);
                    imgstudent.setVisibility(View.INVISIBLE);
                    rbFace.setVisibility(View.INVISIBLE);
                    rbGoogle.setVisibility(View.INVISIBLE);
                    email.setVisibility(View.VISIBLE);
                    password.setVisibility(View.VISIBLE);
                    mode.setText("Klient");
                    //HideKeyboard();

                }
                else //uczen
                {

                    //imgclient.setAnimation(slideDown);
                    imgstudent.setVisibility(View.VISIBLE);
                    imgclient.setVisibility(View.INVISIBLE);
                    rbFace.setVisibility(View.VISIBLE);
                    rbGoogle.setVisibility(View.VISIBLE);
                    email.setVisibility(View.INVISIBLE);
                    password.setVisibility(View.INVISIBLE);

                    mode.setText("Uczeń");
                    //HideKeyboard();
                }
            }
        });


        rbFace.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                rbFace.setChecked(isChecked);
                if (isChecked)
                {
                    rbGoogle.setChecked(false);
                    rbGoogle.setAlpha(0.5f);
                    rbFace.setAlpha(1f);
                }
                else
                {
                    rbFace.setAlpha(0.5f);
                    rbGoogle.setAlpha(1f);
                    rbGoogle.setChecked(true);
                }
            }
        });



        rbGoogle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                rbGoogle.setChecked(isChecked);
                if (isChecked)
                {
                    rbFace.setChecked(false);
                    rbFace.setAlpha(0.5f);
                    rbGoogle.setAlpha(1f);
                }
                else
                {
                    rbGoogle.setAlpha(0.5f);
                    rbFace.setChecked(true);
                    rbFace.setAlpha(1f);
                }
            }
        });


        switchLoginModel.performClick();

        fbloginButton.registerCallback(callbackManager,
                new FacebookCallback< LoginResult >() {@Override
                public void onSuccess(LoginResult loginResult) {

                    String accessToken = loginResult.getAccessToken()
                            .getToken();

                    GraphRequest request = GraphRequest.newMeRequest(
                            loginResult.getAccessToken(),
                            new GraphRequest.GraphJSONObjectCallback() {@Override
                            public void onCompleted(JSONObject object,
                                                    GraphResponse response) {
                                try {
                                    if(object.has("id"))
                                    {
                                        String id = object.getString("id");

                                        FacebookLogIn(id);
                                    }
                                    else{
                                        Toast.makeText(ctx,"Nastąpił problem z zalogowaniem się przez interfejs FB.\nSpróbuj ponownie później",Toast.LENGTH_LONG).show();
                                    }


                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }
                            }
                            });
                    Bundle parameters = new Bundle();
                    parameters.putString("fields",
                            "id");
                    request.setParameters(parameters);
                    request.executeAsync();
                }

                    @Override
                    public void onCancel() {
                        System.out.println("onCancel");
                    }

                    @Override
                    public void onError(FacebookException exception) {
                        System.out.println("onError");
                        Log.v("LoginActivity", exception.getCause().toString());
                    }
                });

        AutoLogIn();

    }

    void HideKeyboard()
    {
        View focused = getCurrentFocus();

        if (focused != null) {
            focused.clearFocus();
            InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(focused.getWindowToken(),0);
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //for facebook
        callbackManager.onActivityResult(requestCode, resultCode, data);

        //for google
        if (requestCode == RC_SIGN_IN)
        {
            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
            handleSignInResult(task);
        }
    }


    private void CheckClientAuthentication(String username, String password)
    {
        User u = new User();
        u.set_Username(username);
        u.set_Password(password);
        LoginStatus logStatus = new LoginStatus(ctx);
        logStatus.LogInClient(u,this);

    }

    private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
        try {
            GoogleSignInAccount account = completedTask.getResult(ApiException.class);

            GoogleLogIn(account.getId());
        } catch (ApiException e) {
            // The ApiException status code indicates the detailed failure reason.
            // Please refer to the GoogleSignInStatusCodes class reference for more information.
            Toast.makeText(ctx,"Nastąpił problem z zalogowaniem się przez interfejs Google.\nSpróbuj ponownie później",Toast.LENGTH_LONG).show();
            Log.w(TAG, "signInResult:failed code=" + e.getStatusCode());

        }
    }

    private void getFbInfo() {
        GraphRequest request = GraphRequest.newMeRequest(
                AccessToken.getCurrentAccessToken(),
                new GraphRequest.GraphJSONObjectCallback() {
                    @Override
                    public void onCompleted(
                            JSONObject object,
                            GraphResponse response) {
                        try {
                            String id = object.getString("id");
                            FacebookLogIn(id);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                });
        Bundle parameters = new Bundle();
        parameters.putString("fields", "id");
        request.setParameters(parameters);
        request.executeAsync();
    }

    void GoogleLogIn(String id)
    {
        LoginStatus logStatus = new LoginStatus(ctx);
        logStatus.LogInStudent("G-"+id, this);
    }

    void FacebookLogIn(String id)
    {
        LoginStatus logStatus = new LoginStatus(ctx);
        logStatus.LogInStudent("F-"+id, this);
    }

    private void SignInGoogle() {
        Intent signInIntent = mGoogleSignInClient.getSignInIntent();
        startActivityForResult(signInIntent, RC_SIGN_IN);
    }

    void AutoLogIn()
    {
        LoginStatus lgStatus = new LoginStatus(ctx);

        User u = lgStatus.IsLoggedIn();

        if(u!= null)
        {   GetUserById getUsr;
            if(u.get_RoleId() == 2)
            {
                getUsr = new GetUserById("Client",u.get_Id(),ctx, false);
            }
            else if(u.get_RoleId() == 1)
            {
                getUsr = new GetUserById("Student",u.get_Id(),ctx, false);
            }
            else{
                getUsr = new GetUserById("",-1,ctx, false);
            }

            if(getUsr != null)
            {
                getUsr.setDBRequestFinishedListener(new OnDBRequestFinished() {
                    @Override
                    public void onDBRequestFinished() {
                        if(getUsr._client!= null)
                        {
                            Config.LoggedInClient = getUsr._client;
                            Intent i = new Intent(ctx,actClientTask.class);
                            startActivity(i);
                            finish();
                        }
                        else if(getUsr._student != null)
                        {
                            Config.LoggedInStudent = getUsr._student;
                            Intent i = new Intent(ctx,actStudentTask.class);
                            startActivity(i);
                            finish();
                        }
                    }
                });

            }
        }
    }

    boolean CanRegisterAs(String mode)
    {
        LocalDB local = new LocalDB(ctx);

        List<User> users = local.GetAllUsers();

        if(users.size() > 0)
        {
            if(mode == "Klient")
            {
                //klient
                Integer role = users.get(0).get_RoleId();
                if(role == 2)
                    return true;
                else return false;
            }
            else
            {
                //student
                Integer role = users.get(0).get_RoleId();
                if(role == 1)
                    return true;
                else return false;
            }
        }
        else
        {
            return true;
        }

    }

}
