package info.knacki.pass.ui.passwordPicker;

import android.content.Context;
import android.content.res.Resources;
import android.widget.Toast;

import java.io.File;

import info.knacki.pass.R;
import info.knacki.pass.io.FileInterfaceFactory;
import info.knacki.pass.io.PathUtils;
import info.knacki.pass.ui.alertPrompt.AlertPromptGenerator;
import info.knacki.pass.ui.alertPrompt.views.PasswordTextEdit;

class PasswordPicker implements FileInterfaceFactory.PasswordGetter {
    protected final Context fContext;
    protected final AlertPromptGenerator fAlertFactory;
    protected String fName = null;

    public PasswordPicker(Context context, AlertPromptGenerator alertFactory) {
        fContext = context;
        fAlertFactory = alertFactory;
    }

    public String GetTitle() {
        return fName == null ? fContext.getResources().getString(R.string.enter_password) : String.format(fContext.getResources().getString(R.string.enter_password_for), fName);
    }

    @Override
    public FileInterfaceFactory.PasswordGetter SetFile(File file) {
        if (file == null) {
            fName = null;
        } else {
            int rootLen = PathUtils.GetPassDir(fContext).length();
            fName = file.getAbsolutePath();
            if (fName.length() > rootLen) {
                fName = fName.substring(rootLen);
                if (fName.startsWith("/"))
                    fName = fName.substring(1);
            }
        }
        return this;
    }

    @Override
    public PasswordPicker GetPassword(final FileInterfaceFactory.OnPasswordEnteredListener onPassword) {
        fAlertFactory.Generate(fContext)
            .setCancelable(true)
            .setView(new PasswordTextEdit(fContext))
            .setPositiveButton(R.string.ok, (dialogInterface, view) -> {
                if (!onPassword.OnResponse(((PasswordTextEdit) view).getStr()))
                    WrongPassword();
            })
            .setNegativeButton(R.string.cancel, (dialogInterface, s) -> {
                if (!onPassword.OnResponse(null))
                    WrongPassword();
            })
            .setTitle(GetTitle())
            .show();
        return this;
    }

    public void WrongPassword() {
        Toast.makeText(fContext, fContext.getResources().getString(R.string.wrongPassword), Toast.LENGTH_LONG).show();
    }

    public static class ChangePasswordPicker extends PasswordPicker implements FileInterfaceFactory.ChangePasswordGetter {
        protected FileInterfaceFactory.ChangePasswordGetter.eStep fCurrentStep = FileInterfaceFactory.ChangePasswordGetter.eStep.eOldPassword;
        private String fFirstPassword = "";
        private FileInterfaceFactory.OnPasswordEnteredListener fListener;

        public ChangePasswordPicker(Context context, AlertPromptGenerator alertFactory) {
            super(context, alertFactory);
        }

        @Override
        public String GetTitle() {
            Resources r = fContext.getResources();
            switch (fCurrentStep) {
                case eOldPassword:
                    return r.getString(R.string.enter_old_password);
                case eNewPassword:
                    return r.getString(R.string.type_new_password);
                case eRetypePassword:
                    return r.getString(R.string.retype_new_password);
            }
            return r.getString(R.string.enter_password);
        }

        private final FileInterfaceFactory.OnPasswordEnteredListener fOnFirstPassEntered = new FileInterfaceFactory.OnPasswordEnteredListener() {
            @Override
            public boolean OnResponse(String result) {
                if (result == null) {
                    fListener.OnResponse(null);
                    return false;
                }
                fFirstPassword = result;
                SetStep(eStep.eRetypePassword).GetPassword(fListener);
                return true;
            }

            @Override
            public void OnError(String msg, Throwable e) {
                fListener.OnError(msg, e);
            }
        };

        private final FileInterfaceFactory.OnPasswordEnteredListener fOnRetypePassEntered = new FileInterfaceFactory.OnPasswordEnteredListener() {
            @Override
            public boolean OnResponse(String result) {
                if (result == null) {
                    SetStep(eStep.eNewPassword).GetPassword(fListener);
                    return false;
                } else if (!fFirstPassword.equals(result)) {
                    Toast.makeText(fContext, fContext.getResources().getString(R.string.password_mismatch), Toast.LENGTH_LONG).show();
                    SetStep(eStep.eNewPassword).GetPassword(fListener);
                    return false;
                }
                fListener.OnResponse(result);
                return true;
            }

            @Override
            public void OnError(String msg, Throwable e) {
                fListener.OnError(msg, e);
            }
        };

        @Override
        public PasswordPicker GetPassword(final FileInterfaceFactory.OnPasswordEnteredListener onPassword) {
            fListener = onPassword;
            switch (fCurrentStep) {
                case eOldPassword:
                    super.GetPassword(onPassword);
                    break;
                case eNewPassword:
                    super.GetPassword(fOnFirstPassEntered);
                    break;
                case eRetypePassword:
                    super.GetPassword(fOnRetypePassEntered);
                    break;
            }
            return this;
        }

        @Override
        public FileInterfaceFactory.ChangePasswordGetter SetStep(FileInterfaceFactory.ChangePasswordGetter.eStep step) {
            fCurrentStep = step;
            return this;
        }

        @Override
        public void WrongPassword() {
        }
    }
}
