/*
 * 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.SightDao;
import ch.spherIC.recurvebowsight.databinding.ActivitySightConfigurationBinding;
import ch.spherIC.recurvebowsight.model.ISight;
import ch.spherIC.recurvebowsight.model.impl.Sight;
import ch.spherIC.recurvebowsight.ui.userguide.UserGuideSightActivity;
import ch.spherIC.recurvebowsight.utilities.NoFilterArrayAdapter;
import ch.spherIC.recurvebowsight.utilities.PlatformUtils;

public class SightConfigurationActivity extends AppCompatActivity {

    private ActivitySightConfigurationBinding binding;
    private SightConfigurationViewModel sightConfigurationViewModel;

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

        this.sightConfigurationViewModel = new ViewModelProvider(this).get(SightConfigurationViewModel.class);
        this.binding = ActivitySightConfigurationBinding.bind(findViewById(R.id.activity_sight_configuration));

        addObservers();
        addSightSpinnerListener();
        addButtonListeners();
        loadSights();
    }

    @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 userGuideSightIntent = new Intent(this.binding.getRoot().getContext(), UserGuideSightActivity.class);
                startActivity(userGuideSightIntent);
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void addObservers() {
        DecimalFormat dF = new DecimalFormat("#.#");
        this.sightConfigurationViewModel.getManufacturer().observe(this, manufacturer -> this.binding.scManufacturerTxt.setText(manufacturer));
        this.sightConfigurationViewModel.getModel().observe(this, model -> this.binding.scModelTxt.setText(model));
        this.sightConfigurationViewModel.getAH().observe(this, aH -> this.binding.scaHTxt.setText(aH != null ? dF.format(aH) : ""));
        this.sightConfigurationViewModel.getAV().observe(this, aV -> this.binding.scaVTxt.setText(aV != null ? dF.format(aV) : ""));
        this.sightConfigurationViewModel.getHeVis().observe(this, heVis -> this.binding.sccHeVSTxt.setText(heVis));
        this.sightConfigurationViewModel.getVertSkalaRangMin().observe(this, vertScRngMin -> this.binding.scVertScaleRngMinTxt.setText(vertScRngMin != null ? dF.format(vertScRngMin) : ""));
        this.sightConfigurationViewModel.getVertSkalaRangMax().observe(this, vertScRngMax -> this.binding.scVertScaleRngMaxTxt.setText(vertScRngMax != null ? dF.format(vertScRngMax) : ""));
        this.sightConfigurationViewModel.getPointerOffset().observe(this, pointerOffset -> this.binding.scPointerOffsetTxt.setText(pointerOffset != null ? dF.format(pointerOffset) : ""));
    }

    private void addSightSpinnerListener() {
        AutoCompleteTextView textView = findViewById(R.id.sightSelectionTxt);
        textView.setOnItemClickListener((parent, view, position, id) -> {
            ISight selectedSight = (ISight) textView.getAdapter().getItem(position);
            if (selectedSight != null) {
                sightConfigurationViewModel.setSight(selectedSight);
            }
        });
    }

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

        Button deleteButton = findViewById(R.id.sightcfg_button_delete);
        deleteButton.setOnClickListener(v -> deleteSight());

        Button saveButton = findViewById(R.id.sightcfg_button_save);
        saveButton.setOnClickListener(v -> saveSightConfiguration());
    }

    private void loadSights() {
        List<ISight> sights = SightDao.getInstance().loadAll();
        ArrayAdapter<ISight> adapter = new NoFilterArrayAdapter<ISight>(this, android.R.layout.simple_dropdown_item_1line, sights);
        AutoCompleteTextView textView = this.binding.sightSelectionTxt;
        textView.setAdapter(adapter);
        textView.invalidate();
    }

    private void addNewSight() {
        ISight newSight = new Sight(0, "", "", null, null, null, null, null, null);
        this.sightConfigurationViewModel.setSight(newSight);
        String strMandatory = getString(R.string.caption_mandatory);
        this.binding.sightSelectionTxt.setText(null, false);
        this.binding.scManufacturerTxt.setError(strMandatory);
        this.binding.scModelTxt.setError(strMandatory);
        this.binding.scaVTxt.setError(strMandatory);
        this.binding.scaHTxt.setError(strMandatory);
        this.binding.sccHeVSTxt.setError(strMandatory);
        this.binding.scVertScaleRngMinTxt.setError(strMandatory);
        this.binding.scVertScaleRngMaxTxt.setError(strMandatory);
        this.binding.scPointerOffsetTxt.setError(strMandatory);
        AutoCompleteTextView textView = this.binding.sightSelectionTxt;
        ((ArrayAdapter<ISight>) textView.getAdapter()).insert(newSight, 0);
        textView.setAdapter((ArrayAdapter<ISight>) textView.getAdapter());
        textView.setSelection(0);
    }

    private void saveSightConfiguration() {
        if (!validateInputs()) {
            return;
        }
        this.sightConfigurationViewModel.setManufacturerText(this.binding.scManufacturerTxt.getText().toString());
        this.sightConfigurationViewModel.setModelText(this.binding.scModelTxt.getText().toString());
        this.sightConfigurationViewModel.setAH(PlatformUtils.parseDouble(this.binding.scaHTxt.getText().toString()));
        this.sightConfigurationViewModel.setAV(PlatformUtils.parseDouble(this.binding.scaVTxt.getText().toString()));
        this.sightConfigurationViewModel.setHeVis(this.binding.sccHeVSTxt.getText().toString());
        this.sightConfigurationViewModel.setVertSkalaRangMin(PlatformUtils.parseDouble(this.binding.scVertScaleRngMinTxt.getText().toString()));
        this.sightConfigurationViewModel.setVertSkalaRangMax(PlatformUtils.parseDouble(this.binding.scVertScaleRngMaxTxt.getText().toString()));
        this.sightConfigurationViewModel.setPointerOffset(PlatformUtils.parseDouble(this.binding.scPointerOffsetTxt.getText().toString()));

        ISight lSight = this.sightConfigurationViewModel.getRiser().getValue();
        if (lSight.getId() > 0) {
            SightDao.getInstance().update(lSight);
            PlatformUtils.toast(SightConfigurationActivity.this, String.format(getString(R.string.caption_Cfg_UpdateSuccessful), lSight)).show();

        } else {
            lSight = SightDao.getInstance().insert(lSight);
            loadSights();
            AutoCompleteTextView textView = this.binding.sightSelectionTxt;
            final int position = ((ArrayAdapter<ISight>) textView.getAdapter()).getPosition(lSight);
            textView.setListSelection(position);
            textView.setText(lSight.toString(), false);
            ((ArrayAdapter<ISight>) textView.getAdapter()).getFilter().filter(null);
            PlatformUtils.toast(SightConfigurationActivity.this, String.format(getString(R.string.caption_Cfg_SaveSuccessful), lSight)).show();
        }
    }

    private boolean validateInputs() {
        int invalidFields = 0;
        if (this.binding.scManufacturerTxt.getText().toString().isEmpty() || this.binding.scManufacturerTxt.getText().toString().equals("*")) {
            invalidFields++;
        }
        if (this.binding.scModelTxt.getText().toString().isEmpty() || this.binding.scModelTxt.getText().toString().equals("*")) {
            invalidFields++;
        }
        if (this.binding.scaVTxt.getText() == null || this.binding.scaVTxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (this.binding.scaHTxt.getText() == null || this.binding.scaHTxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (this.binding.sccHeVSTxt.getText() == null || this.binding.sccHeVSTxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (this.binding.scVertScaleRngMinTxt.getText() == null || this.binding.scVertScaleRngMinTxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (this.binding.scVertScaleRngMaxTxt.getText() == null || this.binding.scVertScaleRngMaxTxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (this.binding.scPointerOffsetTxt.getText() == null || this.binding.scPointerOffsetTxt.getText().toString().equals("")) {
            invalidFields++;
        }
        if (invalidFields > 0) {
            PlatformUtils.toast(this, getResources().getString(R.string.caption_Cfg_FillAllMandatoryFields)).show();
            return false;
        }
        return true;
    }

    private void deleteSight() {
        ISight lSight = this.sightConfigurationViewModel.getRiser().getValue();

        if (lSight != null) {
            AlertDialog dlg = PlatformUtils.getDeleteConfirmDialog(this, lSight.toString(), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(final DialogInterface dialog, final int which) {
                    String message = String.format(getString(R.string.caption_Cfg_DeleteSuccessful), lSight);
                    try {
                        SightDao.getInstance().delete(lSight);
                        loadSights();
                        sightConfigurationViewModel.setSight(null);
                        binding.sightSelectionTxt.setText(null, false);
                    } catch (Exception e) {
                        message = getString(R.string.caption_Cfg_DeleteNotPossible);
                    }
                    PlatformUtils.toast(SightConfigurationActivity.this, message).show();
                }
            });
            dlg.show();
        }
    }
}
