package kz.arta.synergy.workflow.mobile.android.authorization.activities;

import android.Manifest;
import android.accounts.Account;
import android.accounts.AccountAuthenticatorActivity;
import android.accounts.AccountManager;
import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.StrictMode;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.devspark.appmsg.AppMsg;
import com.pnikosis.materialishprogress.ProgressWheel;

import java.io.File;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.Certificate;

import kz.arta.synergy.workflow.mobile.android.R;
import kz.arta.synergy.workflow.mobile.android.authorization.GetCertificate;
import kz.arta.synergy.workflow.mobile.android.authorization.SynergyAccount;
import kz.arta.synergy.workflow.mobile.android.common.activities.MainActivity;
import kz.arta.synergy.workflow.mobile.android.common.components.AuthorizationEditText;
import kz.arta.synergy.workflow.mobile.android.common.models.Person;
import kz.arta.synergy.workflow.mobile.android.common.requests.SendGetRequest;
import kz.arta.synergy.workflow.mobile.android.common.utils.Const;
import kz.arta.synergy.workflow.mobile.android.common.utils.Fonts;

/**
 * Created by neox on 14.03.14.
 *
 * Экран авторизации
 */
public class AuthorizationActivity extends AccountAuthenticatorActivity {

    private static final int QR_CODE_ACTIVITY = 1;
    /**
     * Все нормально
     */
    private static final int OK = 0;
    /**
     * Используется HTTP соединение
     */
    private static final int HTTP_CONNECTION = 1;
    /**
     * Прогрессбар
     */
    private ProgressWheel progressBar;
    /**
     * Поле для ввода логина
     */
    private AuthorizationEditText login;
    /**
     * Поле для ввода хоста
     */
    private AuthorizationEditText host;
    /**
     * Активити
     */
    private Activity activity;
    /**
     * Пользователь
     */
    private Person person;
    /**
     * Менеджер аккаунтов
     */
    private AccountManager accountManager;
    /**
     * Статус выполнения запроса
     */
    private int status;



    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.authorization_activity);

        activity = this;

        ActionBar actionBar = getActionBar();
        if (actionBar != null) {
            actionBar.hide();
        }

        accountManager = AccountManager.get(this);

        person = new Person();

        initComponents();

        Intent intent = getIntent();

        if (intent != null && intent.getBooleanExtra(SynergyAccount.FILE_AUTH, false)) {
            login.setText(intent.getStringExtra(SynergyAccount.LOGIN));
            host.setText(intent.getStringExtra(SynergyAccount.HOST));
            nextButtonPressed();
        }

        isStoragePermissionGranted();
        isCameraPermissionGranted();
    }

    public boolean isStoragePermissionGranted() {
        if (Build.VERSION.SDK_INT >= 30) {
            if (Environment.isExternalStorageManager()) {
                return true;
            } else {
                try {
                    Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                    intent.addCategory("android.intent.category.DEFAULT");
                    intent.setData(Uri.parse(String.format("package:%s", activity.getPackageName())));
                    activity.startActivityForResult(intent, 100);
                } catch (Exception e) {
                    Intent intent = new Intent();
                    intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                    activity.startActivityForResult(intent, 100);
                }
                return false;
            }
        } else if (Build.VERSION.SDK_INT >= 23) {
            if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                return true;
            } else {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
                return false;
            }
        } else {
            return true;
        }
    }

    public boolean isCameraPermissionGranted() {
        if (Build.VERSION.SDK_INT >= 23) {
            if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
                return true;
            } else {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 101);
                return false;
            }
        } else {
            return true;
        }
    }

    /**
     * Инициализация компонентов
     */
    private void initComponents() {

        // заголовки
        ((TextView) findViewById(R.id.authorization_qr_code_title)).setTypeface(Fonts.getRoman(activity));
        ((TextView) findViewById(R.id.authorization_enter_information_title)).setTypeface(Fonts.getRoman(activity));
        ((TextView) findViewById(R.id.authorization_host_title)).setTypeface(Fonts.getRoman(activity));
        ((TextView) findViewById(R.id.authorization_host_title2)).setTypeface(Fonts.getRoman(activity));
        ((TextView) findViewById(R.id.authorization_login_title)).setTypeface(Fonts.getRoman(activity));

        // прогрессбар
        progressBar = (ProgressWheel) findViewById(R.id.authorization_progress_bar);

        // логин
        login = (AuthorizationEditText) findViewById(R.id.login);

        // хост
        host = (AuthorizationEditText) findViewById(R.id.host);

        // кнопка "Сканировать QR-код"
        final Button qrCodeButton = (Button) findViewById(R.id.authorization_qr_code_button);
        qrCodeButton.setTypeface(Fonts.getMedium(activity));
        qrCodeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (isCameraPermissionGranted()) {
                    Intent intent = new Intent(activity, QrCodeActivity.class);
                    startActivityForResult(intent, QR_CODE_ACTIVITY);
                }
            }
        });

        // кнопка "Войти"
        final Button enterButton = (Button) findViewById(R.id.authorization_enter_button);
        enterButton.setTypeface(Fonts.getMedium(activity));
        enterButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                nextButtonPressed();
            }
        });

        // получение списка аккаунтов
        Account[] accounts = accountManager.getAccounts();
        for (Account account : accounts) {
            if (!account.type.equals(SynergyAccount.TYPE)) {
                continue;
            }
            login.setText(accountManager.getUserData(account, SynergyAccount.LOGIN));
            host.setText(accountManager.getUserData(account, SynergyAccount.HOST));
            break;
        }
    }

    /**
     * Метод вызывается при нажатии на кнопку "Войти"
     */
    private void nextButtonPressed() {

        // валидация логина
        if (TextUtils.isEmpty(login.getText())) {
            login.setErrorBackground();
        } else {
            login.setNormalBackground();
        }

        // валидация хоста
        if (TextUtils.isEmpty(host.getText())) {
            host.setErrorBackground();
        } else {
            host.setNormalBackground();
        }

        if (TextUtils.isEmpty(login.getText()) || TextUtils.isEmpty(host.getText())) {
            AppMsg.makeTextBottom(activity, getString(R.string.empty_edit)).show();
            return;
        }

        File file = new File(Environment.getExternalStorageDirectory() +
                File.separator + Const.DIRECTORY_PHOTOS_NAME + File.separator + Const.USER_ICON_NAME);
        if (file.exists()) {
            file.delete();
        }

        // авторизация
        auth();
    }

    /**
     * Метод пытается понять валидный ли пользователь ввел хост
     */
    @SuppressLint("StaticFieldLeak")
    private void auth() {
        new AsyncTask<Void, String, Boolean>() {
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                progressBar.setVisibility(View.VISIBLE);
                String hst = host.getText().toString();
                String synergy = "Synergy.";
                if (hst.startsWith("http://")) {
                    hst = hst.replaceFirst("http://","");
                } else if (hst.startsWith("https://")) {
                    hst = hst.replaceFirst("https://","");
                }
                if (hst.contains(":8080")) {
                    hst = hst.replace(":8080","");
                } else if (hst.contains(":443")) {
                    hst = hst.replace(":443","");
                }
                if (hst.endsWith("/")) {
                    hst = hst.replace("/","");
                }
                if(hst.contains(synergy)){
                    int index = hst.indexOf(synergy);
                    if(index != 1){
                        hst = hst.replace(synergy,synergy.toLowerCase());
                    }
                }
                if (hst.contains("Synergy")) {
                    hst = hst.replace("Synergy","");
                }
                if (hst.endsWith("/")) {
                    hst = hst.replace("/","");
                }

                person.setShortHost(hst);
                person.setHost(host.getText().toString());
                person.setLogin(login.getText().toString());

            }

            @Override
            protected void onPostExecute(Boolean result) {
                super.onPostExecute(result);
                progressBar.setVisibility(View.GONE);
                if (!result) {
                    AppMsg.makeTextBottom(activity, getString(R.string.server_not_response)).show();
                    return;
                }
                if (person.getHost().contains("https")) {
                    startActivity();
                } else {
                    showHttpDialog();
                }
            }

            @Override
            protected void onProgressUpdate(String... values) {
                super.onProgressUpdate(values);
                AppMsg.makeTextBottom(activity, values[0]).show();
            }

            @Override
            protected Boolean doInBackground(Void... voids) {
                try {
                    URL httpsURL = new URL("https://" + person.getShortHost());
                    HttpURLConnection connection = (HttpURLConnection) httpsURL.openConnection();
                    connection.setReadTimeout(SendGetRequest.TIMEOUT);
                    connection.connect();
                    status = OK;
                } catch (Exception exc) {
                    try {
                        GetCertificate getCertificate = new GetCertificate();
                        Certificate cert = getCertificate.getCert(person.getShortHost());
                        getCertificate.save(cert);
                    } catch (Exception e) {
                        status = HTTP_CONNECTION;
                    }
                }
                return parseHost();
            }
        }.execute();
    }

    /**
     * Метод пытается преобразовать хост в валидный
     *
     * @return true - успешно, false - неуспешно
     */
    private boolean parseHost() {
        if (status == HTTP_CONNECTION) {
            String result = SendGetRequest.request("http://" + person.getShortHost() + "/Synergy/about");
            if (result != null && result.contains("About")) {
                person.setHost("http://" + person.getShortHost() + "/Synergy/");
                return true;
            }
            result = SendGetRequest.request("http://" + person.getShortHost() + ":8080/Synergy/about");
            if (result != null && result.contains("About")) {
                person.setHost("http://" + person.getShortHost() + ":8080/Synergy/");
                return true;
            }
            result = SendGetRequest.request("http://" + person.getShortHost() + "/about");
            if (result != null && result.contains("About")) {
                person.setHost("http://" + person.getShortHost() + "/");
                return true;
            }
            result = SendGetRequest.request("http://" + person.getShortHost() + ":8080/about");
            if (result != null && result.contains("About")) {
                person.setHost("http://" + person.getShortHost() + ":8080/");
                return true;
            }
        } else {
            String result = SendGetRequest.request("https://" + person.getShortHost() + "/Synergy/about");
            if (result != null && result.contains("About")) {
                person.setHost("https://" + person.getShortHost() + "/Synergy/");
                return true;
            }
            result = SendGetRequest.request("https://" + person.getShortHost() + ":443/Synergy/about");
            if (result != null && result.contains("About")) {
                person.setHost("https://" + person.getShortHost() + ":443/Synergy/");
                return true;
            }
            result = SendGetRequest.request("https://" + person.getShortHost() + "/about");
            if (result != null && result.contains("About")) {
                person.setHost("https://" + person.getShortHost() + "/");
                return true;
            }
            result = SendGetRequest.request("https://" + person.getShortHost() + ":443/about");
            if (result != null && result.contains("About")) {
                person.setHost("https://" + person.getShortHost() + ":443/");
                return true;
            }
            result = SendGetRequest.request("http://" + person.getShortHost() + "/Synergy/about");
            if (result != null && result.contains("About")) {
                person.setHost("http://" + person.getShortHost() + "/Synergy/");
                return true;
            }
            result = SendGetRequest.request("http://" + person.getShortHost() + ":8080/Synergy/about");
            if (result != null && result.contains("About")) {
                person.setHost("http://" + person.getShortHost() + ":8080/Synergy/");
                return true;
            }
            result = SendGetRequest.request("http://" + person.getShortHost() + "/about");
            if (result != null && result.contains("About")) {
                person.setHost("http://" + person.getShortHost() + "/");
                return true;
            }
            result = SendGetRequest.request("http://" + person.getShortHost() + ":8080/about");
            if (result != null && result.contains("About")) {
                person.setHost("http://" + person.getShortHost() + ":8080/");
                return true;
            }
        }
        return false;
    }

    /**
     * Метод отображает диалог о незашифрованном соединении
     */
    private void showHttpDialog() {
        AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
        dialog.setTitle(R.string.attention);
        dialog.setMessage(R.string.connection_is_not_protected);
        dialog.setNegativeButton(R.string.call_off, null);
        dialog.setPositiveButton(R.string.accept, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                startActivity();
            }
        });
        dialog.setCancelable(true);
        dialog.show();
    }

    /**
     * Метод записывает в менеджер аккаунтов новый аккаунт и открывает второй экран для авторизации
     */
    private void startActivity() {

        // записываем данные пользователя в менеджер аккаунтов в системе
        SynergyAccount synergyAccount = new SynergyAccount(SynergyAccount.TYPE);
        synergyAccount.setLogin(person.getLogin());
        synergyAccount.setHost(person.getHost());
        synergyAccount.setShortHost(person.getShortHost());

        final Bundle result = new Bundle();

        // если аккаунта еще нет в системе - добавляем его, иначе - изменяем
        if (accountManager.addAccountExplicitly(synergyAccount, "", new Bundle())) {
            result.putString(AccountManager.KEY_ACCOUNT_NAME, SynergyAccount.TYPE);
            result.putString(AccountManager.KEY_ACCOUNT_TYPE, synergyAccount.type);
            result.putString(AccountManager.KEY_AUTHTOKEN, SynergyAccount.TYPE);
            accountManager.setAuthToken(synergyAccount, synergyAccount.type, SynergyAccount.TYPE);
            accountManager.setUserData(synergyAccount, SynergyAccount.LOGIN, person.getLogin());
            accountManager.setUserData(synergyAccount, SynergyAccount.HOST, person.getHost());
            accountManager.setUserData(synergyAccount, SynergyAccount.SHORT_HOST, person.getShortHost());
            accountManager.setUserData(synergyAccount, SynergyAccount.SERVER_NAME, "");
            accountManager.setUserData(synergyAccount, SynergyAccount.FIRSTNAME, "");
            accountManager.setUserData(synergyAccount, SynergyAccount.LASTNAME, "");
            accountManager.setPassword(synergyAccount, "");
        } else {
            accountManager.setUserData(synergyAccount, SynergyAccount.LOGIN, person.getLogin());
            accountManager.setUserData(synergyAccount, SynergyAccount.HOST, person.getHost());
            accountManager.setUserData(synergyAccount, SynergyAccount.SHORT_HOST, person.getShortHost());
            accountManager.setUserData(synergyAccount, SynergyAccount.SERVER_NAME, "");
            accountManager.setUserData(synergyAccount, SynergyAccount.FIRSTNAME, "");
            accountManager.setUserData(synergyAccount, SynergyAccount.LASTNAME, "");
            accountManager.setPassword(synergyAccount, "");
        }

        setAccountAuthenticatorResult(result);
        setResult(RESULT_OK);

        // открываем нужный экран
        Intent intent = new Intent(activity, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
        finish();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_CANCELED) {
            return;
        }
        if (requestCode == QR_CODE_ACTIVITY) {
            login.setText(data.getStringExtra(SynergyAccount.LOGIN));
            host.setText(data.getStringExtra(SynergyAccount.HOST));
            nextButtonPressed();
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

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