package org.mte.numecoeval.calculs.infrastructure.repository;

import lombok.extern.slf4j.Slf4j;
import org.mte.numecoeval.calculs.domain.exception.DatabaseException;
import org.mte.numecoeval.common.utils.ResultSetUtils;
import org.mte.numecoeval.topic.data.OperationNonITDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

@Component
@Slf4j
public class OperationNonITRepository {

    @Autowired
    private DataSource dataSource;

    private static final String COLUMN_NAME_NOM_COURT_DATACENTER = "nom_court_datacenter";

    public List<OperationNonITDTO> findOperationNonITDTOs(List<Long> ids) {
        List<OperationNonITDTO> result = new ArrayList<>();

        try (Connection conn = dataSource.getConnection()) {
            try (var ps = conn.prepareStatement("""
                      SELECT *
                        FROM en_operation_non_it opnit
                        WHERE id = ANY (?)
                    """)) {

                ps.setArray(1, conn.createArrayOf("long", ids.toArray(new Long[0])));

                var rs = ps.executeQuery();
                while (rs.next()) {
                    result.add(OperationNonITDTO.builder()
                            .id(rs.getLong("id"))
                            .nomLot(rs.getString("nom_lot"))
                            .dateLot(ResultSetUtils.getLocalDate(rs, "date_lot"))
                            .nomOrganisation(rs.getString("nom_organisation"))
                            .nomItemNonIT(rs.getString("nom_item_non_it"))
                            .quantite(ResultSetUtils.getDouble(rs, "quantite"))
                            .type(rs.getString("type"))
                            .dureeDeVie(ResultSetUtils.getDouble(rs, "duree_de_vie"))
                            .localisation(rs.getString("localisation"))
                            .nomEntite(rs.getString("nom_entite"))
                            .nomSourceDonnee(rs.getString("nom_source_donnee"))
                            .nomCourtDatacenter(rs.getString(COLUMN_NAME_NOM_COURT_DATACENTER))
                            .description(rs.getString("description"))
                            .consoElecAnnuelle(ResultSetUtils.getDouble(rs, "conso_elec_annuelle"))
                            .qualite(rs.getString("qualite"))
                            .build());
                }
            }
        } catch (SQLException e) {
            log.error("Une erreur s'est produite lors de la selection dans PostgreSQL. Exception: ", e);
            throw new DatabaseException(e);
        }

        return result;
    }

    public void setStatutToTraite(Long id) {
        try (Connection conn = dataSource.getConnection()) {
            try (var ps = conn.prepareStatement("""
                    UPDATE en_operation_non_it
                    SET statut_traitement = 'TRAITE', date_update = now()
                    WHERE id = ?
                    """)) {
                ps.setLong(1, id);
                ps.execute();
            }
        } catch (SQLException e) {
            log.error("Une erreur s'est produite lors de la selection dans PostgreSQL. Exception: ", e);
            throw new DatabaseException(e);
        }
    }
}
