package danielcortes.xyz.controllers;

import danielcortes.xyz.data.DAOManager;
import danielcortes.xyz.models.caja.Caja;
import danielcortes.xyz.models.calculo_fondo.CalculoFondo;
import danielcortes.xyz.views.CalcularFondoView;
import danielcortes.xyz.views.components.table_model.FondoTableModel;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JTable;
import javax.swing.KeyStroke;

public class CalcularFondoController extends BaseController {

  private CalcularFondoView view;
  private Caja caja;

  private int editingId;
  private boolean editing;
  private CalculoFondo editingCalculoFondo;

  public CalcularFondoController(CalcularFondoView view, Caja caja) {
    this.view = view;
    this.caja = caja;

    this.fillTable();
    this.fillResumen();
    this.updateResumen();
    this.setupViewEvents();
    this.updateButtonsEnabled();
  }

  private void fillTable() {
    FondoTableModel tableModel = this.view.getTableModel();
    tableModel.removeRows();
    for (CalculoFondo calculoFondo : DAOManager.getCalculoFondoDAO().getByCaja(this.caja)) {
      tableModel.addRow(calculoFondo);
    }
  }

  private void fillResumen() {
    this.view.getFondoField().setValue(this.caja.getFondo());
  }

  private void updateResumen() {
    this.caja.setFondo(this.view.getFondoField().getValue());
    int suma = DAOManager.getCalculoFondoDAO().getTotalCalculoFondo(this.caja);

    this.view.getSumaField().setValue(suma);
    this.view.getDepositoField().setValue(suma - this.caja.getFondo());

    DAOManager.getCajaDAO().update(this.caja);
  }

  private void setupViewEvents() {
    moveTo(this.view.getValorField(), this.view.getDescripcionField());
    doAction(this.view.getDescripcionField(), "save", KeyStroke.getKeyStroke("ENTER"),
        e -> this.guardarActionListener());
    doAction(this.view.getFondoField(), "updateResumen", KeyStroke.getKeyStroke("ENTER"),
        e -> this.updateResumen());

    this.view.getTable().getSelectionModel().addListSelectionListener(e -> updateButtonsEnabled());
    this.view.getGuardarButton().addActionListener(e -> guardarActionListener());
    this.view.getEditarButton().addActionListener(e -> editarActionListener());
    this.view.getEliminarButton().addActionListener(e -> eliminarActionListener());
    this.view.getTable().addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent mouseEvent) {
        JTable table = (JTable) mouseEvent.getSource();
        if (mouseEvent.getClickCount() == 2 && table.getSelectedRow() != -1) {
          CalcularFondoController.this.editarActionListener();
        }
      }
    });
  }

  private void guardarActionListener() {
    this.normalizeInput();

    int valor = this.view.getValorField().getValue();
    String descripcion = this.view.getDescripcionField().getText();

    if (editing) {
      this.editarCalculoFondo(valor, descripcion);
      this.editing = false;
    } else {
      this.guardarCalculoFondo(valor, descripcion);
    }

    this.updateResumen();
    this.cleanInput();
    this.resetFocus();
  }

  private void editarActionListener() {
    int selectedID = this.view.getTable().getSelectedRow();
    if (selectedID >= 0) {
      int selectedModelID = this.view.getTable().getRowSorter().convertRowIndexToModel(selectedID);
      CalculoFondo calculoFondo = this.view.getTableModel().getCalculoFondo(selectedModelID);

      this.editingId = selectedModelID;
      this.editingCalculoFondo = calculoFondo;
      this.editing = true;

      this.view.getValorField().setValue(calculoFondo.getValor());
      this.view.getDescripcionField().setText(calculoFondo.getDescripcion());
    }
  }

  private void eliminarActionListener() {
    int selectedID = this.view.getTable().getSelectedRow();
    if (selectedID >= 0) {
      CalculoFondo calculoFondo = this.view.getTableModel().getCalculoFondo(selectedID);
      this.view.getTableModel().removeRow(selectedID);
      DAOManager.getCalculoFondoDAO().delete(calculoFondo);
      this.updateResumen();
      this.updateButtonsEnabled();
      this.resetFocus();
    }
  }

  private void guardarCalculoFondo(int valor, String descripcion) {
    CalculoFondo calculoFondo = new CalculoFondo();
    calculoFondo.setValor(valor);
    calculoFondo.setDescripcion(descripcion);
    calculoFondo.setCaja(this.caja);
    DAOManager.getCalculoFondoDAO().insert(calculoFondo);
    this.view.getTableModel().addRow(calculoFondo);
  }

  private void editarCalculoFondo(int valor, String descripcion) {
    this.editingCalculoFondo.setValor(valor);
    this.editingCalculoFondo.setDescripcion(descripcion);
    this.editingCalculoFondo.setCaja(this.caja);
    DAOManager.getCalculoFondoDAO().update(editingCalculoFondo);
    this.view.getTableModel().setCalculoFondo(this.editingId, this.editingCalculoFondo);
  }

  private void updateButtonsEnabled() {
    if (this.view.getTable().getSelectedRow() >= 0) {
      this.view.getEliminarButton().setEnabled(true);
      this.view.getEditarButton().setEnabled(true);
    } else {
      this.view.getEliminarButton().setEnabled(false);
      this.view.getEditarButton().setEnabled(false);
    }
  }


  private void cleanInput() {
    this.view.getValorField().setValue(0);
    this.view.getDescripcionField().setText("");

  }

  private void normalizeInput() {
    if (this.view.getDescripcionField().getText() == null) {
      this.view.getDescripcionField().setText("");
    }

    this.view.getDescripcionField().setText(this.view.getDescripcionField().getText().trim());
  }

  private void resetFocus() {
    this.view.getValorField().requestFocus();
  }
}
