package danielcortes.xyz.informes;

import danielcortes.xyz.data.DAOManager;
import danielcortes.xyz.models.caja.Caja;
import danielcortes.xyz.models.caja.CajaDAO;
import danielcortes.xyz.models.ingreso.IngresoDAO;
import danielcortes.xyz.models.tipo_ingreso.TipoIngreso;
import danielcortes.xyz.models.tipo_ingreso.TipoIngresoDAO;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.HashMap;

public class InformeLibroDeVentas{
  private HashMap<LocalDate, LibroDeVentas> informe;
  private InformeLibroDeVentas(){}

  public LibroDeVentas get(LocalDate localDate){
    return informe.get(localDate);
  }

  public int size(){
    return informe.size();
  }

  private void put(LocalDate date, LibroDeVentas libroDeVentas){
    this.informe.put(date, libroDeVentas);
  }

  public static InformeLibroDeVentas generate(YearMonth mes) {
    InformeLibroDeVentas informeLibroDeVentas = new InformeLibroDeVentas();
    informeLibroDeVentas.informe = new HashMap<>();

    LocalDate currentDate = mes.atDay(1);
    LocalDate endDatePlusOne = mes.atEndOfMonth().plusDays(1);

    CajaDAO cajaDAO = DAOManager.getCajaDAO();
    IngresoDAO ingresoDAO = DAOManager.getIngresoDAO();
    TipoIngresoDAO tipoIngresoDAO = DAOManager.getTipoIngresoDAO();

    TipoIngreso boletaFiscal = tipoIngresoDAO.getByNombre("Boletas Fiscales").orElse(TipoIngreso.EMPTY);
    TipoIngreso boletaManual = tipoIngresoDAO.getByNombre("Boletas Manuales").orElse(TipoIngreso.EMPTY);
    TipoIngreso boletaExenta = tipoIngresoDAO.getByNombre("Boleta Exenta").orElse(TipoIngreso.EMPTY);
    TipoIngreso factura = tipoIngresoDAO.getByNombre("Facturas").orElse(TipoIngreso.EMPTY);
    TipoIngreso guias = tipoIngresoDAO.getByNombre("Guias").orElse(TipoIngreso.EMPTY);

    while (currentDate.isBefore(endDatePlusOne)) {
      Caja caja = cajaDAO.getByFecha(currentDate).orElse(Caja.EMPTY);

      LibroDeVentas data = new LibroDeVentas();
      informeLibroDeVentas.put(currentDate, data);

      data.setDia(currentDate.getDayOfWeek().getValue());
      data.setFecha(currentDate);

      data.setManuales(ingresoDAO.getTotalIngresoEnCajaPorTipo(caja, boletaManual));
      data.setManualesInicial(
          ingresoDAO.getPrimerNroInicialDeCajaDeTipo(caja, boletaManual).orElse("0"));
      data.setManualesFinal(
          ingresoDAO.getUltimoNroFinalDeCajaDeTipo(caja, boletaManual).orElse("0"));

      data.setFiscales(ingresoDAO.getTotalIngresoEnCajaPorTipo(caja, boletaFiscal));
      data.setFiscalesInicial(
          ingresoDAO.getPrimerNroInicialDeCajaDeTipo(caja, boletaFiscal).orElse("0"));
      data.setFiscalesFinal(
          ingresoDAO.getUltimoNroFinalDeCajaDeTipo(caja, boletaFiscal).orElse("0"));
      data.setFiscalesZInicial(ingresoDAO.getPrimerNroZInicialDeCaja(caja).orElse("0"));
      data.setFiscalesZFinal(ingresoDAO.getUltimoNroZFinalDeCaja(caja).orElse("0"));

      data.setExentas(ingresoDAO.getTotalIngresoEnCajaPorTipo(caja, boletaExenta));
      data.setExentasInicial(
          ingresoDAO.getPrimerNroInicialDeCajaDeTipo(caja, boletaExenta).orElse("0"));
      data.setExentasFinal(
          ingresoDAO.getUltimoNroFinalDeCajaDeTipo(caja, boletaExenta).orElse("0"));

      data.setFacturas(ingresoDAO.getTotalIngresoEnCajaPorTipo(caja, factura));
      data.setFacturasInicial(
          ingresoDAO.getPrimerNroInicialDeCajaDeTipo(caja, factura).orElse("0"));
      data.setFacturasFinal(ingresoDAO.getUltimoNroFinalDeCajaDeTipo(caja, factura).orElse("0"));

      data.setGuias(ingresoDAO.getTotalIngresoEnCajaPorTipo(caja, guias));
      data.setGuiasInicial(ingresoDAO.getPrimerNroInicialDeCajaDeTipo(caja, guias).orElse("0"));
      data.setGuiasFinal(ingresoDAO.getUltimoNroFinalDeCajaDeTipo(caja, guias).orElse("0"));

      currentDate = currentDate.plusDays(1);
    }

    return informeLibroDeVentas;
  }
}
