package mx.com.amx.mx.dda.crn.bo;

import java.io.File;
import java.io.FileOutputStream;
import java.time.LocalDate;
import java.time.Month;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.ws.client.core.WebServiceTemplate;

import mx.com.amx.mx.dda.crn.dao.DDACargaTransacVisualDAO;
import mx.com.amx.mx.dda.crn.dto.ParamCargaTitulosPNDTO;
import mx.com.amx.mx.dda.crn.dto.ParamCargaTitulosVSDTO;
import mx.com.amx.mx.dda.crn.dto.ResponseCargaTitulosPNDTO;
import mx.com.amx.mx.dda.crn.dto.ResponseCargaTitulosVSDTO;
import mx.com.amx.mx.dda.crn.dto.TransaccionDTO;
import mx.com.amx.mx.dda.crn.dto.VisualizacionDTO;
import mx.com.amx.mx.dda.crn.restClient.DDARestClient;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class DDACargaTransacVisualBO {

    private final Logger LOG = Logger.getLogger(this.getClass().getSimpleName());
    private final String ARCHIVO_PROPIEDADES = "/general.properties";
    Properties env = new Properties();

    @Autowired
    @Qualifier("wsNotificaAFijoSAP")
    private WebServiceTemplate wsNotificaAFijoSAP;

    private DDACargaTransacVisualDAO dao;

    private String AMBIENTE;

    private String fileName;
    private String date;
    private String dateName;
    private String expediente = "soporte";

    public DDACargaTransacVisualBO() {
        super();
        try {
            getDate();
            env.load(this.getClass().getResourceAsStream(ARCHIVO_PROPIEDADES));
            AMBIENTE = env.getProperty("ambiente");
        } catch (Exception e) {
            LOG.error(">Constructor[" + this.getClass().getSimpleName() + "] Ocurrio un error : " + e.getMessage());
        }
    }

    public void recuperarTransacciones() throws Exception {
        LOG.debug("    - [" + this.getClass().getSimpleName() + "::creando Archivo de Excel para carga]");

        //Por cada línea se crea un arreglo de objetos (Object[])
        Map<Integer, Object[]> datos = new TreeMap<>();
        LOG.info("Recuperando de la base de datos");
        List<TransaccionDTO> transacciones = dao.obtenerTransaccionesMes(date);
        LOG.info(transacciones.size() + " datos recuperados con fecha " + date);
        datos.put(1, new Object[]{"FILIAL", "ID PROGRAM", "TITULO", "MEDIO PAGO", "ABONO", "PRECIO", "CANTIDAD", "FORMATO"});
        Integer k = 2;
        LOG.info("comenzando a crear archivo");
        for (TransaccionDTO transaccion : transacciones) {
            datos.put(k, new Object[]{transaccion.getPAIS(), transaccion.getID_PROGRAM(), transaccion.getTITULO(),
                transaccion.getMEDIO_PAGO(), transaccion.getABONO(), transaccion.getPRECIO(),
                transaccion.getCANTIDAD(), transaccion.getFORMATO()});
            k++;
        }
        LOG.info(transacciones.size() + " datos recuperados");
        createFile("Transacciones", datos, date, "/home/scm/server/dda/cargaTitulosPN/excel/", Boolean.FALSE);
    }

    public void recuperarVisualizaciones() throws Exception {
        LOG.debug("    - [" + this.getClass().getSimpleName() + "::creando Archivo de Excel para carga]");

        //Por cada línea se crea un arreglo de objetos (Object[])
        Map<Integer, Object[]> datos = new TreeMap<>();
        LOG.info("Recuperando de la base de datos");
        List<VisualizacionDTO> visualizaciones = dao.obtenerVisualizacionesMes(date);
        LOG.info(visualizaciones.size() + " datos recuperados con fecha " + date);
        datos.put(1, new Object[]{"Id Broadview", "Titulo", "Visualizaciones", "Mes"});
        Integer k = 2;
        LOG.info("comenzando a crear archivo");
        for (VisualizacionDTO visualizacion : visualizaciones) {
            datos.put(k, new Object[]{visualizacion.getID_BV(), visualizacion.getTITULO(),
                visualizacion.getVISUALIZACIONES(), visualizacion.getMES_F()});
            k++;
        }

        LOG.info(datos.size() + " datos recuperados");

        createFile("Visualizaciones", datos, date, "/home/scm/server/dda/cargaTitulosVS/excel/", Boolean.TRUE);
    }

    public void getDate() {
        LocalDate localDate = LocalDate.now();
        int year = localDate.getYear();
        int month = localDate.getMonthValue() - 1;
        if (localDate.getMonth() == Month.JANUARY) {
            --year;
            month = 12;
        }
        date = "01/" + "06" + "/" + year;
        dateName = "01/" + "06" + "/" + year;
    }

    public void createFile(String tituloHoja, Map<Integer, Object[]> datos, String date, String ruta, boolean isVisual) {
        //Crear libro de trabajo en blanco
        Workbook workbook = new XSSFWorkbook();
        //Crea hoja nueva
        Sheet sheet = workbook.createSheet(tituloHoja);
        //Iterar sobre datos para escribir en la hoja
        int numeroRenglon = 0;
        for (Integer key : new HashSet<Integer>(datos.keySet())) {
            Row row = sheet.createRow(numeroRenglon++);
            Object[] arregloObjetos = datos.get(key);
            int numeroCelda = 0;
            for (Object obj : arregloObjetos) {
                Cell cell = null;
                if (isVisual && (numeroCelda == 2 || numeroCelda == 3)) {
                    cell = row.createCell(numeroCelda++);
                    cell.setCellType(XSSFCell.CELL_TYPE_NUMERIC);
                } else {
                    cell = row.createCell(numeroCelda++);
                }
                if (obj instanceof String) {
                    cell.setCellValue((String) obj);
                } else if (obj instanceof Integer) {
                    cell.setCellValue((Integer) obj);
                }
            }
        }
        try {
            //Se genera el documento
            LOG.info("Archivo guardado");
            fileName = ruta.concat(dateName.concat(tituloHoja) + ".xlsx");
            //FileOutputStream out = new FileOutputStream(new File(fileName));
            File d = new File(fileName);
            d.setExecutable(true, false);
            d.setReadable(true, false);
            d.setWritable(true, false);
            FileOutputStream out = new FileOutputStream(d);
            workbook.write(out);
            out.close();
            LOG.info("Archivo guardado" + fileName);
            fileName = dateName.concat(tituloHoja) + ".xlsx";

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @return the dao
     */
    public DDACargaTransacVisualDAO getDao() {
        return dao;
    }

    /**
     * @param dao the dao to set
     */
    public void setDao(DDACargaTransacVisualDAO dao) {
        this.dao = dao;
    }

    public void cargarTransacciones() {
        DDARestClient client = new DDARestClient("http://localhost:8080/DDA_WSB_Procesos/services/proceso/procesarCargaTitulosPN");
        ParamCargaTitulosPNDTO request = new ParamCargaTitulosPNDTO();
        LOG.info("Recuperando idCarga");
        String idCarga = dao.obtenerSiguienteIdCarga();
        LOG.info("Registrando idCarga " + idCarga);
        dao.registrarCargaTransaccion(idCarga, date);
        request.setNombreArchivo(fileName);
        request.setExpediente(expediente);
        request.setIdCargaTransacciones(idCarga);
        LOG.info("Cargando transacciones ");
        LOG.info("Request: " + request);
        ResponseCargaTitulosPNDTO response = client.get(request, ResponseCargaTitulosPNDTO.class);
        if (response.getMensaje().equals("OK")) {
            try {
                dao.ejecutarSPAsociarTitTransCntVigentes(idCarga);
                dao.ejecutarCalculoOverage(idCarga);
            } catch (Exception e) {
                LOG.error("Fallo el archivo " + response.getDatosCarga().getARCHIVO_XLSX());
            }
            LOG.info("Transacciones  cargadas " + response.getDatosCarga().getARCHIVO_XLSX());
        } else {
            LOG.error("Fallo el archivo " + response.getDatosCarga().getARCHIVO_XLSX());
        }
    }

    public void cargarVisualizaciones() {
        DDARestClient client = new DDARestClient("http://localhost:8080/DDA_WSB_Procesos/services/proceso/procesarCargaTitulosVS");
        ParamCargaTitulosVSDTO request = new ParamCargaTitulosVSDTO();
        request.setNombreArchivo(fileName);
        request.setExpediente(expediente);
        request.setMesCarga(date);
        LOG.info("Cargando visualizaciones ");
        ResponseCargaTitulosVSDTO response = client.get(request, ResponseCargaTitulosVSDTO.class);
        LOG.info("visualizaciones  cargadas " + response.getDatosCarga().getARCHIVO_XLSX());
    }

}
