package com.mx.dla.dda.admin.catalogos.addons.bos;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.executor.result.ResultMapException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;

import com.mx.dla.dda.admin.catalogos.addons.dtos.EstudioAddonDTO;
import com.mx.dla.dda.admin.catalogos.addons.dtos.ReporteAddonDTO;
import com.mx.dla.dda.admin.catalogos.estudios.daos.CatalogoEstudiosDAO;
import com.mx.dla.dda.contrato.transaccion.exceptions.dtos.TransaccionException;
import com.mx.dla.dda.excelMapper.bos.ExcelMapperTransform;
import com.mx.dla.dda.excelMapper.context.ExcelMapperContext;
import com.mx.dla.dda.excelMapper.dtos.ExcelMapper;
import com.mx.dla.dda.reporte.pago.daos.ReportePagoAlternoDAO;
import com.mx.dla.dda.reporte.pago.dtos.ReporteAddOnRowDTO;
import com.mx.dla.global.bos.BaseBO;

@Component
public class ReporteAddOnsBO extends BaseBO {

	@Autowired
	private ReportePagoAlternoDAO reportePagoAlterno;
		
	@Autowired
	private CatalogoEstudiosDAO estudiosDao;
	
	@Autowired
	protected ExcelMapperTransform excelMapperTransform;

	@Autowired
	private ExcelMapperContext excelMapperContext;

	public InputStream obtenerReporteEnExcel(String estudioName, String mes) {

		byte[] info = null;
		InputStream reporte = null;
		List<ReporteAddOnRowDTO> lReporte = null;
		Long idEstudio= Long.parseLong(estudioName);
		String tipoReporte = "";

		// setEncabezado(ReporteSuscriptoresBO.obtenerEncabezadoCA());
		SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yyyy");
		Date fechaInicio = null;
		try {
			fechaInicio = formato.parse("01/"+mes);
		} catch (ParseException e) {
		// // TODO Auto-generated catch block
		e.printStackTrace();
		}
		
		try {
			
			logger.debug("antes de reporte");
			EstudioAddonDTO estudio = estudiosDao.catalogoEstudiosAddOnById(idEstudio);
			
			ReporteAddonDTO report = estudiosDao.getTiposReporteById(estudio.getIdReporte());
			logger.info("Reporte Recuperado de BD : " + report.getDescFormula());
			switch(report.getFormula()) {
			case "A": 
				lReporte = reportePagoAlterno.obtenerReporteGeneral(fechaInicio, idEstudio, "'MEXICO'");
				lReporte.addAll(reportePagoAlterno.obtenerReporteGeneralMexico(fechaInicio, idEstudio));
				agregarTotales(lReporte);
				break;
			case "B":
			case "C": 
				lReporte = reportePagoAlterno.obtenerReporteGeneral(fechaInicio, idEstudio, "'TODOS'");
				agregarTotales(lReporte);
				break;
			case "D": 
				lReporte = reportePagoAlterno.obtenerReporteFoxGeneral(fechaInicio, idEstudio);
				agregarTotales(lReporte);
				break;
			case "E": 
				lReporte = reportePagoAlterno.obtenerReporteKaraokeQello(fechaInicio, idEstudio,"'TODOS'");
				agregarTotales(lReporte);
				break;
			default: logger.error("Reporte no reconocido: " + report.getDescFormula());
			}
			
			logger.debug("Regresando reporte");
		}catch(Exception ex){
			logger.error("[{}]", ex);
			logger.debug("No regresa reporte ");
		}

		
		if(Objects.nonNull(lReporte) && !lReporte.isEmpty()){
			tipoReporte = lReporte.get(0).getM2();
		} 
		logger.info("Tipo reporte: " + tipoReporte);
		
		ExcelMapper mapper = null;
		
		switch (tipoReporte) {
		case "1":
			mapper = excelMapperContext.getExcelMapper("addonsRepo1");
			break;
		case "2":
			mapper = excelMapperContext.getExcelMapper("addonsRepo2");
			break;
		case "3":
			mapper = excelMapperContext.getExcelMapper("addonsRepo3");
			break;
		case "4":
			mapper = excelMapperContext.getExcelMapper("addonsRepo4");
			break;
		case "5":
			mapper = excelMapperContext.getExcelMapper("addonsRepo5");
			break;

		default:
			break;
		}
		
		try{

			info = excelMapperTransform.transformObjectToExcel(lReporte, mapper, ReporteAddOnRowDTO.class);
			reporte = new ByteArrayInputStream(info);
		}catch(Exception e){
			logger.error("Error : " + e);
		}
		return reporte;
	}
	
	public void agregarTotales(List<ReporteAddOnRowDTO> reporte) {
		ReporteAddOnRowDTO totales = new ReporteAddOnRowDTO();
		Double f2 = 0.0;
		Double fd1 = 0.0;
		Double m19 = 0.0;
		for (ReporteAddOnRowDTO r : reporte) {
			f2 = f2 + Double.parseDouble(r.getF2());
			fd1 = fd1 + Double.parseDouble(r.getFd1());
			m19 = m19 + Double.parseDouble(r.getM19());
		}
		totales.setF2(BigDecimal.valueOf(f2).setScale(2, RoundingMode.HALF_UP).toString());
		totales.setFd1(BigDecimal.valueOf(fd1).setScale(2, RoundingMode.HALF_UP).toString());
		totales.setM19(BigDecimal.valueOf(m19).setScale(2, RoundingMode.HALF_UP).toString());
		totales.setM5("Totales: ");
		reporte.add(totales);
	}

	public String obtenerNombreEstudio(String idEstudio){
		
		EstudioAddonDTO estudio = estudiosDao.catalogoEstudiosAddOnById(Long.parseLong(idEstudio));
		
		return !Objects.isNull(estudio)?estudio.getNombre():"";
	}
	
	public List<ReporteAddonDTO> getTiposReporte(String id) throws ResultMapException, SQLException, TransaccionException {
        try {
        	List<ReporteAddonDTO> reportes = new ArrayList<ReporteAddonDTO>();
    		if (id.isEmpty()) {
    			return estudiosDao.getTiposReporte();
    		} else {
    			reportes.add(estudiosDao.getTiposReporteById(id));
    			return reportes;
    		}
        } catch (PersistenceException e) {
            throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
        } catch (DataAccessException e) {
            throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
        }

    }
}
