package com.hesiii.i_hear.SignFunction;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;

import android.Manifest;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.hesiii.i_hear.API.ApiServices;
import com.hesiii.i_hear.API.RetroServer;
import com.hesiii.i_hear.R;
import com.hesiii.i_hear.ResponseModels.SignResponse;
import com.hesiii.i_hear.databinding.ActivitySignFunctionBinding;
import com.hesiii.i_hear.databinding.SignResultViewBinding;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class SignFunctionActivity extends AppCompatActivity {

    private ActivitySignFunctionBinding binding;
    private File signImageFile;
    private static final int START_CAMERA_CODE = 2;
    private static final int GALLERY_REQUEST_CODE = 1;
    private String [] words;
    private String randomSign;
    private ProgressDialog progressDialog;
    private Dialog resultLayout;
    private SignResultViewBinding signResultViewBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivitySignFunctionBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        if (getSupportActionBar() != null) {

            getSupportActionBar().hide();

        }

        words = new String[] {
                "A", "B", "C", "D", "E", "F", "G"
        };

        if ((checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) || (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {

            requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);

        } else {

            binding.imageCaptureButton.setEnabled(true);

        }

        progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Please Wait...");
        progressDialog.setCancelable(false);

        randomSign = getRandomWord();
        binding.signText.setText(randomSign);
        setResultView();

        binding.imageCaptureButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                imageCaptureButtonProcess();

            }
        });

        binding.getResultButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                checkWithAPI(new File(signImageFile.getAbsolutePath()));

            }
        });

    }

    private void setResultView() {

        resultLayout = new Dialog(this);
        resultLayout.setContentView(R.layout.sign_result_view);
        resultLayout.setCancelable(true);
        //resultLayout.getWindow().setBackgroundDrawable(ContextCompat.getDrawable(this, R.drawable.window_background));
        resultLayout.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        signResultViewBinding = SignResultViewBinding.bind(resultLayout.findViewById(R.id.resultLayout));

        signResultViewBinding.doneButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                resultLayout.dismiss();
                startActivity(new Intent(SignFunctionActivity.this, SignFunctionActivity.class));
                finish();

            }
        });

    }

    private String getRandomWord() {

        // Create a Random object
        Random random = new Random();

        // Generate a random index within the range of the array
        int randomIndex = random.nextInt(words.length);

        // Get the random word
        String randomWord = words[randomIndex];

        // Print the random word
        System.out.println("Randomly selected word: " + randomWord);
        return randomWord;

    }

    private void imageCaptureButtonProcess() {

        signImageFile = createPhotoFile();

        Uri fileURI = FileProvider.getUriForFile(this, "com.hesiii.file_provider", signImageFile);

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileURI);
        startActivityForResult(intent, START_CAMERA_CODE);

    }

    private File createPhotoFile() {

        File photoFileDir = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "SIGN_IMAGES");

        if (!photoFileDir.exists()) {

            photoFileDir.mkdirs();

        }

        String name = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date())+".jpg";
        return new File(photoFileDir.getPath()+File.separator+name);

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == 0) {

            if (grantResults.length > 0) {

                if ((grantResults[0] == PackageManager.PERMISSION_GRANTED) && (grantResults[1] == PackageManager.PERMISSION_GRANTED)) {

                    binding.imageCaptureButton.setEnabled(true);
                    Toast.makeText(this, "PERMISSION GRANTED", Toast.LENGTH_SHORT).show();

                } else {

                    Toast.makeText(this, "PERMISSION DENIED", Toast.LENGTH_SHORT).show();

                }

            }

        }

    }

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

        if (resultCode == RESULT_OK) {

            if (requestCode == START_CAMERA_CODE) {

                System.out.println("callback camera");
                System.out.println("Image Path : "+signImageFile.getAbsolutePath());

                Bitmap bitmap = BitmapFactory.decodeFile(signImageFile.getAbsolutePath());
                binding.signImage.setImageBitmap(bitmap);
                binding.contentContainer.setVisibility(View.VISIBLE);
                //checkWithAPI(new File(signImageFile.getAbsolutePath()));

            }

        } else {

            Toast.makeText(this, "Something Went wrong!", Toast.LENGTH_SHORT).show();

        }

    }

    private void checkWithAPI(File file) {

        progressDialog.show();

        // Create an instance of the ApiService using the Retrofit instance
        ApiServices apiServices = RetroServer.getRetrofitInstance().create(ApiServices.class);

        // Create a request body from the file to be sent in the API request
        RequestBody requestFile = RequestBody.create(MediaType.parse("image/*"), file);
        // Create a MultipartBody.Part for the image file with the key "image_path"
        MultipartBody.Part imagePart = MultipartBody.Part.createFormData("image_path", file.getName(), requestFile);

        // Create the API request to get the sign response
        Call<SignResponse> getSignResponse = apiServices.getSignResult(randomSign, imagePart);

        // Enqueue the API request and define callbacks for success and failure
        getSignResponse.enqueue(new Callback<SignResponse>() {
            @Override
            public void onResponse(@NonNull Call<SignResponse> call, @NonNull Response<SignResponse> response) {

                if (response.isSuccessful()) {

                    // Handle success response from the API
                    if (response.body() != null) {

                        setDataForResultLayout(response.body());

                    } else {

                        Toast.makeText(SignFunctionActivity.this, "Try Again!", Toast.LENGTH_SHORT).show();
                        progressDialog.cancel();

                    }

                } else {

                    // Handle error response from the API
                    Toast.makeText(SignFunctionActivity.this, "Something Went Wrong - "+response.code(), Toast.LENGTH_SHORT).show();
                    progressDialog.cancel();

                }

            }

            @Override
            public void onFailure(@NonNull Call<SignResponse> call, @NonNull Throwable t) {

                // Handle failure, such as network issues or exceptions
                Toast.makeText(SignFunctionActivity.this, t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
                System.out.println(t.getLocalizedMessage());
                progressDialog.cancel();

            }
        });

    }

    private void setDataForResultLayout(SignResponse signResponse) {

        String status = null;

        if (signResponse.getMatched().equals("True")) {

            status = "Matched";
            signResultViewBinding.matchText.setTextColor(Color.GREEN);

        } else {

            status = "Not Matched";
            signResultViewBinding.matchText.setTextColor(Color.RED);

        }

        signResultViewBinding.matchText.setText(status);
        System.out.println(status);

        String preSignType = "Pre Sign Type : "+signResponse.getPreSignType();
        signResultViewBinding.preSignType.setText(preSignType);
        System.out.println(signResponse.getPreSignType());

        String trueSignType = "True Sign Type : "+signResponse.getTrueSignType();
        signResultViewBinding.trueSignType.setText(trueSignType);
        System.out.println(signResponse.getTrueSignType());

        String probability = "Probability : "+signResponse.getProbability();
        signResultViewBinding.probabilityText.setText(probability);
        System.out.println(signResponse.getProbability());

        progressDialog.cancel();
        resultLayout.show();

    }

}