package com.utopiaindustries.qualitychecker.ui.adapter;

import static androidx.core.app.ActivityCompat.startActivityForResult;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.utopiaindustries.qualitychecker.R;
import com.utopiaindustries.qualitychecker.models.InspectionCheckPoint;
import com.utopiaindustries.qualitychecker.models.InspectionCheckpointSku;
import com.utopiaindustries.qualitychecker.models.InspectionDefect;
import com.utopiaindustries.qualitychecker.models.InspectionItemCheckPoint;
import com.utopiaindustries.qualitychecker.utils.ImageUriHolder;

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

public class CheckPointAdapter extends
        RecyclerView.Adapter<CheckPointAdapter.ViewHolder> {

    private final List<InspectionItemCheckPoint> checkPointList;
    private final List<InspectionCheckPoint> checkPoints;
    private final List<InspectionDefect> defects;
    private final List<String> defectTypes;
    private final List<InspectionCheckpointSku> checkpointSkus;
    private final Context context;

    public CheckPointAdapter(  List<InspectionItemCheckPoint> checkPointList,
                               List<InspectionCheckPoint> checkPoints,
                               List<InspectionDefect> defects,
                               List<String> defectTypes,
                               List<InspectionCheckpointSku> checkpointSkus,
                               Context context ) {

        this.checkPointList = checkPointList;
        this.checkPoints = checkPoints;
        this.defects = defects;
        this.defectTypes = defectTypes;
        this.checkpointSkus = checkpointSkus;
        this.context = context;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from( parent.getContext() )
                .inflate(R.layout.check_point, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public long getItemId(int position) {
        return checkPointList.get( position ).getUuid().hashCode();
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        InspectionItemCheckPoint checkPoint = checkPointList.get( position );
        holder.imageRecyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));
        holder.bind(checkPoints, defects, defectTypes, checkPoint, checkpointSkus, context );

        //holder.setIsRecyclable(false);
        // spinner on change
        {
            holder.checkpointSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                    if( parent.getItemAtPosition(position) != null  ){
                        String selectedItem = parent.getItemAtPosition(position).toString();
                        InspectionCheckPoint cp = checkPoints.stream().filter(check -> check.getTitle().equalsIgnoreCase(selectedItem))
                                .findFirst().orElse(new InspectionCheckPoint());
                        holder.populateDefects(cp, defects, checkPoint);
                        checkPoint.setTitle(selectedItem);

                        if (view instanceof TextView) {
                            ((TextView) view).setTextColor(Color.BLACK);
                        }
                    }
                }
                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                }
            });

        }
        // checkboxes on change
        {
           holder.setUpCheckboxesListeners( checkPoint );
        }
        // remarks on change
        {
           holder.setupRemarksListener( checkPoint );
        }

        holder.imagePicker.setOnClickListener( v -> {
            //--------------------------------------------------------------------------------------
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            builder.setTitle("Choose an Option");

            String[] options = {"Gallery", "Camera"};
            builder.setItems(options, (dialog, which) -> {
                switch (which) {
                    case 0:
                        Log.e("Gallery","**********");
                        Intent intent = new Intent( Intent.ACTION_GET_CONTENT );
                        intent.addCategory( Intent.CATEGORY_OPENABLE );
                        intent.setType( "image/*" );
                        ( ( Activity ) context ).startActivityForResult( intent,  position );
                        break;
                    case 1:
                        Log.e("Camera: ","***********");
                        Intent camera_intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        File imageFile = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "captured_image.jpg");
                        Uri imageUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", imageFile);
                        //Log.e("imageUri: ",""+imageUri);
                        ImageUriHolder.getInstance().setImageUri(imageUri);
                        camera_intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                        ( ( Activity ) context ).startActivityForResult(camera_intent, position);
                        break;
                }
            });

            builder.setNegativeButton("Cancel", (dialog, which) -> dialog.dismiss());

            AlertDialog dialog = builder.create();
            dialog.show();
            //--------------------------------------------------------------------------------------
            //Image pick from Gallery
            /*Intent intent = new Intent( Intent.ACTION_GET_CONTENT );
            intent.addCategory( Intent.CATEGORY_OPENABLE );
            intent.setType( "image/*" );
            ( ( Activity ) context ).startActivityForResult( intent,  position );*/

            //Now image Pick from Camera
            /*Intent camera_intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            ( ( Activity ) context ).startActivityForResult(camera_intent, position);*/

        });

        holder.deleteImage.setOnClickListener( v -> {
            checkPoint.setFile( null );
            checkPoint.setImagePath( "" );
           // holder.imagePreview.setImageDrawable( null );
            checkPoint.getFiles().listIterator(checkPoint.getFiles().size());
            if (!checkPoint.getFiles().isEmpty()) {
                checkPoint.getFiles().remove(checkPoint.getFiles().size() - 1);
            } else {
                System.out.println("The list is empty");
            }
            notifyItemChanged( position );
        });

        holder.addDefect.setOnClickListener( v -> {
            checkPoint.getDefectTitles().add("");
            checkPoint.getDefectSeverites().add("MINOR");
            checkPoint.getQuantities().add(0f);
            notifyItemChanged( position );
        });
    }


    @Override
    public int getItemCount() {
        return checkPointList.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        private final Spinner checkpointSpinner;
        private final CheckBox okCheckBox, noCheckBox;
        private final EditText remarks;
        private final ImageButton imagePicker,deleteImage,addDefect;
        private final LinearLayout linearLayout;
        private final TextView selectedImage,standard;
        //private final ImageView imagePreview;
        private final RecyclerView defectRecyclerView;
        private TextWatcher remarksTextWatcher;
        private CompoundButton.OnCheckedChangeListener okCheckboxListener;
        private CompoundButton.OnCheckedChangeListener noCheckboxListener;

        private RecyclerView imageRecyclerView;
        private ImageAdapter imageAdapter;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            remarks = itemView.findViewById(R.id.check_point_remarks);
            checkpointSpinner = itemView.findViewById(R.id.check_point_spinner);
            checkpointSpinner.setClickable(false);
            checkpointSpinner.setEnabled(false);
            okCheckBox = itemView.findViewById(R.id.check_point_ok);
            noCheckBox = itemView.findViewById(R.id.check_point_no);
            imagePicker = itemView.findViewById(R.id.image_picker );
            selectedImage = itemView.findViewById( R.id.selected_image );
            linearLayout = itemView.findViewById(R.id.defect_layout);
            deleteImage = itemView.findViewById( R.id.delete_image );
           // imagePreview = itemView.findViewById( R.id.preview_image );

            imageRecyclerView = itemView.findViewById(R.id.imageRecyclerView);

            defectRecyclerView = itemView.findViewById( R.id.defects_recyclerview );
            addDefect = itemView.findViewById( R.id.add_defect );
            standard = itemView.findViewById( R.id.standard );
        }


        public void bind(List<InspectionCheckPoint> checkPoints,
                         List<InspectionDefect> defects,
                         List<String> defectTypeOptions,
                         InspectionItemCheckPoint data,
                         List<InspectionCheckpointSku> checkpointSkus,
                         Context context ) {

            if ( remarksTextWatcher != null) {
                remarks.removeTextChangedListener(remarksTextWatcher);
            }
            if( okCheckboxListener != null ){
                okCheckBox.setOnCheckedChangeListener( null );
            }
            if( noCheckboxListener != null ){
                noCheckBox.setOnCheckedChangeListener( null );
            }

            remarks.setText( data.getRemarks() );
           // imagePreview.setImageBitmap( null );
            selectedImage.setText( "" );
            /*if( data.getFile() != null && data.getFile().length > 0 && data.getImagePath() != null && ! data.getImagePath().isEmpty() ){
                Bitmap bitmap = BitmapFactory.decodeByteArray( data.getFile(), 0 , data.getFile().length );
                imagePreview.setImageBitmap( bitmap );
                selectedImage.setText( data.getImagePath() );
            }*/

            // initialize recyclerview
            List<String> checkPointsList = checkPoints.stream().map(InspectionCheckPoint::getTitle).collect(Collectors.toList());


            // Populate checklist Spinner dropdown
            ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(checkpointSpinner.getContext(),
                    android.R.layout.simple_spinner_item, checkPointsList);
            spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            checkpointSpinner.setAdapter(spinnerAdapter);

            //image Recyclerview

            if ( data != null ) {
                if (data.getFiles() != null) {
                    List<byte[]> imageList = data.getFiles();
                    //System.out.println("Image-size-adapter: " + imageList.size());
                    imageRecyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));
                    imageAdapter = new ImageAdapter(imageList, context);
                    imageRecyclerView.setAdapter(imageAdapter);
                    imageAdapter.notifyItemChanged(getAdapterPosition());

                }
            }

            // Pre populate
            String defaultSelectedItem = data.getTitle();
            int defaultPosition = checkPointsList.indexOf(defaultSelectedItem);
            checkpointSpinner.setSelection(defaultPosition);

            okCheckBox.setChecked( data.getChecked() );
            noCheckBox.setChecked( ! data.getChecked());

            if( data.getChecked()){
                linearLayout.setVisibility(View.INVISIBLE);
            } else {
                linearLayout.setVisibility(View.VISIBLE);
            }

            InspectionCheckPoint cp = checkPoints.stream().filter(c -> c.getTitle().equalsIgnoreCase(defaultSelectedItem)).findFirst().orElse( new InspectionCheckPoint());
            // set standard
            if( checkpointSkus != null ){
                InspectionCheckpointSku cpSku = checkpointSkus.stream()
                        .filter( inspectionCheckpointSku -> inspectionCheckpointSku.getCheckpointId() ==  cp.getId() )
                        .findFirst()
                        .orElse( new InspectionCheckpointSku() );
                if( cpSku.getStandard() != null && ! cpSku.getStandard().isEmpty() ){
                    standard.setText( cpSku.getStandard() );
                } else {
                    if( standard.getParent() != null  ){
                        ((ViewGroup) standard.getParent() ).removeView( standard );
                    }
                }
            }
            defectRecyclerView.setLayoutManager( new LinearLayoutManager( context ) );
            DefectsAdapter defectsAdapter = new DefectsAdapter(data, defectTypeOptions, defects, cp);
            defectRecyclerView.setAdapter( defectsAdapter );

        }
        private void populateDefects(InspectionCheckPoint cp, List<InspectionDefect> defects, InspectionItemCheckPoint data) {

            List<InspectionDefect> filteredDefects = defects.stream()
                    .filter(d -> d.getCategory().equalsIgnoreCase(cp.getCategory()))
                    .collect(Collectors.toList());
            List<String> defectList = filteredDefects.stream().map(InspectionDefect::getDefect).collect(Collectors.toList());

        }

        public void setupRemarksListener(InspectionItemCheckPoint checkPoint) {
            // Remarks EditText listener
            remarksTextWatcher = new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    checkPoint.setRemarks(s.toString());
                }

                @Override
                public void afterTextChanged(Editable s) {
                }
            };
            remarks.addTextChangedListener( remarksTextWatcher );
        }

        public void setUpCheckboxesListeners( InspectionItemCheckPoint checkPoint  ){

            okCheckboxListener = (buttonView, isChecked) -> {
                if (isChecked) {
                    linearLayout.setVisibility(View.INVISIBLE);
                }
                checkPoint.setChecked ( false );
                noCheckBox.setChecked( !isChecked );
            };

            noCheckboxListener = (buttonView, isChecked) -> {
                if (isChecked) {
                    linearLayout.setVisibility(View.VISIBLE);
                }
                checkPoint.setChecked( true );
                okCheckBox.setChecked( !isChecked );
            };

            okCheckBox.setOnCheckedChangeListener( okCheckboxListener );
            noCheckBox.setOnCheckedChangeListener( noCheckboxListener );
        }
    }
}
