/*
 * Copyright (C) 2022 - Florindo Smilari (spherIC)
 */
package ch.spherIC.recurvebowsight.ui.configuration;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;

import java.text.DecimalFormat;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import ch.spherIC.recurvebowsight.R;
import ch.spherIC.recurvebowsight.database.dao.ArcherySetupDao;
import ch.spherIC.recurvebowsight.database.dao.ArrowDao;
import ch.spherIC.recurvebowsight.database.dao.RiserDao;
import ch.spherIC.recurvebowsight.database.dao.SightDao;
import ch.spherIC.recurvebowsight.databinding.ActivityEquipmentConfigurationBinding;
import ch.spherIC.recurvebowsight.model.IArcherySetup;
import ch.spherIC.recurvebowsight.model.IArrow;
import ch.spherIC.recurvebowsight.model.IRiser;
import ch.spherIC.recurvebowsight.model.ISight;
import ch.spherIC.recurvebowsight.model.impl.ArcherySetup;
import ch.spherIC.recurvebowsight.ui.userguide.UserGuideArcherySetupActivity;
import ch.spherIC.recurvebowsight.utilities.NoFilterArrayAdapter;
import ch.spherIC.recurvebowsight.utilities.PlatformUtils;

public class ArcherySetupConfigurationActivity extends AppCompatActivity {

    private ActivityEquipmentConfigurationBinding binding;
    private ArcherySetupConfigurationViewModel archerySetupConfigurationViewModel;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_equipment_configuration);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setTitle(R.string.title_activity_archery_setup_configuration);

        this.archerySetupConfigurationViewModel = new ViewModelProvider(this).get(ArcherySetupConfigurationViewModel.class);
        this.binding = ActivityEquipmentConfigurationBinding.bind(findViewById(R.id.activity_equipment_configuration));

        addObservers();
        addSpinnerListeners();
        addButtonListeners();
        loadSightsRisersArrows();
        loadArcherySetups();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        MenuItem menuItemSettings = menu.findItem(R.id.action_settings);
        MenuItem menuItemHelp = menu.findItem(R.id.action_help);
        menuItemSettings.setEnabled(false);
        menuItemHelp.setEnabled(true);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                this.finish();
                return true;
            case R.id.action_help:
                Intent userGuideASIntent = new Intent(this.binding.getRoot().getContext(), UserGuideArcherySetupActivity.class);
                startActivity(userGuideASIntent);
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void addObservers() {
        DecimalFormat dF = new DecimalFormat("#.#");
        DecimalFormat dF2 = new DecimalFormat("#.##");
        DecimalFormat dF3 = new DecimalFormat("#.###");
        this.archerySetupConfigurationViewModel.getName().observe(this, name -> this.binding.asLabelTxt.setText(name));
        this.archerySetupConfigurationViewModel.getSight().observe(this, sight -> this.binding.asSightSelectionTxt.setText(sight != null ? sight.toString() : "", false));
        this.archerySetupConfigurationViewModel.getRiser().observe(this, riser -> this.binding.asRiserSelectionTxt.setText(riser != null ? riser.toString() : "", false));
        this.archerySetupConfigurationViewModel.getArrow().observe(this, arrow -> this.binding.asArrowSelectionTxt.setText(arrow != null ? arrow.toString() : "", false));
        this.archerySetupConfigurationViewModel.getArrowNockHeight().observe(this, arwNH -> this.binding.asArrowNockHeightTxt.setText(arwNH != null ? dF2.format(arwNH) : ""));
        this.archerySetupConfigurationViewModel.getTargetCenterHeight().observe(this, arwCH -> this.binding.asTargetCenterHeightTxt.setText(arwCH != null ? dF.format(arwCH) : ""));
        this.archerySetupConfigurationViewModel.getBowPullout().observe(this, bowPlOut -> this.binding.asBowPulloutTxt.setText(bowPlOut != null ? dF.format(bowPlOut) : ""));
        this.archerySetupConfigurationViewModel.getHNA().observe(this, ahNA -> this.binding.asHNATxt.setText(ahNA != null ? dF.format(ahNA) : ""));
        this.archerySetupConfigurationViewModel.getNockRaising().observe(this, nockRsg -> this.binding.asNockRaisingTxt.setText(nockRsg != null ? dF.format(nockRsg) : ""));
        this.archerySetupConfigurationViewModel.getBraceHeight().observe(this, brH -> this.binding.asBraceHeightTxt.setText(brH != null ? dF.format(brH) : ""));
        this.archerySetupConfigurationViewModel.getDeltaTime().observe(this, deltaTm -> this.binding.asDeltaTimeTxt.setText(deltaTm != null ? dF3.format(deltaTm) : ""));
        this.archerySetupConfigurationViewModel.getCalcPrecision().observe(this, calcPrec -> this.binding.asCalcPrecisionTxt.setText(calcPrec != null ? dF.format(calcPrec) : ""));
        this.archerySetupConfigurationViewModel.getSightVertSkalaMiddle().observe(this, vScaleMdl -> this.binding.asSightVertScaleMiddleTxt.setText(vScaleMdl != null ? dF.format(vScaleMdl) : ""));
        this.archerySetupConfigurationViewModel.getSightHorzSetting().observe(this, hrzSetting -> this.binding.asSightHorzSettingTxt.setText(hrzSetting != null ? dF.format(hrzSetting) : ""));
    }

    private void addSpinnerListeners() {
        AutoCompleteTextView textViewAS = findViewById(R.id.asArcherySetupSelectionTxt);
        textViewAS.setOnItemClickListener((parent, view, position, id) -> {
            IArcherySetup selectedArcherySetup = (IArcherySetup) textViewAS.getAdapter().getItem(position);
            if (selectedArcherySetup != null) {
                archerySetupConfigurationViewModel.setArcherySetup(selectedArcherySetup);
            }
        });
    }

    private void addButtonListeners() {
        Button newButton = findViewById(R.id.archerystpcfg_button_new);
        newButton.setOnClickListener(v -> addNewArcherySetup());

        Button deleteButton = findViewById(R.id.archerystpcfg_button_delete);
        deleteButton.setOnClickListener(v -> deleteArcherySetup());

        Button saveButton = findViewById(R.id.archerystpcfg_button_save);
        saveButton.setOnClickListener(v -> saveArcherySetupConfiguration());
    }

    private void loadSightsRisersArrows() {
        List<ISight> sights = SightDao.getInstance().loadAll();
        this.archerySetupConfigurationViewModel.setAllSights(sights);
        ArrayAdapter<ISight> sightsAdapter = new NoFilterArrayAdapter<ISight>(this, android.R.layout.simple_dropdown_item_1line, sights);
        AutoCompleteTextView textViewSights = this.binding.asSightSelectionTxt;
        textViewSights.setAdapter(sightsAdapter);
        textViewSights.invalidate();

        List<IRiser> risers = RiserDao.getInstance().loadAll();
        this.archerySetupConfigurationViewModel.setAllRisers(risers);
        ArrayAdapter<IRiser> riserAdapter = new NoFilterArrayAdapter<IRiser>(this, android.R.layout.simple_dropdown_item_1line, risers);
        AutoCompleteTextView textViewRisers = this.binding.asRiserSelectionTxt;
        textViewRisers.setAdapter(riserAdapter);
        textViewRisers.invalidate();

        List<IArrow> arrows = ArrowDao.getInstance().loadAll();
        this.archerySetupConfigurationViewModel.setAllArrows(arrows);
        ArrayAdapter<IArrow> arrowAdapter = new NoFilterArrayAdapter<IArrow>(this, android.R.layout.simple_dropdown_item_1line, arrows);
        AutoCompleteTextView textViewArrows = this.binding.asArrowSelectionTxt;
        textViewArrows.setAdapter(arrowAdapter);
        textViewArrows.invalidate();
    }

    private void loadArcherySetups() {
        List<IArcherySetup> archerySetups = ArcherySetupDao.getInstance().loadAll();
        ArrayAdapter<IArcherySetup> archerySetupsAdapter = new NoFilterArrayAdapter<IArcherySetup>(this, android.R.layout.simple_dropdown_item_1line, archerySetups);
        AutoCompleteTextView textViewASs = this.binding.asArcherySetupSelectionTxt;
        textViewASs.setAdapter(archerySetupsAdapter);
        textViewASs.invalidate();
    }

    private void addNewArcherySetup() {
        IArcherySetup newArcherySetup = new ArcherySetup(0, "", null, null, null, null, null,
                                                         null, null, null, null, null,
                                                         null, null, null);
        this.archerySetupConfigurationViewModel.setArcherySetup(newArcherySetup);
        String strMandatory = getString(R.string.caption_mandatory);
        this.binding.asArcherySetupSelectionTxt.setText(null, false);
        this.binding.asLabelTxt.setError(strMandatory);
        this.binding.asRiserSelectionTxt.setError(strMandatory);
        this.binding.asSightSelectionTxt.setError(strMandatory);
        this.binding.asArrowSelectionTxt.setError(strMandatory);
        this.binding.asArrowNockHeightTxt.setError(strMandatory);
        this.binding.asTargetCenterHeightTxt.setError(strMandatory);
        this.binding.asBowPulloutTxt.setError(strMandatory);
        this.binding.asHNATxt.setError(strMandatory);
        this.binding.asNockRaisingTxt.setError(strMandatory);
        this.binding.asBraceHeightTxt.setError(strMandatory);
        this.binding.asDeltaTimeTxt.setError(strMandatory);
        this.binding.asCalcPrecisionTxt.setError(strMandatory);
        this.binding.asSightVertScaleMiddleTxt.setError(strMandatory);
        this.binding.asSightHorzSettingTxt.setError(strMandatory);

        AutoCompleteTextView textView = binding.asArcherySetupSelectionTxt;
        ((ArrayAdapter<IArcherySetup>) textView.getAdapter()).insert(newArcherySetup, 0);
        textView.setAdapter((ArrayAdapter<IRiser>) textView.getAdapter());
        textView.setSelection(0);
    }

    private void deleteArcherySetup() {
        IArcherySetup lArcherySetup = this.archerySetupConfigurationViewModel.getArcherySetup().getValue();

        if (lArcherySetup != null) {
            AlertDialog dlg = PlatformUtils.getDeleteConfirmDialog(this, lArcherySetup.toString(), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(final DialogInterface dialog, final int which) {
                    String message = String.format(getString(R.string.caption_Cfg_DeleteSuccessful), lArcherySetup);
                    try {
                        ArcherySetupDao.getInstance().delete(lArcherySetup);
                        loadArcherySetups();
                        archerySetupConfigurationViewModel.setArcherySetup(null);
                        binding.asArcherySetupSelectionTxt.setText(null, false);
                    } catch (Exception e) {
                        message = getString(R.string.caption_Cfg_DeleteNotPossible);
                    }
                    PlatformUtils.toast(ArcherySetupConfigurationActivity.this, message).show();
                }
            });
            dlg.show();
        }
    }

    private void saveArcherySetupConfiguration() {
        if (!validateInputs()) {
            return;
        }
        this.archerySetupConfigurationViewModel.setName(this.binding.asLabelTxt.getText().toString());
        this.archerySetupConfigurationViewModel.setSight(this.archerySetupConfigurationViewModel.findSightByName(this.binding.asSightSelectionTxt.getText().toString()));
        this.archerySetupConfigurationViewModel.setRiser(this.archerySetupConfigurationViewModel.findRiserByName(this.binding.asRiserSelectionTxt.getText().toString()));
        this.archerySetupConfigurationViewModel.setArrow(this.archerySetupConfigurationViewModel.findArrowByName(this.binding.asArrowSelectionTxt.getText().toString()));
        this.archerySetupConfigurationViewModel.setArrowNockHeight(PlatformUtils.parseDouble(this.binding.asArrowNockHeightTxt.getText().toString()));
        this.archerySetupConfigurationViewModel.setBowPullout(PlatformUtils.parseDouble(this.binding.asBowPulloutTxt.getText().toString()));
        this.archerySetupConfigurationViewModel.setHNA(PlatformUtils.parseDouble(this.binding.asHNATxt.getText().toString()));
        this.archerySetupConfigurationViewModel.setNockRaising(PlatformUtils.parseDouble(this.binding.asNockRaisingTxt.getText().toString()));
        this.archerySetupConfigurationViewModel.setBraceHeight(PlatformUtils.parseDouble(this.binding.asBraceHeightTxt.getText().toString()));
        this.archerySetupConfigurationViewModel.setTargetCenterHeight(PlatformUtils.parseDouble(this.binding.asTargetCenterHeightTxt.getText().toString()));
        this.archerySetupConfigurationViewModel.setDeltaTime(PlatformUtils.parseDouble(this.binding.asDeltaTimeTxt.getText().toString()));
        this.archerySetupConfigurationViewModel.setCalcPrecision(PlatformUtils.parseDouble(this.binding.asCalcPrecisionTxt.getText().toString()));
        this.archerySetupConfigurationViewModel.setSightVertSkalaMiddle(PlatformUtils.parseDouble(this.binding.asSightVertScaleMiddleTxt.getText().toString()));
        this.archerySetupConfigurationViewModel.setSightHorzSetting(PlatformUtils.parseDouble(this.binding.asSightHorzSettingTxt.getText().toString()));


        IArcherySetup lArcherySetup = this.archerySetupConfigurationViewModel.getArcherySetup().getValue();
        if (lArcherySetup.getId() > 0) {
            ArcherySetupDao.getInstance().update(lArcherySetup);
            PlatformUtils.toast(ArcherySetupConfigurationActivity.this, String.format(getString(R.string.caption_Cfg_UpdateSuccessful), lArcherySetup)).show();
        } else {
            lArcherySetup = ArcherySetupDao.getInstance().insert(lArcherySetup);
            loadArcherySetups();
            AutoCompleteTextView textView = this.binding.asArcherySetupSelectionTxt;
            final int position = ((ArrayAdapter<IArcherySetup>) textView.getAdapter()).getPosition(lArcherySetup);
            textView.setListSelection(position);
            textView.setText(lArcherySetup.toString());
            ((ArrayAdapter<IArcherySetup>) textView.getAdapter()).getFilter().filter(null);
            PlatformUtils.toast(ArcherySetupConfigurationActivity.this, String.format(getString(R.string.caption_Cfg_SaveSuccessful), lArcherySetup)).show();
        }

    }

    private boolean validateInputs() {
        int invalidFields = 0;
        if (this.binding.asLabelTxt.getText().toString().isEmpty() || this.binding.asLabelTxt.getText().toString().equals("*")) {
            invalidFields++;
        }
        if (this.binding.asSightSelectionTxt.getText() == null || this.binding.asSightSelectionTxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (this.binding.asRiserSelectionTxt.getText() == null || this.binding.asRiserSelectionTxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (this.binding.asArrowSelectionTxt.getText() == null || this.binding.asArrowSelectionTxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (this.binding.asArrowNockHeightTxt.getText() == null || this.binding.asArrowNockHeightTxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (this.binding.asTargetCenterHeightTxt.getText() == null || this.binding.asTargetCenterHeightTxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (this.binding.asBowPulloutTxt.getText() == null || this.binding.asBowPulloutTxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (this.binding.asHNATxt.getText() == null || this.binding.asHNATxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (this.binding.asNockRaisingTxt.getText() == null || this.binding.asNockRaisingTxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (this.binding.asBraceHeightTxt.getText() == null || this.binding.asBraceHeightTxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (this.binding.asDeltaTimeTxt.getText() == null || this.binding.asDeltaTimeTxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (this.binding.asCalcPrecisionTxt.getText() == null || this.binding.asCalcPrecisionTxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (this.binding.asSightVertScaleMiddleTxt.getText() == null || this.binding.asSightVertScaleMiddleTxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (this.binding.asSightHorzSettingTxt.getText() == null || this.binding.asSightHorzSettingTxt.getText().toString().equals("")) {
            invalidFields++;
        }

        if (invalidFields > 0) {
            PlatformUtils.toast(this, getResources().getString(R.string.caption_Cfg_FillAllMandatoryFields)).show();
            return false;
        }
        return true;
    }
}