package danielcortes.xyz.models.estado_resultado;

import danielcortes.xyz.data.ConnectionHolder;
import danielcortes.xyz.data.SQLiteConnectionHolder;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class SQLiteEstadoResultadoDAO implements EstadoResultadoDAO {

  private static final Logger log = LogManager.getLogger(SQLiteEstadoResultadoDAO.class);
  private ConnectionHolder connectionHolder;

  public SQLiteEstadoResultadoDAO() {
    this.connectionHolder = new SQLiteConnectionHolder();
  }

  public SQLiteEstadoResultadoDAO(ConnectionHolder connectionHolder) {
    this.connectionHolder = connectionHolder;
  }

  @Override
  public List<EstadoResultado> getAll() {
    log.debug("Se intentara conseguir todos los EstadoResultado");
    List<EstadoResultado> estadoResultadoList = new ArrayList<>();
    String query = "select * from estado_resultado";
    try (Connection conn = connectionHolder.getConnection()) {
      try (PreparedStatement ps = conn.prepareStatement(query)) {
        try (ResultSet rs = ps.executeQuery()) {
          while (rs.next()) {
            EstadoResultado estadoResultado = new EstadoResultado();
            estadoResultado.setId(rs.getInt("id"));
            estadoResultado.setMes(YearMonth.from(LocalDate.parse(rs.getString("mes"))));
            estadoResultado.setCostoVenta(rs.getInt("costo_venta"));
            estadoResultado.setCuentaCorrienteFactura(rs.getInt("cuenta_corriente_factura"));
            estadoResultado.setCuentaCorrienteBoleta(rs.getInt("cuenta_corriente_boleta"));
            estadoResultado
                .setCuentaCorrienteSinRespaldo(rs.getInt("cuenta_corriente_sin_respaldo"));
            estadoResultado.setRemuneraciones(rs.getInt("remuneraciones"));
            estadoResultado.setFiniquitos(rs.getInt("finiquitos"));
            estadoResultado.setAguinaldo(rs.getInt("aguinaldo"));
            estadoResultado.setBonosPersonal(rs.getInt("bonos_personal"));
            estadoResultado.setHonorariosContador(rs.getInt("honorarios_contador"));
            estadoResultado.setArriendo(rs.getInt("arriendo"));
            estadoResultado.setAgua(rs.getInt("agua"));
            estadoResultado.setLuz(rs.getInt("luz"));
            estadoResultado.setGas(rs.getInt("gas"));
            estadoResultado.setTelefono(rs.getInt("telefono"));
            estadoResultado.setOtroServicio(rs.getInt("otro_servicio"));
            estadoResultado.setPpm(rs.getDouble("ppm"));
            estadoResultado.setIvaFavor(rs.getInt("ivaFavor"));
          }
        }
      }
    } catch (SQLException e) {
      log.error("Error al intentar conseguir todos los EstadoResultado", e);
    }

    log.debug("Se consiguieron " + estadoResultadoList.size() + "EstadoResultado");
    return estadoResultadoList;
  }

  @Override
  public Optional<EstadoResultado> getById(int id) {
    log.debug("Se intentara conseguir el EstadoResultado con el id " + id);
    EstadoResultado estadoResultado = null;
    String query = "select * from estado_resultado where id = ?";
    try (Connection conn = connectionHolder.getConnection()) {
      try (PreparedStatement ps = conn.prepareStatement(query)) {
        ps.setInt(1, id);
        try (ResultSet rs = ps.executeQuery()) {
          if (rs.next()) {
            estadoResultado = new EstadoResultado();
            estadoResultado.setId(rs.getInt("id"));
            estadoResultado.setMes(YearMonth.from(LocalDate.parse(rs.getString("mes"))));
            estadoResultado.setCostoVenta(rs.getInt("costo_venta"));
            estadoResultado.setCuentaCorrienteFactura(rs.getInt("cuenta_corriente_factura"));
            estadoResultado.setCuentaCorrienteBoleta(rs.getInt("cuenta_corriente_boleta"));
            estadoResultado
                .setCuentaCorrienteSinRespaldo(rs.getInt("cuenta_corriente_sin_respaldo"));
            estadoResultado.setRemuneraciones(rs.getInt("remuneraciones"));
            estadoResultado.setFiniquitos(rs.getInt("finiquitos"));
            estadoResultado.setAguinaldo(rs.getInt("aguinaldo"));
            estadoResultado.setBonosPersonal(rs.getInt("bonos_personal"));
            estadoResultado.setHonorariosContador(rs.getInt("honorarios_contador"));
            estadoResultado.setArriendo(rs.getInt("arriendo"));
            estadoResultado.setAgua(rs.getInt("agua"));
            estadoResultado.setLuz(rs.getInt("luz"));
            estadoResultado.setGas(rs.getInt("gas"));
            estadoResultado.setTelefono(rs.getInt("telefono"));
            estadoResultado.setOtroServicio(rs.getInt("otro_servicio"));
            estadoResultado.setPpm(rs.getDouble("ppm"));
            estadoResultado.setIvaFavor(rs.getInt("ivaFavor"));
          }
        }
      }
    } catch (SQLException e) {
      log.error("Error al intentar conseguir el EstadoResultado con id " + id, e);
    }
    log.debug("Se consiguio el EstadoResultado " + estadoResultado);
    return Optional.ofNullable(estadoResultado);
  }

  @Override
  public Optional<EstadoResultado> getByMonth(YearMonth month) {
    log.debug("Se intentara conseguir un EstadoResultado con el mes " + month);
    EstadoResultado estadoResultado = null;
    String query = "select * from estado_resultado where mes = ?";
    try (Connection conn = connectionHolder.getConnection()) {
      try (PreparedStatement ps = conn.prepareStatement(query)) {
        ps.setString(1, month.atDay(1).toString());
        try (ResultSet rs = ps.executeQuery()) {
          if (rs.next()) {
            estadoResultado = new EstadoResultado();
            estadoResultado.setId(rs.getInt("id"));
            estadoResultado.setMes(YearMonth.from(LocalDate.parse(rs.getString("mes"))));
            estadoResultado.setCostoVenta(rs.getInt("costo_venta"));
            estadoResultado.setCuentaCorrienteFactura(rs.getInt("cuenta_corriente_factura"));
            estadoResultado.setCuentaCorrienteBoleta(rs.getInt("cuenta_corriente_boleta"));
            estadoResultado
                .setCuentaCorrienteSinRespaldo(rs.getInt("cuenta_corriente_sin_respaldo"));
            estadoResultado.setRemuneraciones(rs.getInt("remuneraciones"));
            estadoResultado.setFiniquitos(rs.getInt("finiquitos"));
            estadoResultado.setAguinaldo(rs.getInt("aguinaldo"));
            estadoResultado.setBonosPersonal(rs.getInt("bonos_personal"));
            estadoResultado.setHonorariosContador(rs.getInt("honorarios_contador"));
            estadoResultado.setArriendo(rs.getInt("arriendo"));
            estadoResultado.setAgua(rs.getInt("agua"));
            estadoResultado.setLuz(rs.getInt("luz"));
            estadoResultado.setGas(rs.getInt("gas"));
            estadoResultado.setTelefono(rs.getInt("telefono"));
            estadoResultado.setOtroServicio(rs.getInt("otro_servicio"));
            estadoResultado.setPpm(rs.getDouble("ppm"));
            estadoResultado.setIvaFavor(rs.getInt("ivaFavor"));
          }
        }
      }
    } catch (
        SQLException e) {
      log.error("Error al intentar conseguir un EstadoResultado con el mes " + month, e);
    }
    log.debug("Se consiguio el EstadoResultado " + estadoResultado);
    return Optional.ofNullable(estadoResultado);
  }

  @Override
  public void insert(EstadoResultado estadoResultado) {
    log.debug("Se intentara insertar el EstadoResultado " + estadoResultado);
    String query = "insert into estado_resultado (mes, costo_venta, cuenta_corriente_factura, cuenta_corriente_boleta, cuenta_corriente_sin_respaldo, remuneraciones, finiquitos, aguinaldo, bonos_personal, honorarios_contador, arriendo, agua, luz, gas, telefono, otro_servicio, ppm, ivaFavor) values (?, ?, ?, ?, ?, ? , ?, ? , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
    try (Connection conn = connectionHolder.getConnection()) {
      try (PreparedStatement ps = conn.prepareStatement(query)) {
        ps.setString(1, estadoResultado.getMes().atDay(1).toString());
        ps.setInt(2, estadoResultado.getCostoVenta());
        ps.setInt(3, estadoResultado.getCuentaCorrienteFactura());
        ps.setInt(4, estadoResultado.getCuentaCorrienteBoleta());
        ps.setInt(5, estadoResultado.getCuentaCorrienteSinRespaldo());
        ps.setInt(6, estadoResultado.getRemuneraciones());
        ps.setInt(7, estadoResultado.getFiniquitos());
        ps.setInt(8, estadoResultado.getAguinaldo());
        ps.setInt(9, estadoResultado.getBonosPersonal());
        ps.setInt(10, estadoResultado.getHonorariosContador());
        ps.setInt(11, estadoResultado.getArriendo());
        ps.setInt(12, estadoResultado.getAgua());
        ps.setInt(13, estadoResultado.getLuz());
        ps.setInt(14, estadoResultado.getGas());
        ps.setInt(15, estadoResultado.getTelefono());
        ps.setInt(16, estadoResultado.getOtroServicio());
        ps.setDouble(17, estadoResultado.getPpm());
        ps.setDouble(18, estadoResultado.getIvaFavor());

        ps.executeUpdate();
      }
      try (PreparedStatement ps = conn.prepareStatement("select  last_insert_rowid()")) {
        try (ResultSet rs = ps.executeQuery()) {
          rs.next();
          estadoResultado.setId(rs.getInt(1));
        }
      }
    } catch (SQLException e) {
      log.error("Error al intentar insertar el EstadoResultado " + estadoResultado, e);
    }
    log.debug("Se inserto el EstadoResultado " + estadoResultado);
  }

  @Override
  public void update(EstadoResultado estadoResultado) {
    log.debug("Se intentara actualizar el estadoResultado " + estadoResultado);
    String query = "update estado_resultado set mes = ?, costo_venta = ?, cuenta_corriente_factura = ?, cuenta_corriente_boleta = ?, cuenta_corriente_sin_respaldo = ?, remuneraciones = ?, finiquitos = ?, aguinaldo = ?, bonos_personal = ?, honorarios_contador = ?, arriendo = ?, agua = ?, luz = ?, gas = ?, telefono = ?, otro_servicio = ?, ppm = ?, ivaFavor = ? where id = ?";
    try (Connection conn = connectionHolder.getConnection()) {
      try (PreparedStatement ps = conn.prepareStatement(query)) {
        ps.setString(1, estadoResultado.getMes().atDay(1).toString());
        ps.setInt(2, estadoResultado.getCostoVenta());
        ps.setInt(3, estadoResultado.getCuentaCorrienteFactura());
        ps.setInt(4, estadoResultado.getCuentaCorrienteBoleta());
        ps.setInt(5, estadoResultado.getCuentaCorrienteSinRespaldo());
        ps.setInt(6, estadoResultado.getRemuneraciones());
        ps.setInt(7, estadoResultado.getFiniquitos());
        ps.setInt(8, estadoResultado.getAguinaldo());
        ps.setInt(9, estadoResultado.getBonosPersonal());
        ps.setInt(10, estadoResultado.getHonorariosContador());
        ps.setInt(11, estadoResultado.getArriendo());
        ps.setInt(12, estadoResultado.getAgua());
        ps.setInt(13, estadoResultado.getLuz());
        ps.setInt(14, estadoResultado.getGas());
        ps.setInt(15, estadoResultado.getTelefono());
        ps.setInt(16, estadoResultado.getOtroServicio());
        ps.setDouble(17, estadoResultado.getPpm());
        ps.setDouble(18, estadoResultado.getIvaFavor());
        ps.setInt(19, estadoResultado.getId());

        ps.executeUpdate();
      }
    } catch (SQLException e) {
      log.error("Error al intentar actualizar el estadoResultado " + estadoResultado, e);
    }
    log.debug("Se actualizo el estadoResultado " + estadoResultado);
  }


  @Override
  public void delete(EstadoResultado estadoResultado) {
    log.debug("Se intentara eliminar el EstadoResultado " + estadoResultado);
    String query = "delete from estado_resultado where id = ?";
    try (Connection conn = connectionHolder.getConnection()) {
      try (PreparedStatement ps = conn.prepareStatement(query)) {
        ps.setInt(1, estadoResultado.getId());
        ps.executeUpdate();
      }
    } catch (SQLException e) {
      log.error("Error al intentar eliminar el EstadoResultado " + estadoResultado, e);
    }
    log.debug("Se elimino el EstadoResultado " + estadoResultado);
  }
}
