package com.yono.messeripos;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.CursorLoader;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ArrayAdapter;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import com.google.zxing.common.StringUtils;
import com.jaredrummler.materialspinner.MaterialSpinner;
import com.yono.messeripos.api.client.Client;
import com.yono.messeripos.api.service.CategoryServise;
import com.yono.messeripos.api.service.ProductService;
import com.yono.messeripos.databinding.FormProductBinding;
import com.yono.messeripos.models.CategoryModels;
import com.yono.messeripos.models.MainViewModels;
import com.yono.messeripos.models.ProductModels;
import com.yono.messeripos.response.DataResponse;
import com.yono.messeripos.utils.Utils;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class FormProductActivity extends AppCompatActivity {

    FormProductBinding binding;
    ProductModels productModels, productModelsSave;
    File file;
    MainViewModels mainViewModels;
    MaterialSpinner spinner;
    List<String> categoryModels;
    List<String> str = new ArrayList<>();
    private static final int REQUEST_IMAGE_CAPTURE = 1;
    private static final int REQUEST_PERMISSIONS = 448;
    private boolean isUpdate = false;
    String locationPath = null;
    int idCategorySelected = 0;
    public int id = 0;
    public String categoryName = null;

    private String[] permissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE};
    private Utils utils = new Utils();
    ProgressDialog progressDialog;
    Client client = new Client();
    ProductModels productModelsIntent;
    List<Integer> categorySelect = new ArrayList<>();
    FormCategory formCategory;
    SharedPreferences sharedPreferences;

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.form_product);

        binding.btnAdd.setText("Add New Product");
        productModels = new ProductModels();
        productModelsSave = new ProductModels();
        mainViewModels = ViewModelProviders.of(this).get(MainViewModels.class);
        progressDialog = new ProgressDialog(FormProductActivity.this);
        progressDialog.setMessage("Loading...");
        progressDialog.show();
        sharedPreferences = getSharedPreferences(MainActivity.MY_SHARED_PREFERENCES, Context.MODE_PRIVATE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window w = getWindow();
            w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
        }

        productModelsIntent = getIntent().getParcelableExtra(MainActivity.DATA_PRODUCT);
        formCategory = new FormCategory();


        MaterialToolbar toolbars = findViewById(R.id.topAppBarForm);
        setSupportActionBar(toolbars);

        if (getSupportActionBar() != null){
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setDisplayShowHomeEnabled(true);
            getSupportActionBar().setTitle("Add Product");
            toolbars.setNavigationOnClickListener(view -> onBackPressed());
        }

        if (productModelsIntent != null){
            isUpdate = true;

            productModelsSave.setProductName(productModelsIntent.getProductName());
            productModelsSave.setPriceProduct(productModelsIntent.getPriceProduct());
            productModelsSave.setStockProduct(productModelsIntent.getStockProduct());
            productModelsSave.setImageProduct(productModelsIntent.getImageProduct());

            binding.setProductForm(productModelsIntent);
            binding.setPhoto(productModelsIntent.getImageProduct());

            binding.btnAdd.setText("UPDATE PRODUCT");
        }else{
            new ProductModels("",0,0, utils.convertImageBase64Resource(getResources(), R.drawable.logo_32));
        }

        binding.cvProduct.setOnClickListener(view -> openFile());
        binding.btnAdd.setOnClickListener(view -> saveProduct());
        binding.btnAddCategory.setOnClickListener(view -> addCategory());

        //spinner

        setSpinner("");
        setSelectedSpinner();
        setAddListenerCategory();
    }

    private void setAddListenerCategory() {
        formCategory.setListener(new FormCategory.FormCategoryListener() {
            @Override
            public void onAddCategory(CategoryModels categoryModels) {
                progressDialog.show();
                CategoryServise categoryServise = client.Client(CategoryServise.class);
                categoryServise.addCategory(categoryModels).enqueue(new Callback<DataResponse<CategoryModels>>() {
                    @RequiresApi(api = Build.VERSION_CODES.N)
                    @Override
                    public void onResponse(Call<DataResponse<CategoryModels>> call, Response<DataResponse<CategoryModels>> response) {
                        if (response.body().getStatusData()){
                            progressDialog.dismiss();
                            setSpinner("post");
                            formCategory.dismiss();
                            formCategory.etCategoryName.setText("");
                        }
                    }

                    @Override
                    public void onFailure(Call<DataResponse<CategoryModels>> call, Throwable t) {
                        new AlertDialog.Builder(FormProductActivity.this)
                                .setTitle("Add Category failed!")
                                .setMessage("Add category failed, try again!").show();
                    }
                });
            }

            @Override
            public void onUpdateCategory(CategoryModels categoryModels) {

            }
        });
    }

    private void addCategory() {
        formCategory.show(getSupportFragmentManager(),
                "ModalFormCategory");
    }

    private void setSelectedSpinner() {
        binding.listCategory.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener() {
            @Override
            public void onItemSelected(MaterialSpinner view, int position, long id, Object item) {
                progressDialog.show();
                getCategory(item.toString());
            }
        });
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    private void setSpinner(String s) {
        progressDialog.show();
        HashSet<String> set = new HashSet<>();
        categoryModels = new ArrayList<>();
        Log.i("GET_CATEGORY", "setSpinner: "+utils.convertGson(productModelsIntent));
        if (productModelsIntent == null){
            str.add("SELECT CATEGORY");
        }else{
            Log.i("Category_Product", "setSpinner: "+productModelsIntent.getCategoryProduct());
            getCategoryById(productModelsIntent.getCategoryProduct());
            categorySelect.add(0, productModelsIntent.getCategoryProduct());
        }
//        str.add("SELECT CATEGORY");
        mainViewModels.getCategory().observe(this, listDataResponse -> {
            progressDialog.dismiss();
            for (CategoryModels cd: listDataResponse.getData()){
                categoryModels.add(cd.getNameCategory());
            }

            List<String> collect = categoryModels.stream().map(v -> {

                if (set.add(v) == true) {
                    str.add(v);
                }
                return v;
            }).collect(Collectors.toList());


            Log.i("SPINNER", "setSpinner: "+utils.convertGson(str));
            @SuppressLint("ResourceType")
            ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(FormProductActivity.this,
                    R.id.listCategory, str);
            binding.listCategory.setAdapter(dataAdapter);
        });
    }

    private void saveProduct(){
        productModelsSave = new ProductModels();
        productModelsSave.setProductName(binding.etName.getText().toString());
        productModelsSave.setPriceProduct(Integer.parseInt(binding.etPrice.getText().toString()));
        productModelsSave.setStockProduct(Integer.parseInt(binding.etStock.getText().toString()));
        productModelsSave.setCategoryProduct(categorySelect.get(0));

        if (productModelsIntent == null){
            productModelsSave.setImageProduct(productModels.getImageProduct());
        }else{
            if (productModels.getImageProduct() == null){
                productModelsSave.setImageProduct(productModelsIntent.getImageProduct());
            }else{
                productModelsSave.setImageProduct(productModels.getImageProduct());
            }
        }

        Log.i("SAVEPRODUCT", "saveProduct: "+utils.convertGson(productModelsSave));

        if (isUpdate){
            Log.i("update_path", "saveProduct: "+locationPath);
            if (
                    !productModelsSave.getProductName().isEmpty() ||
                            productModelsSave.getPriceProduct() != 0 ||
                            productModelsSave.getStockProduct() != 0
            ){
                progressDialog.setCancelable(false);
                progressDialog.show();
                ProductService productService = client.Client(ProductService.class);
                Log.i("data_post", "saveProduct: "+utils.convertGson(productModelsIntent.getIdProduct()));
                productModelsSave.setIdProduct(productModelsIntent.getIdProduct());
                Log.i("data_post+intent", "saveProduct: "+utils.convertGson(productModelsSave.getIdProduct()));
                productService.updateProduct(productModelsSave, productModelsIntent.getIdProduct()).enqueue(new Callback<DataResponse<ProductModels>>() {
                    @Override
                    public void onResponse(Call<DataResponse<ProductModels>> call, Response<DataResponse<ProductModels>> response) {
                        Log.i("CodeUpdate", "onResponse: "+utils.convertGson(response.body()));
                        if (response.body() != null){
                            new AlertDialog.Builder(FormProductActivity.this)
                                    .setCancelable(false)
                                    .setTitle("Update Product")
                                    .setMessage("Update product success")
                                    .setPositiveButton("Oke", new DialogInterface.OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialogInterface, int i) {
                                            MainActivity.status_update = false;
                                            startActivity(new Intent(FormProductActivity.this, MainActivity.class));
                                            finish();
                                        }
                                    }).show();
                        }else{
                            new AlertDialog.Builder(FormProductActivity.this)
                                    .setTitle("Update Product")
                                    .setMessage("Update product failed, try again!").show();
                        }
                        progressDialog.dismiss();
                    }

                    @Override
                    public void onFailure(Call<DataResponse<ProductModels>> call, Throwable t) {
                        progressDialog.dismiss();
                        Log.e("Error input", "onFailure: ",t );
                    }
                });
            }
        }else {
            Log.i("save_path", "saveProduct: "+locationPath);
            if (locationPath != null){
                File fileImage = new File(locationPath);
                Log.i("save", "saveProduct: "+locationPath);
                if (fileImage.exists()){
                    if (
                            !productModelsSave.getProductName().isEmpty() ||
                                    productModelsSave.getPriceProduct() != 0 ||
                                    productModelsSave.getStockProduct() != 0
                    ){
                        progressDialog.setCancelable(false);
                        progressDialog.show();
                        ProductService productService = client.Client(ProductService.class);
                        Log.i("data_post", "saveProduct: "+utils.convertGson(productModelsSave.getProductName()+productModelsSave.getStockProduct()+productModelsSave.getPriceProduct()));
                        Log.i("IMAGE", "saveProduct: "+utils.convertGson(productModelsSave.getImageProduct()));
                        productService.postProduct(productModelsSave).enqueue(new Callback<DataResponse<ProductModels>>() {
                            @Override
                            public void onResponse(Call<DataResponse<ProductModels>> call, Response<DataResponse<ProductModels>> response) {
                                Log.i("Success Post", "onResponse: "+utils.convertGson(response.body()));
                                if (response.body() != null){
                                    new AlertDialog.Builder(FormProductActivity.this)
                                            .setCancelable(false)
                                            .setTitle("Add New Product")
                                            .setMessage("Add new product success")
                                            .setPositiveButton("Oke", new DialogInterface.OnClickListener() {
                                                @Override
                                                public void onClick(DialogInterface dialogInterface, int i) {
                                                    startActivity(new Intent(FormProductActivity.this, MainActivity.class));
                                                    finish();
                                                }
                                            }).show();
                                }else{
                                    new AlertDialog.Builder(FormProductActivity.this)
                                            .setTitle("Add New Product")
                                            .setMessage("Add new product failed, try again!").show();
                                }
                                progressDialog.dismiss();
                            }

                            @Override
                            public void onFailure(Call<DataResponse<ProductModels>> call, Throwable t) {
                                progressDialog.dismiss();
                                Log.e("Error input", "onFailure: ",t );
                            }
                        });
                    }

                }
            }
        }
    }

    private int getCategory(String s) {

        Log.i("CATEGORY", "getCategory: "+s);
        CategoryServise categoryServise = client.Client(CategoryServise.class);
        categoryServise.getCategoryByName(s).enqueue(new Callback<DataResponse<List<CategoryModels>>>() {
            @Override
            public void onResponse(Call<DataResponse<List<CategoryModels>>> call, Response<DataResponse<List<CategoryModels>>> response) {
                Log.i("CHDJHD", "getCategory: "+utils.convertGson(response.body()));
                id = response.body().getData().get(0).getIdCategory();
                productModels.setCategoryProduct(id);
                categorySelect.add(0, id);
                progressDialog.dismiss();
            }

            @Override
            public void onFailure(Call<DataResponse<List<CategoryModels>>> call, Throwable t) {

            }
        });
        return id;
    }

    private String getCategoryById(int s) {
        CategoryServise categoryServise = client.Client(CategoryServise.class);
        categoryServise.getCategoryId(s).enqueue(new Callback<DataResponse<CategoryModels>>() {
            @Override
            public void onResponse(Call<DataResponse<CategoryModels>> call, Response<DataResponse<CategoryModels>> response) {
                if (response.body() != null){
                    str.add(response.body().getData().getNameCategory());
                }else{
                    str.add("SELECT CATEGORY");
                }
            }

            @Override
            public void onFailure(Call<DataResponse<CategoryModels>> call, Throwable t) {

            }
        });
        Log.i("CategoryName", "getCategoryById: "+categoryName);
        return categoryName;
    }

    private void openFile(){
        requestPermissions(permissions, REQUEST_PERMISSIONS);
        Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(i, 100);

    }

    private File createImageFile() {
        try {
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
            File image = File.createTempFile(
                    "MESSER_" + timeStamp + "_",
                    ".jpg",
                    getExternalFilesDir(Environment.DIRECTORY_PICTURES)
            );
            file = image;
            return image;
        } catch (Exception ex) {
            ex.printStackTrace();

            return null;
        }
    }

    private void takePhoto() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            File photoFile = createImageFile();

            if (photoFile != null) {
                Uri photoURI = FileProvider.getUriForFile(this,
                        "com.example.android.messer",
                        photoFile);
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 100 && resultCode == RESULT_OK && data != null) {
            Uri selectedImage = data.getData();

            binding.setPhoto(utils.convertImageBase64File(getRealPathFromURI(selectedImage)));

            locationPath = getRealPathFromURI(selectedImage);


            binding.ivProduct.setImageBitmap(utils.decodeImageBase64(utils.convertImageBase64File(getRealPathFromURI(selectedImage))));
            productModels.setImageProduct(utils.convertImageBase64File(getRealPathFromURI(selectedImage)));
//            utils.convertImageBase64File(getRealPathFromURI(selectedImage))
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == REQUEST_PERMISSIONS && grantResults.length != permissions.length) {
            requestPermissions(permissions, REQUEST_PERMISSIONS);
        }
    }

    private String getRealPathFromURI(Uri contentUri) {
        String[] proj = {MediaStore.Images.Media.DATA};
        CursorLoader loader = new CursorLoader(this, contentUri, proj, null, null, null);
        Cursor cursor = loader.loadInBackground();
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        String result = cursor.getString(column_index);
        cursor.close();
        return result;
    }
}
