package com.eugenefn.openapi.sample.view.dialog;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.text.InputFilter;
import android.text.Spanned;
import android.util.Pair;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.eugenefn.openapi.proc.SmartChampAPI;
import com.eugenefn.openapi.sample.view.control.CertSelectSpinner;
import com.eugenefn.openapi.sample.view.control.ItemSelectSpinner;
import com.eugenefn.openapi.sample.view.util.LayoutUtil;
import com.eugenefn.openapi.sample.view.util.SampleUtil;

import java.util.ArrayList;

public class LoginDialog extends Dialog
        implements View.OnClickListener, CompoundButton.OnCheckedChangeListener
{
    private static final String LOG_TAG = "LoginDialog";

    public interface ID
    {
        int     CTRL_ID_LOGIN = 100;
        int     CTRL_ID_CANCEL = 101;
        int		CTRL_ID_CERTSEL = 102;
        int		CTRL_ID_CERTCHECK = 103;

        int		CTRL_ID_IMPORT_CERT = 201;
        int		CTRL_ID_EXPORT_CERT = 202;
        int		CTRL_ID_DELETE_CERT = 203;
    }

    private String      m_strUserId = "";
    private String      m_strUserPwd = "";
    private String		m_strCertDN = "";
    private String      m_strCertPwd = "";
    private boolean		m_isCertLogin = false;
    private String      m_strCorpCode = "";

    private EditText m_editUserId;
    private EditText m_editUserPwd;
    private CertSelectSpinner m_spinnerCert;
    private EditText m_editCertPwd;
    private CheckBox m_checkCertLogin;

    private ItemSelectSpinner m_spinnerCorp;

    private Activity m_activity;

    public LoginDialog(@NonNull Context context, Activity activity) {
        super(context);

        m_activity = activity;
    }

    //초기화
    public void initView()
    {
        int nTitleWidth = (int) SampleUtil.dipToPixels(getContext(), 100);	// 입력항목 제목 너비
        int nInputWidth = (int)SampleUtil.dipToPixels(getContext(), 200);	// 입력항목 에디트 너비
        int nInputPaddingH = (int)SampleUtil.dipToPixels(getContext(), 20);	// 입력항목 가로 패딩
        int nInputPaddingV = (int)SampleUtil.dipToPixels(getContext(), 5);	// 입력항목 세로 패딩
        int nInputHeight = (int)SampleUtil.dipToPixels(getContext(), 46);	// 입력항목 높이
        int nButtonWidth = (int)SampleUtil.dipToPixels(getContext(), 100);	// 버튼 너비
        int nButtonHeight = (int)SampleUtil.dipToPixels(getContext(), 50);	// 버튼 높이
        int nLineHeight = (int)SampleUtil.dipToPixels(getContext(), 3);	// 구분선 높이
        int nButtonWidth2 = (int)SampleUtil.dipToPixels(getContext(), 160);	// 버튼 너비

        LinearLayout layoutFrame = new LinearLayout(getContext());
        layoutFrame.setOrientation(LinearLayout.VERTICAL);

        LinearLayout layoutTitle = new LinearLayout(getContext());
        layoutTitle.setOrientation(LinearLayout.HORIZONTAL);
        layoutTitle.setPadding(nInputPaddingH, 0, nInputPaddingH, 0);

        TextView viewTitle = LayoutUtil.makeTextView(getContext(), "로그인 입력");

        ArrayList<Pair<String,String>> arrCorp = new ArrayList<>();
        arrCorp.add(new Pair<>("010", "개인고객"));
        arrCorp.add(new Pair<>("020", "제휴사A"));

        m_spinnerCorp = new ItemSelectSpinner(getContext(), "제휴사 선택");
        m_spinnerCorp.setItemList(arrCorp);
        m_spinnerCorp.selectItemByKey(SampleUtil.getConfig(m_activity, "corp_code", ""));
        m_spinnerCorp.setOnItemSelectedListener(new ItemSelectSpinner.OnItemSelectedListener() {
            @Override
            public void onItemSelected(String strKey, String srValue) {
                SampleUtil.setConfig(m_activity, "corp_code", strKey);

                m_strCorpCode = strKey;
            }
        });

        layoutTitle.addView(viewTitle, new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1));
        layoutTitle.addView(m_spinnerCorp, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT));

        layoutFrame.addView(layoutTitle, new LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, nInputHeight));

        String strPrevLoginId = SampleUtil.getConfig(m_activity, "login.userid", "");
        //아이디
        TextView viewIDTitle = LayoutUtil.makeTextView(getContext(), "아이디");
        m_editUserId = LayoutUtil.makeEditView(getContext(), strPrevLoginId);
        m_editUserId.setFilters(new InputFilter[]{ new UserIdInputFilter(), new InputFilter.AllCaps() });

        LinearLayout layoutID = new LinearLayout(getContext());
        layoutID.setOrientation(LinearLayout.HORIZONTAL);

        layoutID.addView(viewIDTitle, new LinearLayout.LayoutParams(nTitleWidth, nInputHeight));
        layoutID.addView(m_editUserId, new LinearLayout.LayoutParams(nInputWidth, nInputHeight));
        layoutID.setPadding(nInputPaddingH, nInputPaddingV, nInputPaddingH, 0);
        layoutFrame.addView(layoutID, new LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));

        LayoutUtil.setEditText(m_editUserId, true, false);
        //비밀번호
        TextView viewPWTitle = LayoutUtil.makeTextView(getContext(), "비밀번호");
        m_editUserPwd = LayoutUtil.makeEditView(getContext(), "");
        LayoutUtil.setEditText(m_editUserPwd, false, false);
        m_editUserPwd.setFilters(new InputFilter[] { new InputFilter.LengthFilter(8)});

        LinearLayout layoutPW = new LinearLayout(getContext());
        layoutPW.setOrientation(LinearLayout.HORIZONTAL);

        layoutPW.addView(viewPWTitle, new LinearLayout.LayoutParams(nTitleWidth, nInputHeight));
        layoutPW.addView(m_editUserPwd, new LinearLayout.LayoutParams(nInputWidth, nInputHeight));
        layoutPW.setPadding(nInputPaddingH, nInputPaddingV, nInputPaddingH, 0);
        layoutFrame.addView(layoutPW, new LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));

        LayoutUtil.setEditText(m_editUserPwd, false, false);

        // 인증서
        TextView viewCertTitle = LayoutUtil.makeTextView(getContext(), "공동인증서");
        m_spinnerCert = new CertSelectSpinner(getContext());
        m_spinnerCert.setCertList(SmartChampAPI.getInstance().getUserCertList());
        m_spinnerCert.setCertDN(SampleUtil.getConfig(m_activity, "cert_dn", ""));

        m_spinnerCert.setOnCertSelectedListener(new CertSelectSpinner.OnCertSelectedListener()
        {
            @Override
            public void onCertSelected(String strDN)
            {
                m_strCertDN = strDN;

                SampleUtil.setConfig(m_activity, "cert_dn", strDN);
            }

        });

        LinearLayout layoutCert = new LinearLayout(getContext());
        layoutCert.setOrientation(LinearLayout.HORIZONTAL);

        layoutCert.addView(viewCertTitle, new LinearLayout.LayoutParams(nTitleWidth, nInputHeight));
        layoutCert.addView(m_spinnerCert, new LinearLayout.LayoutParams(0, nInputHeight, 1));
        layoutCert.setPadding(nInputPaddingH, nInputPaddingV, nInputPaddingH, 0);
        layoutFrame.addView(layoutCert, new LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));

        //공인인증
        TextView viewCertPWTitle = LayoutUtil.makeTextView(getContext(), "인증비번");
        m_editCertPwd = LayoutUtil.makeEditView(getContext(), "");
        LayoutUtil.setEditText(m_editCertPwd, false, false);
        m_editCertPwd.setFilters(new InputFilter[] { new InputFilter.LengthFilter(30)});

        LinearLayout layoutCertPW = new LinearLayout(getContext());
        layoutCertPW.setOrientation(LinearLayout.HORIZONTAL);

        layoutCertPW.addView(viewCertPWTitle, new LinearLayout.LayoutParams(nTitleWidth, nInputHeight));
        layoutCertPW.addView(m_editCertPwd, new LinearLayout.LayoutParams(nInputWidth, nInputHeight));
        layoutCertPW.setPadding(nInputPaddingH, nInputPaddingV, nInputPaddingH, nInputPaddingV);
        layoutFrame.addView(layoutCertPW, new LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));

        LayoutUtil.setEditText(m_editCertPwd, false, false);

        // 공인인증만으로 로그인
        m_checkCertLogin = LayoutUtil.makeCheckBox(getContext(), ID.CTRL_ID_CERTCHECK, "인증서만으로 로그인");
        LinearLayout layoutCertCheck = new LinearLayout(getContext());
        layoutCertCheck.setOrientation(LinearLayout.HORIZONTAL);

        layoutCertCheck.addView(m_checkCertLogin, new LinearLayout.LayoutParams(nInputWidth, nInputHeight));
        layoutCertCheck.setPadding(nInputPaddingH, 0, nInputPaddingH, 0);

        layoutFrame.addView(layoutCertCheck, new LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));
        m_checkCertLogin.setOnCheckedChangeListener(this);

        //버튼
        Button buttonLogin = LayoutUtil.makeCtrlButton(getContext(), ID.CTRL_ID_LOGIN, "로그인");
        Button buttonCancel = LayoutUtil.makeCtrlButton(getContext(), ID.CTRL_ID_CANCEL, "취소");

        LinearLayout layoutbtn = new LinearLayout(getContext());
        layoutbtn.setOrientation(LinearLayout.HORIZONTAL);
        layoutbtn.setPadding(0, nInputPaddingV, 0, nInputPaddingV);
        layoutbtn.addView(buttonLogin, new LinearLayout.LayoutParams(nButtonWidth, nButtonHeight));
        layoutbtn.addView(buttonCancel, new LinearLayout.LayoutParams(nButtonWidth, nButtonHeight));

        LinearLayout.LayoutParams paramButtons = new LinearLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
        paramButtons.gravity = Gravity.CENTER_HORIZONTAL;
        layoutFrame.addView(layoutbtn, paramButtons);

        // 구분선
        View viewLine = new View(getContext());
        viewLine.setBackgroundColor(Color.GRAY);
        LinearLayout.LayoutParams paramLine = new LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, nLineHeight);
        paramLine.setMargins(nInputPaddingH, nInputPaddingV, nInputPaddingH, nInputPaddingV);
        layoutFrame.addView(viewLine, paramLine);

        // 인증센터
        Button buttonImportCert = LayoutUtil.makeCtrlButton(getContext(), ID.CTRL_ID_IMPORT_CERT, "인증서 가져오기");
        TextView viewImportInfo = LayoutUtil.makeTextView(getContext(), "PC홈페이지나 다른 모바일앱에서 인증서 내보내기를 통해 샘플앱으로 가져옴", false);
        LinearLayout layoutImport = new LinearLayout(getContext());
        layoutImport.setOrientation(LinearLayout.HORIZONTAL);
        layoutImport.setGravity(Gravity.CENTER_VERTICAL);
        layoutImport.addView(buttonImportCert, new LinearLayout.LayoutParams(nButtonWidth2, nButtonHeight));
        layoutImport.addView(viewImportInfo, new LinearLayout.LayoutParams(0, FrameLayout.LayoutParams.WRAP_CONTENT, 1));
        layoutImport.setPadding(nInputPaddingH, nInputPaddingV, nInputPaddingH, nInputPaddingV);

        layoutFrame.addView(layoutImport, new LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));

        Button buttonExportCert = LayoutUtil.makeCtrlButton(getContext(), ID.CTRL_ID_EXPORT_CERT, "인증서 내보내기");
        TextView viewExportInfo = LayoutUtil.makeTextView(getContext(), "샘플앱의 인증서를 PC홈페이지나 다른 모바일앱으로 가져가기", false);
        LinearLayout layoutExport = new LinearLayout(getContext());
        layoutExport.setOrientation(LinearLayout.HORIZONTAL);
        layoutExport.setGravity(Gravity.CENTER_VERTICAL);
        layoutExport.addView(buttonExportCert, new LinearLayout.LayoutParams(nButtonWidth2, nButtonHeight));
        layoutExport.addView(viewExportInfo, new LinearLayout.LayoutParams(0, FrameLayout.LayoutParams.WRAP_CONTENT, 1));
        layoutExport.setPadding(nInputPaddingH, nInputPaddingV, nInputPaddingH, nInputPaddingV);

        layoutFrame.addView(layoutExport, new LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));

        Button buttonDeleteCert = LayoutUtil.makeCtrlButton(getContext(), ID.CTRL_ID_DELETE_CERT, "인증서 삭제");
        TextView viewDeleteInfo = LayoutUtil.makeTextView(getContext(), "샘플앱에 저장된 인증서를 삭제", false);
        LinearLayout layouDelete = new LinearLayout(getContext());
        layouDelete.setOrientation(LinearLayout.HORIZONTAL);
        layouDelete.setGravity(Gravity.CENTER_VERTICAL);
        layouDelete.addView(buttonDeleteCert, new LinearLayout.LayoutParams(nButtonWidth2, nButtonHeight));
        layouDelete.addView(viewDeleteInfo, new LinearLayout.LayoutParams(0, FrameLayout.LayoutParams.WRAP_CONTENT, 1));
        layouDelete.setPadding(nInputPaddingH, nInputPaddingV, nInputPaddingH, nInputPaddingV);

        layoutFrame.addView(layouDelete, new LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));

        setContentView(layoutFrame, new ViewGroup.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));

        buttonLogin.setOnClickListener(this);
        buttonCancel.setOnClickListener(this);

        buttonImportCert.setOnClickListener(this);
        buttonExportCert.setOnClickListener(this);
        buttonDeleteCert.setOnClickListener(this);

        setInputState();
        setCanceledOnTouchOutside(false);

        getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    }

    @Override
    public void show()
    {
        initView();

        super.show();
    }

    private void setInputState()
    {
        m_editUserId.setEnabled(!m_isCertLogin);
        m_editUserPwd.setEnabled(!m_isCertLogin);
        m_spinnerCert.setEnabled(m_isCertLogin);
        m_editCertPwd.setEnabled(true);

        m_editUserId.setTextColor(m_isCertLogin ? Color.LTGRAY : Color.BLACK);
        m_editUserPwd.setTextColor(m_isCertLogin ? Color.LTGRAY : Color.BLACK);
    }

    /**
     * Activity에서 유저 아이디란에 세팅을 위한 함수
     * @param strUserId
     */
    public void setUserId(String strUserId)
    {
        m_editUserId.setText(strUserId);
        m_strUserId = strUserId;
    }
    /**
     * 입력된 아이디를 리턴
     * @return
     */
    public String getUserId()
    {
        m_strUserId = m_editUserId.getText().toString().toUpperCase();
        m_editUserId.setText(m_strUserId);
        return m_strUserId ;
    }

    /**
     * Activity에서 View의 유저 비밀번호란에 세팅을 위한 함수
     * @param strUserPwd
     */
    public void setUserPwd(String strUserPwd)
    {
        m_strUserPwd = strUserPwd;
        m_editUserPwd.setText(strUserPwd);
    }

    /**
     *입력된 비밀번호를 리턴
     * @return
     */
    public String getUserPwd()
    {
        m_strUserPwd = m_editUserPwd.getText().toString();
        return m_strUserPwd;
    }

    public void setCertDN(String strCertDN)
    {
        m_strCertDN = strCertDN;
    }

    public String getCertDN()
    {
        return m_strCertDN;
    }

    /**
     * 입력된 공인인증 비밀번호를 리턴
     * @return
     */
    public String getCertPwd()
    {
        m_strCertPwd = m_editCertPwd.getText().toString();
        return m_strCertPwd;
    }

    public String getCorpCode()
    {
        return m_strCorpCode;
    }

    private void importCert()
    {
        final CertImportDialog dlgImport = new CertImportDialog(getContext());
        dlgImport.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                if(dlgImport.m_isSuccess)
                {
                    m_spinnerCert.setCertList(SmartChampAPI.getInstance().getUserCertList());
                    m_spinnerCert.setCertDN(SampleUtil.getConfig(m_activity, "cert_dn", ""));
                }
            }
        });
        dlgImport.show();
    }

    private void exportCert()
    {
        CertExportDialog dlgExport = new CertExportDialog(getContext());
        dlgExport.show(m_activity);
    }

    private void deleteCert()
    {
        final CertDeleteDialog dlgDelete = new CertDeleteDialog(getContext());
        dlgDelete.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                m_spinnerCert.setCertList(SmartChampAPI.getInstance().getUserCertList());
                m_strCertDN = m_spinnerCert.getCertDN();

                SampleUtil.setConfig(m_activity,"cert_dn", m_strCertDN);
            }
        });
        dlgDelete.show(m_activity);
    }

    @Override
    public void onClick(View v)
    {
        int nCtrlId = v.getId();
        /**
         * 사용자가 로그인을 요청 할 때 로그인에 필요한 정보를 확인 하고
         * 필요한 정보가 전부 입력되지 않았을 경우 해당 정보를 요청하는 메시지를 보여주거나
         * 필요한 정보가 모두 갖춰졌을 때 해당정보를 기반으로 로그인을 요청한다.
         */
        switch(nCtrlId)
        {
            case ID.CTRL_ID_LOGIN :
                if( !m_isCertLogin && getUserId().isEmpty() )
                {
                    Toast.makeText( getContext(), "아이디를 확인하세요.", Toast.LENGTH_SHORT ).show();
                    return;
                }
                else if(!m_isCertLogin && getUserPwd().isEmpty())
                {
                    Toast.makeText( getContext(), "비밀번호를 확인하세요.", Toast.LENGTH_SHORT ).show();
                    return;
                }
                else if(m_isCertLogin && m_spinnerCert.getSelectedItem() == null)
                {
                    Toast.makeText( getContext(), "공인인증서를 선택하세요.", Toast.LENGTH_SHORT ).show();
                    return;
                }
                else if(m_isCertLogin && getCertPwd().isEmpty() )
                {
                    Toast.makeText( getContext(), "공인인증 비밀번호를 확인하세요.", Toast.LENGTH_SHORT ).show();
                    return;
                }

                //로그인 시작
                if(m_isCertLogin)
                    SmartChampAPI.getInstance().loginUser(getCertDN(), getCertPwd(), getCorpCode());
                else
                    SmartChampAPI.getInstance().loginUser(getUserId(), getUserPwd(), getCertPwd(), getCorpCode());

                break;
            /**
             * 유저가 로그인 취소를 할 경우
             */
            case ID.CTRL_ID_CANCEL :
                dismiss();
                break;

            case ID.CTRL_ID_IMPORT_CERT:
                importCert();
                break;

            case ID.CTRL_ID_EXPORT_CERT:
                exportCert();
                break;

            case ID.CTRL_ID_DELETE_CERT:
                deleteCert();
                break;
        }
    }

    @Override
    public void onCheckedChanged(CompoundButton button, boolean isChecked)
    {
        if(button.getId() == ID.CTRL_ID_CERTCHECK)
        {
            m_isCertLogin = isChecked;

            setInputState();
        }
    }

    // 사용자 아이디 알파벳/숫자만 입력
    private class UserIdInputFilter implements InputFilter
    {
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)
        {
            StringBuilder builder = new StringBuilder();
            for(int i = start; i < end; i++)
            {
                char ch = source.charAt(i);
                if(ch >= '0' && ch <= '9') builder.append(ch);
                else if(ch >= 'a' && ch <= 'z') builder.append(ch);
                else if(ch >= 'A' && ch <= 'Z') builder.append(ch);
            }

            return (builder.length() == (end - start)) ? null : builder.toString();
        }
    }
}
