/*
 * MIT License
 *
 * Copyright (c) 2018-2019 Daniel Cortes
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package danielcortes.xyz.controllers;

import danielcortes.xyz.data.DAOManager;
import danielcortes.xyz.models.caja.Caja;
import danielcortes.xyz.models.documentos.Documentos;
import danielcortes.xyz.models.efectivo.Efectivo;
import danielcortes.xyz.views.ArqueoView;
import danielcortes.xyz.views.CajasView;
import danielcortes.xyz.views.EgresosView;
import danielcortes.xyz.views.IngresosView;
import java.awt.CardLayout;
import java.time.LocalDate;

/**
 * Controlador destinado a controlar la vista de CajasView Ademas es la que crea las vistas internas
 * en un CardLayaut junto a sus controladores
 */
public class CajasController {

  private CajasView view;

  private IngresosController ingresosController;
  private EgresosController egresosController;
  private ArqueoController arqueoController;

  /**
   * Crea el controlador Necesita todos las interfaces DAO para poder asignarselos a sus vistas,
   * esto con el objetivo que sean facilmente intercambiables.
   * <p>
   * Llama a los metodos que: - Cargan el contenido del CardLayout - Selecciona una fecha inicial -
   * Genera los eventos de la vista - Presiona el boton de la vista inicial
   */
  public CajasController(CajasView view) {
    this.view = view;
    this.loadCardContents();
    this.setUpDate();
    this.setUpViewEvents();
    this.pressInitialButton();
  }

  public CajasView getView() {
    return view;
  }

  /**
   * Coloca la fecha actual en el datepicker y luego llama a actualizar las cajas de las vistas
   */
  private void setUpDate() {
    this.view.getDatePicker().setDateToToday();
    this.updateCaja();
  }

  /**
   * Setea los eventos de los botones y el datepicker - Cada vez que se cambia la fecha en el
   * datepicker se llama a actualizar la caja - Cuando se presiona uno de los botones muestra la
   * vista correspondiente en el cardlayout
   */
  private void setUpViewEvents() {
    this.view.getEgresosButton().addActionListener(e -> {
      CardLayout layout = (CardLayout) this.view.getCardPanel().getLayout();
      layout.show(this.view.getCardPanel(), "EGRESOS");
    });
    this.view.getIngresosButton().addActionListener(e -> {
      CardLayout layout = (CardLayout) this.view.getCardPanel().getLayout();
      layout.show(this.view.getCardPanel(), "INGRESOS");
    });
    this.view.getArqueoButton().addActionListener(e -> {
      this.arqueoController.updateResumen();

      CardLayout layout = (CardLayout) this.view.getCardPanel().getLayout();
      layout.show(this.view.getCardPanel(), "ARQUEO");
    });
    this.view.getDatePicker().addDateChangeListener(e -> updateCaja());
  }

  /**
   * Llama a update caja con la fecha seleccionada en el datepicker en los controladores del
   * manager.
   */
  private void updateCaja() {
    LocalDate selectedDate = this.view.getDatePicker().getDate();
    Caja caja = DAOManager.getCajaDAO().getByFecha(selectedDate).orElseGet(() -> {
      Caja c = new Caja();
      c.setFecha(selectedDate);
      DAOManager.getCajaDAO().insert(c);

      Efectivo efectivo = new Efectivo();
      efectivo.setCaja(c);
      efectivo.setDiez(0);
      efectivo.setCincuenta(0);
      efectivo.setCien(0);
      efectivo.setQuinientos(0);
      efectivo.setMil(0);
      efectivo.setDosMil(0);
      efectivo.setCincoMil(0);
      efectivo.setDiezMil(0);
      efectivo.setVeinteMil(0);
      DAOManager.getEfectivoDAO().insert(efectivo);

      Documentos documentos = new Documentos();
      documentos.setTarjetas(0);
      documentos.setCheques(0);
      documentos.setRetiros(0);
      documentos.setCaja(c);
      DAOManager.getDocumentosDAO().insert(documentos);

      return c;
    });

    this.ingresosController.updateCaja(caja);
    this.egresosController.updateCaja(caja);
    this.arqueoController.updateCaja(caja);
  }

  /**
   * Llama a los metodos que cargan las vistas que estaran dentro del cardlayout
   */
  private void loadCardContents() {
    this.loadEgresosView();
    this.loadIngresosView();
    this.loadArqueoView();
  }

  /**
   * Crea la vista de ingresos, la agrega a el cardlayout y se le es asignado a su controlador
   */
  private void loadIngresosView() {
    IngresosView ingresosView = new IngresosView();

    this.view.getCardPanel().add(ingresosView.getContentPanel(), "INGRESOS");

    this.ingresosController = new IngresosController(ingresosView);
  }

  /**
   * Crea la vista de egresos, la agrega a el cardlayout y se le es asignado a su controlador
   */
  private void loadEgresosView() {
    EgresosView egresosView = new EgresosView();

    this.view.getCardPanel().add(egresosView.getContentPanel(), "EGRESOS");

    this.egresosController = new EgresosController(egresosView);
  }

  /**
   * Crea la vista de arqueo, la agrega a el cardlayout y se le es asignado a su controlador
   */
  private void loadArqueoView() {
    ArqueoView arqueoView = new ArqueoView();

    this.view.getCardPanel().add(arqueoView.getContentPanel(), "ARQUEO");

    this.arqueoController = new ArqueoController(arqueoView);
  }

  /**
   * Activa el primer boton del manager
   */
  private void pressInitialButton() {
    this.view.getIngresosButton().doClick();
  }
}
