package br.com.codetec.saudesabor.ui.login;

import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Base64;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import br.com.codetec.saudesabor.R;
import br.com.codetec.saudesabor.model.Bairro;
import br.com.codetec.saudesabor.model.Cidade;
import br.com.codetec.saudesabor.model.Endereco;
import br.com.codetec.saudesabor.model.Estado;
import br.com.codetec.saudesabor.model.Idioma;
import br.com.codetec.saudesabor.model.ResponseBairros;
import br.com.codetec.saudesabor.model.ResponseCEP;
import br.com.codetec.saudesabor.model.ResponseCadastro;
import br.com.codetec.saudesabor.model.ResponseCidades;
import br.com.codetec.saudesabor.model.ResponseEstados;
import br.com.codetec.saudesabor.service.SaudeSaborService;
import br.com.codetec.saudesabor.service.ServiceConector;
import br.com.codetec.saudesabor.utils.UtilsActivity;
import br.com.codetec.saudesabor.utils.components.alert.CustomAlert;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class CadastrarUsuarioActivity extends AppCompatActivity {

    private static final int CODIGO_GALERIA = 100;
    private static final int CODIGO_CAMERA = 200;

    private String caminhoFoto;
    private Bitmap bitmap;

    private Button btn;
    private ImageView img;

    private SaudeSaborService saudeSaborService = ServiceConector.getService(CadastrarUsuarioActivity.this);
    private List<Estado> listaEstados = new ArrayList<>();
    private List<Cidade> listaCidades = new ArrayList<>();
    private List<Bairro> listaBairros = new ArrayList<>();
    private List<Idioma> listaIdiomas = new ArrayList<>();

    private Endereco enderecoDoCEP;
    private AutoCompleteTextView bairroAutoComplete;
    private Button btnRemoverImagem;

    public static Boolean EDIT_MODE = false;
    public static Integer INDEX_ESTADO = null;
    public static Integer INDEX_CIDADE = null;

    private Spinner state;
    private Spinner city;
    private Spinner spinnerIdioma;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cadastrar_usuario);

        final EditText firstName = findViewById(R.id.firstName);
        final EditText lastName = findViewById(R.id.lastName);
        final EditText email = findViewById(R.id.email);
        final EditText telephone = findViewById(R.id.telephone);
        final EditText password = findViewById(R.id.password);
        final EditText zipcode = findViewById(R.id.zipcode);
        final EditText address1 = findViewById(R.id.address1);
        final EditText address2 = findViewById(R.id.address2);
        state = findViewById(R.id.spinnerZone);
        city = findViewById(R.id.city);
        spinnerIdioma = findViewById(R.id.spinnerIdioma);
//        final Spinner zone = findViewById(R.id.zone);
        final TextView termosDeUso  = findViewById(R.id.txtViewTermosDeUso);
        final CheckBox checkTermosDeUso  = findViewById(R.id.checkTermosDeUso);

        final Button btnCadastrarUsuario = findViewById(R.id.btnCadastrarUsuario);
        final Button pesquisarCEPButton= findViewById(R.id.pesquisarCEP);

        listaIdiomas.add(new Idioma("pt", "Português"));
        listaIdiomas.add(new Idioma("ja", "Japonês"));

        ArrayAdapter adapterIdioma = new ArrayAdapter<Idioma>(this,
                R.layout.layout_spinner, listaIdiomas);
        spinnerIdioma.setAdapter(adapterIdioma);

        btnRemoverImagem = findViewById(R.id.btnRemoverFoto);

        btn= findViewById(R.id.btnEscolherFoto);
        img = findViewById(R.id.imagemFoto);

        btnRemoverImagem.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                img.setImageBitmap(null);
                img.setVisibility(View.GONE);
                btnRemoverImagem.setVisibility(View.GONE);
            }
        });

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ActivityCompat.checkSelfPermission(CadastrarUsuarioActivity.this,
                        Manifest.permission.READ_EXTERNAL_STORAGE)
                        != PackageManager.PERMISSION_GRANTED) {

                    ActivityCompat.requestPermissions(CadastrarUsuarioActivity.this,
                            new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);

                }else{
                    registerForContextMenu(btn);
                    openContextMenu(btn);
                }
            }
        });

        bairroAutoComplete = findViewById(R.id.bairroAutoComplete);
        termosDeUso.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(ServiceConector.TERMOS_DE_USO_URL));
                startActivity(browserIntent);
            }
        });

        carregarEstados();

        pesquisarCEPButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pesquisarPorCep(zipcode, address2);
            }
        });

        zipcode.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if(hasFocus == false){
                    pesquisarPorCep(zipcode, address2);
                }
            }
        });

        state.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                try {
                    listaBairros = new ArrayList<>();
                    listaCidades = new ArrayList<>();

                    refreshComboBairros();
                    refreshComboCidades();

                    Estado estado = listaEstados.get(position);
                    carregarCidades(estado);
                }catch(Exception e){
                    e.printStackTrace();
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });

        city.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                listaBairros = new ArrayList<>();
//                refreshComboBairros(zone);

                Cidade cidade = listaCidades.get(position);
                carregarBairros(cidade);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });

        btnCadastrarUsuario.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.O)
            @Override
            public void onClick(View v) {
                cadastrarUsuarioClick(checkTermosDeUso, firstName, lastName, email, telephone, password, address1, address2, zipcode);
            }
        });


        //PREENCHER FORMULARIO
        if(EDIT_MODE){
//            final EditText firstName = findViewById(R.id.firstName);
//            final EditText lastName = findViewById(R.id.lastName);
//            final EditText email = findViewById(R.id.email);
//            final EditText telephone = findViewById(R.id.telephone);
//            final EditText password = findViewById(R.id.password);
//            final EditText zipcode = findViewById(R.id.zipcode);
//            final EditText address1 = findViewById(R.id.address1);
//            final EditText address2 = findViewById(R.id.address2);
//            final Spinner state = findViewById(R.id.spinnerZone);
//            final Spinner city = findViewById(R.id.city);
////        final Spinner zone = findViewById(R.id.zone);
//            final TextView termosDeUso  = findViewById(R.id.txtViewTermosDeUso);
//            final CheckBox checkTermosDeUso  = findViewById(R.id.checkTermosDeUso);


            firstName.setText(LoginActivity.responseLogin.getUsuario().getFirstname());
            lastName.setText(LoginActivity.responseLogin.getUsuario().getLastname());
            email.setText(LoginActivity.responseLogin.getUsuario().getEmail());
            telephone.setText(LoginActivity.responseLogin.getUsuario().getTelephone());
            password.setText("");
            zipcode.setText(LoginActivity.responseLogin.getUsuario().getPostcode());
            address1.setText(LoginActivity.responseLogin.getUsuario().getAddress_1());
            address2.setText(LoginActivity.responseLogin.getUsuario().getAddress_2());

            if(LoginActivity.responseLogin.getUsuario().getPhoto()!=null) {
                try {
                    byte[] decodedString = Base64.decode(LoginActivity.responseLogin.getUsuario().getPhoto(), Base64.DEFAULT);
                    Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
                    img.setImageBitmap(decodedByte);
                    img.setVisibility(View.VISIBLE);
                    btnRemoverImagem.setVisibility(View.VISIBLE);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void onBackPressed() {
        CustomAlert.getInstance().show(
            this, getString(R.string.app_name),
            getString(R.string.promtp_deseja_realmente_sair),
                getString(R.string.nao),
                getString(R.string.sim),
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    CadastrarUsuarioActivity.this.finish();
                }
            });
    }

    private void pesquisarPorCep(EditText zipcode, EditText address2) {

        UtilsActivity.getInstance().esconderTeclado(getApplicationContext(), zipcode);

        Call<ResponseCEP> call = saudeSaborService.consultarCep(getString(R.string.locale), zipcode.getText().toString());
        call.enqueue(new Callback<ResponseCEP>() {
            @Override
            public void onResponse(Call<ResponseCEP> call, Response<ResponseCEP> response) {
                if(response.isSuccessful() && response.body() != null && response.body().getEndereco()!=null){
//                    address2.setText(response.body().getEndereco().getBairro());
                    enderecoDoCEP = response.body().getEndereco();

                    if(enderecoDoCEP!=null) {
                        int positionEstado = 0;
                        for (Estado est : listaEstados) {
                            if (est.getEstado().equalsIgnoreCase(enderecoDoCEP.getEstado())) {
                                break;
                            }
                            positionEstado++;
                        }
                        state.setSelection(positionEstado);
                        carregarCidades(listaEstados.get(positionEstado));
                    }else{
                        CustomAlert.getInstance().show(CadastrarUsuarioActivity.this, getString(R.string.cep_nao_encontrado));
                    }
                }else if(response.body()!=null && response.body().getErro()!=null && response.body().getErro().equals("true")){
                    CustomAlert.getInstance().show(CadastrarUsuarioActivity.this, response.body().getMensagem());
//                    zipcode.setText("");
                }
            }

            @Override
            public void onFailure(Call<ResponseCEP> call, Throwable t) {
                CustomAlert.getInstance().show(CadastrarUsuarioActivity.this, getString(R.string.erro_conectividade));
            }
        });
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void cadastrarUsuarioClick(CheckBox checkTermosDeUso, EditText firstName, EditText lastName, EditText email, EditText telephone, EditText password, EditText address1, EditText address2, EditText zipcode) {
        if(!checkTermosDeUso.isChecked()){
            CustomAlert.getInstance().show(CadastrarUsuarioActivity.this, getString(R.string.voce_precisa_aceitar_termos));
            return;
        }

        String fotoBase64 = "";
        try {
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 50, stream);
            byte[] byteArray = stream.toByteArray();
            bitmap.recycle();
            fotoBase64 = java.util.Base64.getEncoder().encodeToString(byteArray);//Base64.encodeToString(byteArray, Base64.DEFAULT);
        }catch (Exception e){

        }
        String cidade = "";

        try {
            cidade = ((Cidade)city.getSelectedItem()).getCidade();
        }catch(Exception e){
            e.printStackTrace();
        }

        String customerID = "0";
        if(EDIT_MODE){
            customerID = LoginActivity.responseLogin.getUsuario().getId();
        }

        String zoneId = ((Estado) state.getSelectedItem()).getZone_id();
                Call<ResponseCadastro> call = saudeSaborService.cadastrarUsuario(
                        ((Idioma)spinnerIdioma.getSelectedItem()).getLocale(),
                        firstName.getText().toString(),
                        lastName.getText().toString(),
                        email.getText().toString(),
                        telephone.getText().toString(),
                        password.getText().toString(),
                        "",
                        address1.getText().toString(),
                        bairroAutoComplete.getText().toString(),
                        cidade,
                        zipcode.getText().toString(),
                        zoneId, fotoBase64, customerID
                );
                call.enqueue(new Callback<ResponseCadastro>() {
                    @Override
                    public void onResponse(Call<ResponseCadastro> call, Response<ResponseCadastro> response) {
                        if(response.body()!=null){
                            CustomAlert.getInstance().show(CadastrarUsuarioActivity.this, response.body().getMensagem(), new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    CadastrarUsuarioActivity.this.finish();
                                }
                            });
                        }
            }

            @Override
            public void onFailure(Call<ResponseCadastro> call, Throwable t) {
                CustomAlert.getInstance().show(CadastrarUsuarioActivity.this, getString(R.string.falha_comunicacao));
            }
        });
    }

    private void carregarCidades(Estado estado) {
        Call<ResponseCidades> callCidades = saudeSaborService.consultarCidades(getString(R.string.locale), estado.getEstado());
        callCidades.enqueue(new Callback<ResponseCidades>() {
            @Override
            public void onResponse(Call<ResponseCidades> call, Response<ResponseCidades> response) {
                if(response.isSuccessful() && response.body()!=null){
                    listaCidades = response.body().getCidades();
                    if(listaCidades==null) return;
                    refreshComboCidades();

                    if(enderecoDoCEP!=null) {
                        int positionCidade = 0;
                        for (Cidade cid : listaCidades) {
                            if (cid.getCidade().equalsIgnoreCase(enderecoDoCEP.getCidade())) {
                                break;
                            }
                            positionCidade++;
                        }
                        city.setSelection(positionCidade);
                        carregarBairros(listaCidades.get(positionCidade) );
                    }

                    if(EDIT_MODE) {
                        int i = 0;
                        for (Cidade cidade : listaCidades) {
                            if(cidade.getCidade().equalsIgnoreCase(LoginActivity.responseLogin.getUsuario().getCity())){
                                INDEX_CIDADE = i;
                                break;
                            }
                            i++;
                        }
                    }
                }
            }
            @Override
            public void onFailure(Call<ResponseCidades> call, Throwable t) {
                t.printStackTrace();
            }
        });
    }

    private void refreshComboCidades() {
        listaCidades.add( 0, new Cidade(getString(R.string.select_selecione_uma_cidade)));
        city.setAdapter(new ArrayAdapter<Cidade>(CadastrarUsuarioActivity.this, R.layout.layout_spinner, listaCidades));

        if(EDIT_MODE) {
            if(INDEX_CIDADE!=null) {
                if(INDEX_CIDADE>0) {
                    city.setSelection(INDEX_CIDADE);
                    carregarBairros(listaCidades.get(INDEX_CIDADE));
                }
            }
        }
    }

    private void refreshComboBairros() {
//        zone.setAdapter(new ArrayAdapter<Bairro>(CadastrarUsuarioActivity.this, android.R.layout.simple_list_item_1, listaBairros));
        ArrayAdapter myAdapter = new ArrayAdapter<Bairro>(this,
                R.layout.layout_spinner, listaBairros);
        bairroAutoComplete.setAdapter(myAdapter );
    }

    private void refreshComboEstados() {
        listaEstados.add( 0, new Estado(null,getString(R.string.select_selecione_um_estado), null));
        state.setAdapter(new ArrayAdapter<Estado>(CadastrarUsuarioActivity.this, R.layout.layout_spinner, listaEstados));
        if(EDIT_MODE) {
            if(INDEX_ESTADO>0) {
                state.setSelection(INDEX_ESTADO);
                carregarCidades(listaEstados.get(INDEX_ESTADO));
            }
        }
    }

    private void carregarBairros(Cidade cidade) {
        Call<ResponseBairros> callBairros = saudeSaborService.consultarBairros(getString(R.string.locale), cidade.getCidade());
        callBairros.enqueue(new Callback<ResponseBairros>() {
            @Override
            public void onResponse(Call<ResponseBairros> call, Response<ResponseBairros> response) {
                if(response.isSuccessful() && response.body()!=null){
                    listaBairros = response.body().getBairros();
                    if(listaBairros==null) return;
                    refreshComboBairros();

                    if(enderecoDoCEP!=null) {
                        int positionBairro = 0;
                        for (Bairro cid : listaBairros) {
                            if (cid.getBairro().equalsIgnoreCase(enderecoDoCEP.getBairro())) {
                                bairroAutoComplete.setText(cid.getBairro());
                                break;
                            }
                            positionBairro++;
                        }
                    }
                }
            }
            @Override
            public void onFailure(Call<ResponseBairros> call, Throwable t) {
                t.printStackTrace();
            }
        });
    }

    private void carregarEstados() {
        //Carregar Estados
        Call<ResponseEstados> callEstados = saudeSaborService.consultarEstados(getString(R.string.locale));
        callEstados.enqueue(new Callback<ResponseEstados>() {
            @Override
            public void onResponse(Call<ResponseEstados> call, Response<ResponseEstados> response) {
                if (response.isSuccessful() && response.body() != null) {
                    listaEstados = response.body().getEstados();
                    if(listaEstados == null) return;

                    if(EDIT_MODE) {
                        int i = 0;
                        for (Estado estado : listaEstados) {
                            if(estado.getEstado().equalsIgnoreCase(LoginActivity.responseLogin.getUsuario().getEstado())){
                                INDEX_ESTADO = i;
                                break;
                            }
                            i++;
                        }
                    }
                    refreshComboEstados();
                }
            }

            @Override
            public void onFailure(Call<ResponseEstados> call, Throwable t) {
                CustomAlert.getInstance().show(CadastrarUsuarioActivity.this, getString(R.string.erro_conectividade));
            }
        });
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);

        MenuItem carregarImg = menu.add(R.string.da_galeria);
        carregarImg.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                selecionarGaleria();
                return false;
            }
        });

        MenuItem camera = menu.add(R.string.da_camera);
        camera.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                selecionarCamera();
                return false;
            }
        });
    }

    public void selecionarGaleria(){
        Intent abrirGaleria = new Intent(Intent.ACTION_GET_CONTENT);
        abrirGaleria.setType("image/*");
        abrirGaleria.addCategory(Intent.CATEGORY_OPENABLE);
        startActivityForResult(abrirGaleria,CODIGO_GALERIA);
    }

    public void selecionarCamera(){
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(takePictureIntent, CODIGO_CAMERA);
        }
    }


    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == CODIGO_GALERIA && resultCode == RESULT_OK) {
            carregarImagemGaleria(data);
        }

        if (requestCode == CODIGO_CAMERA && resultCode == RESULT_OK) {
            Bundle extras = data.getExtras();
            Bitmap imageBitmap = (Bitmap) extras.get("data");
            bitmap = imageBitmap;
            img.setImageBitmap(imageBitmap);
            img.setVisibility(View.VISIBLE);
            btnRemoverImagem.setVisibility(View.VISIBLE);
        }

//        if(requestCode == CODIGO_CAMERA && resultCode == RESULT_OK){
//            carregarImagemCamera();
//        }
    }

    public void carregarImagemGaleria(Intent data){
        InputStream stream = null;

        try {
            if(bitmap != null){
                bitmap.recycle();
            }

            stream = getContentResolver().openInputStream(data.getData());
            bitmap = BitmapFactory.decodeStream(stream);
            img.setImageBitmap(bitmap);
            img.setVisibility(View.VISIBLE);
            btnRemoverImagem.setVisibility(View.VISIBLE);

//            CustomAlert.getInstance().show(CadastrarUsuarioActivity.this, "Imagem da galeria carregada...");
//            exibirMsg("Imagem da GALERIA carregada...");
        } catch(FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (stream != null)
                try {
                    stream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }

    }

}