package com.jachdev.consumerprotection.ui.camera;

import androidx.annotation.Nullable;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import butterknife.BindView;
import butterknife.OnClick;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import com.github.dhaval2404.imagepicker.ImagePicker;
import com.google.mlkit.vision.text.TextRecognition;
import com.google.mlkit.vision.text.TextRecognizer;
import com.google.mlkit.vision.text.latin.TextRecognizerOptions;
import com.jachdev.commonlibs.base.BaseActivity;
import com.jachdev.commonlibs.utils.DateTimeUtil;
import com.jachdev.commonlibs.utils.Helper;
import com.jachdev.commonlibs.widget.CustomImageView;
import com.jachdev.commonlibs.widget.CustomTextView;
import com.jachdev.consumerprotection.BuildConfig;
import com.jachdev.consumerprotection.R;
import com.jachdev.consumerprotection.data.LipidProfile;
import com.jachdev.consumerprotection.data.enums.TestReportType;
import com.jachdev.consumerprotection.ui.notifications.NotificationsViewModel;
import com.jachdev.consumerprotection.util.ImageAnalyzer;
import com.jachdev.consumerprotection.util.SessionManager;
import com.karumi.dexter.Dexter;
import com.karumi.dexter.MultiplePermissionsReport;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.multi.MultiplePermissionsListener;

import java.io.File;
import java.util.List;

public class CameraActivity extends BaseActivity implements ImageAnalyzer.ImageAnalyzerListener {

    private static final String TAG = CameraActivity.class.getSimpleName();
    @BindView(R.id.civ_camera)
    CustomImageView imageView;
    @BindView(R.id.tv_glucose)
    CustomTextView tvGlucose;
    @BindView(R.id.tv_chol)
    CustomTextView tvChol;
    @BindView(R.id.tv_hdl)
    CustomTextView tvHdl;
    @BindView(R.id.tv_ldl)
    CustomTextView tvLdl;

    private CameraViewModel cameraViewModel;
    private ImageAnalyzer analyzer;
    private Uri uri;
    private LipidProfile lipidProfile;

    @Override
    protected int layoutRes() {
        return R.layout.activity_camera;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        analyzer = new ImageAnalyzer(CameraActivity.this, this);
        lipidProfile = new LipidProfile(SessionManager.getInstance().getUser().getUid(), System.currentTimeMillis()/1000);

        cameraViewModel = new ViewModelProvider(this).get(CameraViewModel.class);
        cameraViewModel.getLipidProfile().observe(this, mObserverLipidProfile);

        tvGlucose.setAnyText(getString(R.string.glucose_level, "0"));
        tvChol.setAnyText(getString(R.string.cholesterol_level, "0"));
        tvHdl.setAnyText(getString(R.string.hdl_level, "0"));
        tvLdl.setAnyText(getString(R.string.ldl_level, "0"));
    }

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

        checkCameraPermissions();
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (resultCode == Activity.RESULT_OK) {
            uri = data.getData();

            imageView.loadImage(uri.getPath());

            textExtract(uri);

        } else if (resultCode == ImagePicker.RESULT_ERROR) {
            Toast.makeText(this, ImagePicker.Companion.getError(data), Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "Task Cancelled", Toast.LENGTH_SHORT).show();
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void onTestReportExtract(TestReportType type, double amount, String unit) {
        Log.d(TAG, "onGlucoseExtract: type = " + type.toString());
        Log.d(TAG, "onGlucoseExtract: amount = " + amount);
        Log.d(TAG, "onGlucoseExtract: unit = " + unit);

        if(amount == 0 || unit == null)
            return;

        String level = null;
        switch (type){
            case GLUCOSE:

                level = Helper.toCurrencyFormat(amount) + " " + unit;
                tvGlucose.setAnyText(getString(R.string.glucose_level, level));
                lipidProfile.setGlu(String.valueOf(amount));

                break;
            case CHOLESTEROL:

                level = Helper.toCurrencyFormat(amount) + " " + unit;
                tvChol.setAnyText(getString(R.string.cholesterol_level, level));
                lipidProfile.setCho(String.valueOf(amount));

                break;
            case HDL:

                level = Helper.toCurrencyFormat(amount) + " " + unit;
                tvHdl.setAnyText(getString(R.string.hdl_level, level));
                lipidProfile.setHdl(String.valueOf(amount));

                break;
            case LDL:

                level = Helper.toCurrencyFormat(amount) + " " + unit;
                tvLdl.setAnyText(getString(R.string.ldl_level, level));
                lipidProfile.setLdl(String.valueOf(amount));

                break;
        }
    }

    @OnClick(R.id.civ_camera)
    public void OnClickCamera(){
        onImagePicker();
    }

    @OnClick(R.id.btn_rescan)
    public void OnClickRescan(){
        textExtract(uri);
    }

    @OnClick(R.id.btn_sync)
    public void OnClickSync(){
        lipidProfile.setCreatedAt(System.currentTimeMillis()/1000);
        lipidProfile.setUpdatedAt(System.currentTimeMillis()/1000);
        cameraViewModel.addLipidProfile(lipidProfile);
        showWaiting();
    }

    private void textExtract(Uri uri) {
        analyzer.analyze(uri);
    }

    public void onImagePicker() {

        ImagePicker.Companion.with(this)
                .crop()	    			//Crop image(Optional), Check Customization for more option
                .compress(1024)			//Final image size will be less than 1 MB(Optional)
                .maxResultSize(1080, 1080)	//Final image resolution will be less than 1080 x 1080(Optional)
                .start();
    }

    private void checkCameraPermissions() {
        Dexter.withActivity(this)
                .withPermissions(
                        Manifest.permission.READ_EXTERNAL_STORAGE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.CAMERA)
                .withListener(new MultiplePermissionsListener() {
                    @Override
                    public void onPermissionsChecked(MultiplePermissionsReport report) {
                        // check if all permissions are granted
                        if (report.areAllPermissionsGranted()) {
                            // do you work now
                        }

                        // check for permanent denial of any permission
                        if (report.isAnyPermissionPermanentlyDenied()) {
                            // permission is denied permenantly, navigate user to app settings
                            showSettingsDialog();
                        }
                    }

                    @Override
                    public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
                        token.continuePermissionRequest();
                    }
                })
                .onSameThread()
                .check();
    }

    private void showSettingsDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(CameraActivity.this);
        builder.setTitle(getString(R.string.need_permissions));
        builder.setMessage(getString(R.string.need_permissions_to_use_this_feature));
        builder.setPositiveButton(getString(R.string.goto_settings), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
                openSettings();
            }
        });
        builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });
        builder.show();
    }

    private Observer<? super List<LipidProfile>> mObserverLipidProfile = new Observer<List<LipidProfile>>() {
        @Override
        public void onChanged(List<LipidProfile> lipidProfiles) {
            dismissWaiting();


        }
    };
}