/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.rjconsultores.ventaboletos.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Set;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.zkoss.util.resource.Labels;

import com.rjconsultores.ventaboletos.dao.RutaCombinacionDAO;
import com.rjconsultores.ventaboletos.entidad.Categoria;
import com.rjconsultores.ventaboletos.entidad.ClaseServicio;
import com.rjconsultores.ventaboletos.entidad.Empresa;
import com.rjconsultores.ventaboletos.entidad.Marca;
import com.rjconsultores.ventaboletos.entidad.Moneda;
import com.rjconsultores.ventaboletos.entidad.OrgaoConcedente;
import com.rjconsultores.ventaboletos.entidad.Parada;
import com.rjconsultores.ventaboletos.entidad.Ruta;
import com.rjconsultores.ventaboletos.entidad.RutaCombinacion;
import com.rjconsultores.ventaboletos.entidad.TipoPuntoVenta;
import com.rjconsultores.ventaboletos.entidad.Tramo;
import com.rjconsultores.ventaboletos.entidad.VigenciaTarifa;
import com.rjconsultores.ventaboletos.service.RutaCombinacionService;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;
import com.rjconsultores.ventaboletos.vo.tarifa.TarifaEscalaGroupVO;
import com.rjconsultores.ventaboletos.vo.tarifa.TarifaEscalaVO;
import com.rjconsultores.ventaboletos.vo.tarifa.TarifaOficialEscalaGroupVO;
import com.rjconsultores.ventaboletos.vo.tarifa.TarifaOficialEscalaVO;

/**
 *
 * @author Rafius
 */
@Service("rutaCombinacionaService")
public class RutaCombinacionServiceImpl implements RutaCombinacionService {

    @Autowired
    private RutaCombinacionDAO rutaCombinacionDAO;
    private static final Logger log = LogManager.getLogger(RutaCombinacionServiceImpl.class);
    private int NUM_LINHA_INICIO = 8;

    public List<RutaCombinacion> obtenerTodos() {
        return rutaCombinacionDAO.obtenerTodos();
    }

    public RutaCombinacion obtenerID(Integer id) {
        return rutaCombinacionDAO.obtenerID(id);
    }

    @Transactional
    public RutaCombinacion suscribir(RutaCombinacion entidad) {
        entidad.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
        entidad.setFecmodif(Calendar.getInstance().getTime());
        entidad.setActivo(Boolean.TRUE);

        return rutaCombinacionDAO.suscribir(entidad);
    }

    @Transactional
    public RutaCombinacion actualizacion(RutaCombinacion entidad) {
        entidad.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
        entidad.setFecmodif(Calendar.getInstance().getTime());
        entidad.setActivo(Boolean.TRUE);

        return rutaCombinacionDAO.actualizacion(entidad);
    }

    @Transactional
    public void borrar(RutaCombinacion entidad) {
        entidad.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
        entidad.setFecmodif(Calendar.getInstance().getTime());
        entidad.setActivo(Boolean.FALSE);

        rutaCombinacionDAO.actualizacion(entidad);
    }

    public boolean busquedaRutaTramo(Ruta ruta, Tramo tramo, Boolean ativo) {
        return rutaCombinacionDAO.busquedaRutaTramo(ruta, tramo, ativo);
    }

    public RutaCombinacion busquedaTramoRutaTramo(Ruta ruta, Tramo trBuscaOrigemDestino) {
        return rutaCombinacionDAO.busquedaTramoRutaTramo(ruta, trBuscaOrigemDestino);
    }

    public void ativar(RutaCombinacion rcExiste) {
        rcExiste.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
        rcExiste.setFecmodif(Calendar.getInstance().getTime());
        rcExiste.setActivo(Boolean.TRUE);

        rutaCombinacionDAO.actualizacion(rcExiste);
    }

    public Tramo busqueda(Ruta ruta, Parada origen, Parada destino) {
        return rutaCombinacionDAO.busqueda(ruta, origen, destino);
    }

    public RutaCombinacion busquedaTramoRutaOrigemDestino(Ruta ruta, Parada origem, Parada destino) {
        return rutaCombinacionDAO.busquedaTramoRutaOrigemDestino(ruta, origem, destino);
    }

    public RutaCombinacion busquedaTramoRutaOrigemDestino(Integer ruta, Integer origemId, Integer destinoId) {
        return rutaCombinacionDAO.busquedaTramoRutaOrigemDestino(ruta, origemId, destinoId);
    }
    
    public List<RutaCombinacion> obtenerPorRuta(Ruta ruta) {
        return rutaCombinacionDAO.obtenerPorRuta(ruta);
    }

    public boolean buscarRutaCombinacionExisteTramo(Tramo tramo) {
        return rutaCombinacionDAO.buscarRutaCombinacionExisteTramo(tramo);
    }

    public int borrarCombinaciones(Ruta ruta) {
        return rutaCombinacionDAO.borrarCombinaciones(ruta);
    }

    @Transactional
    public void activar(Ruta ruta, Tramo trBuscaOrigemDestino) {
        rutaCombinacionDAO.activar(ruta, trBuscaOrigemDestino);
    }

    public HSSFWorkbook gerarTarifaEscala(List<Moneda> lsAddRmvMonedas, List<Marca> lsAddRmvMarcas, List<ClaseServicio> lsAddRmvClaseServico, List<Categoria> lsAddRmvCategoria, List<Empresa> lsAddRmvEmpresas, List<Ruta> lsAddRmvRutas, List<TipoPuntoVenta> lsAddRmvTipoPuntoVenta, List<VigenciaTarifa> lsAddRmvVigenciaTarifa) {

        HSSFWorkbook wb = new HSSFWorkbook();
        // fonte em negrito:
        HSSFFont fonte = wb.createFont();
        fonte.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        HSSFCellStyle estilo = wb.createCellStyle();
        estilo.setFont(fonte);

        //Bucando todas as Linhas com Clase Marca e Moeda Separadamente
        List<TarifaEscalaGroupVO> lsLinhasAgrupadas = rutaCombinacionDAO.pesquisaTarifaGroupObj(lsAddRmvMonedas, lsAddRmvMarcas, lsAddRmvClaseServico,
                lsAddRmvCategoria, lsAddRmvEmpresas, lsAddRmvRutas, lsAddRmvTipoPuntoVenta, lsAddRmvVigenciaTarifa);


        HSSFSheet sheet1 = null;

        int linha = NUM_LINHA_INICIO;
        int linhaAnterior = NUM_LINHA_INICIO;
        int coluna = 0;
        int numAba = 1;

        Object[] rows = new Object[10000];

        TarifaEscalaVO tarAnterior = null;
        for (TarifaEscalaGroupVO teg : lsLinhasAgrupadas) {
            try {

                String descRuta = teg.getDESCRUTA();
                Integer rutaId = teg.getRUTA_ID().intValue();

                //Buscando preços especificos de uma Linha
                List<TarifaEscalaVO> lsTarifaEscala = rutaCombinacionDAO.pesquisaTarifaEscalaObj(rutaId.toString(), teg.getMONEDA_ID().toString(),
                        teg.getVIGENCIATARIFA_ID().toString(), teg.getMARCA_ID().toString());
                //Nome da Aba
                String sheetName = "";
                //Se o nome da ruta for muito grande, tem que cortar para caber no noma da aba com seu ID
                if (descRuta.toString().length() > 22) {
                    sheetName = numAba + " ".concat(descRuta.substring(0, 22).concat(" (").concat(rutaId.toString()).concat(")"));
                } else {
                    sheetName = numAba + " ".concat(descRuta.concat(" (").concat(rutaId.toString()).concat(")"));
                }

                numAba = numAba + 1;
                sheet1 = wb.createSheet(sheetName);
                SimpleDateFormat sf = new SimpleDateFormat("dd/MM/yyyy HH:mm");

                //Montando o Cabeçalho
                HSSFRow r0 = sheet1.createRow(0);
                r0.createCell(0).setCellValue(Labels.getLabel("tarifaEscalaContorller.lhFeciniciovigencia.label"));
                r0.createCell(1).setCellValue(sf.format(teg.getFECINICIOVIGENCIA()) + " - " + sf.format(teg.getFECFINVIGENCIA()));

                HSSFRow r1 = sheet1.createRow(1);
                r1.createCell(0).setCellValue(Labels.getLabel("tarifaEscalaContorller.lhMoneda.label"));
                r1.createCell(1).setCellValue(teg.getDESCMONEDA().toUpperCase());

                HSSFRow r2 = sheet1.createRow(2);
                r2.createCell(0).setCellValue(Labels.getLabel("tarifaEscalaContorller.lhMarca.label"));
                r2.createCell(1).setCellValue(teg.getDESCMARCA().toUpperCase());

                HSSFRow r3 = sheet1.createRow(3);
                r3.createCell(0).setCellValue(Labels.getLabel("tarifaEscalaContorller.lhClaseServicio.label"));
                r3.createCell(1).setCellValue(teg.getDESCCLASE().toUpperCase());

                HSSFRow r4 = sheet1.createRow(4);
                r4.createCell(0).setCellValue(Labels.getLabel("tarifaEscalaContorller.lhRuta.label"));
                r4.createCell(1).setCellValue(descRuta.toUpperCase());

                for (TarifaEscalaVO tar : lsTarifaEscala) {
                    //Primeira Execucao
                    //Crias as Linhas
                    //Coloca o preço do primeiro registro
                    if (linha == NUM_LINHA_INICIO) {
                        for (int i = NUM_LINHA_INICIO; i <= lsTarifaEscala.size() + NUM_LINHA_INICIO; i++) {
                            HSSFRow row = sheet1.createRow(i);
                            rows[i] = row;
                        }

                        HSSFRow rowOrigem = (HSSFRow) rows[linha];
                        //Nome e Descrição
                        rowOrigem.createCell(coluna).setCellValue(tar.getCVEORIGEM());
                        rowOrigem.createCell(coluna + 1).setCellValue(tar.getDESCORIGEM());
                        rows[linha] = rowOrigem;

                        HSSFRow rowPrimeiroPrecio = (HSSFRow) rows[linha + 1];
                        rowPrimeiroPrecio.createCell(coluna).setCellValue(tar.getPRECIO().setScale(2).doubleValue());
                        rows[linha + 1] = rowPrimeiroPrecio;

                        linha = linha + 1;
                        tarAnterior = tar;
                        continue;
                    }

                    //Si mesma origen, se coloca  somente o precio
                    if (tar.getCVEORIGEM().equals(tarAnterior.getCVEORIGEM())) {
                        HSSFRow rowTarifa = (HSSFRow) rows[linha + 1];
                        if (tar.getPRECIO() != null) {
                            rowTarifa.createCell(coluna).setCellValue(tar.getPRECIO().setScale(2).doubleValue());
                        }
                        rows[linha + 1] = rowTarifa;

                        linha = linha + 1;
                    } else {

                        //Se nao mostra proxima Localidade + Preço na linha
                        linhaAnterior = linhaAnterior + 1;
                        linha = linhaAnterior;
                        coluna = coluna + 1;

                        HSSFRow rowOrigem = (HSSFRow) rows[linha];
                        rowOrigem.createCell(coluna).setCellValue(tar.getCVEORIGEM());
                        rowOrigem.createCell(coluna + 1).setCellValue(tar.getDESCORIGEM());
                        rows[linha] = rowOrigem;

                        HSSFRow rowOrigemPrecio = (HSSFRow) rows[linha + 1];
                        rowOrigemPrecio.createCell(coluna).setCellValue(tar.getPRECIO().setScale(2).doubleValue());
                        rows[linha + 1] = rowOrigemPrecio;

                        linha = linha + 1;
                    }
                    tarAnterior = tar;
                }
                //Ultima Execucao Coloca o Destino Final
                HSSFRow rowOrigem = (HSSFRow) rows[linha];
                rowOrigem.createCell(coluna + 1).setCellValue(tarAnterior.getCVEDESTINO());
                rowOrigem.createCell(coluna + 2).setCellValue(tarAnterior.getDESCDESTINO());
                rows[linha] = rowOrigem;
                linha = NUM_LINHA_INICIO;
                linhaAnterior = NUM_LINHA_INICIO;
                coluna = 0;
            } catch (Exception ex) {
                log.error("Exportação Excel Escala: ", ex);
            }
        }

        return wb;
    }

    public HSSFWorkbook gerarTarifaOficialEscala(List<Moneda> lsAddRmvMonedas, List<Marca> lsAddRmvMarcas, List<ClaseServicio> lsAddRmvClaseServico, ArrayList<Categoria> arrayList, List<Empresa> lsAddRmvEmpresas, List<Ruta> lsAddRmvRutas, ArrayList<TipoPuntoVenta> arrayList0, List<VigenciaTarifa> lsAddRmvVigenciaTarifa) {

        HSSFWorkbook wb = new HSSFWorkbook();
        // fonte em negrito:
        HSSFFont fonte = wb.createFont();
        fonte.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        HSSFCellStyle estilo = wb.createCellStyle();
        estilo.setFont(fonte);

        //Bucando todas as Linhas com Clase Marca e Moeda Separadamente
        List<TarifaOficialEscalaGroupVO> lsLinhasAgrupadas = rutaCombinacionDAO.pesquisaTarifaOficialGroupObj(lsAddRmvMonedas, lsAddRmvMarcas, lsAddRmvClaseServico,
                lsAddRmvEmpresas, lsAddRmvRutas, lsAddRmvVigenciaTarifa);
        
        if(lsLinhasAgrupadas == null || lsLinhasAgrupadas.isEmpty()){
        	return null;
        }

        HSSFSheet sheet1 = null;

        int linha = NUM_LINHA_INICIO;
        int linhaAnterior = NUM_LINHA_INICIO;
        int coluna = 0;
        int numAba = 1;

        Object[] rows = new Object[10000];

        TarifaOficialEscalaVO tarAnterior = null;
        for (TarifaOficialEscalaGroupVO teg : lsLinhasAgrupadas) {
            try {

                String descRuta = teg.getDESCRUTA();
                Integer rutaId = teg.getRUTA_ID().intValue();

                //Buscando preços especificos de uma Linha
                List<TarifaOficialEscalaVO> lsTarifaEscala = rutaCombinacionDAO.pesquisaTarifaOficialEscalaObj(rutaId.toString(), teg.getMONEDA_ID().toString(),
                        null, teg.getMARCA_ID().toString());
                //Nome da Aba
                String sheetName = "";
                //Se o nome da ruta for muito grande, tem que cortar para caber no noma da aba com seu ID
                if (descRuta.toString().length() > 22) {
                    sheetName = numAba + " ".concat(descRuta.substring(0, 22).concat(" (").concat(rutaId.toString()).concat(")"));
                } else {
                    sheetName = numAba + " ".concat(descRuta.concat(" (").concat(rutaId.toString()).concat(")"));
                }

                numAba = numAba + 1;
                sheet1 = wb.createSheet(sheetName);
                HSSFRow r1 = sheet1.createRow(1);
                r1.createCell(0).setCellValue(Labels.getLabel("tarifaEscalaContorller.lhMoneda.label"));
                r1.createCell(1).setCellValue(teg.getDESCMONEDA().toUpperCase());

                HSSFRow r2 = sheet1.createRow(2);
                r2.createCell(0).setCellValue(Labels.getLabel("tarifaEscalaContorller.lhMarca.label"));
                r2.createCell(1).setCellValue(teg.getDESCMARCA().toUpperCase());

                HSSFRow r3 = sheet1.createRow(3);
                r3.createCell(0).setCellValue(Labels.getLabel("tarifaEscalaContorller.lhClaseServicio.label"));
                r3.createCell(1).setCellValue(teg.getDESCCLASE().toUpperCase());

                HSSFRow r4 = sheet1.createRow(4);
                r4.createCell(0).setCellValue(Labels.getLabel("tarifaEscalaContorller.lhRuta.label"));
                r4.createCell(1).setCellValue(descRuta.toUpperCase());

                HSSFRow r6 = sheet1.createRow(6);
                r6.createCell(0).setCellValue("Preço - Taxa - Seguro - Pedagio - Outros");


                for (TarifaOficialEscalaVO tar : lsTarifaEscala) {
                    //Primeira Execucao
                    //Crias as Linhas
                    //Coloca o preço do primeiro registro
                    if (linha == NUM_LINHA_INICIO) {
                        for (int i = NUM_LINHA_INICIO; i <= lsTarifaEscala.size() + NUM_LINHA_INICIO; i++) {
                            HSSFRow row = sheet1.createRow(i);
                            rows[i] = row;
                        }

                        HSSFRow rowOrigem = (HSSFRow) rows[linha];
                        //Nome e Descrição
                        rowOrigem.createCell(coluna).setCellValue(tar.getCVEORIGEM());
                        rowOrigem.createCell(coluna + 1).setCellValue(tar.getDESCORIGEM());
                        rows[linha] = rowOrigem;

                        HSSFRow rowPrimeiroPrecio = (HSSFRow) rows[linha + 1];
                        BigDecimal taxa = tar.getTAXAEMBARQUE();
                        BigDecimal segu = tar.getSEGURO();
                        BigDecimal outros = tar.getOUTROS();
                        BigDecimal pedagio = tar.getPEDAGIO();
                        rowPrimeiroPrecio.createCell(coluna).setCellValue(tar.getPRECIO().setScale(2).doubleValue() + " \n"
                                + (taxa == null ? " 0 " : taxa.setScale(2).doubleValue()) + " \n"
                                + (segu == null ? " 0 " : segu.setScale(2).doubleValue()) + " \n"
                                + (pedagio == null ? " 0 " : pedagio.setScale(2).doubleValue()) + " \n"
                                + (outros == null ? " 0 " : outros.setScale(2).doubleValue()));
                        rows[linha + 1] = rowPrimeiroPrecio;

                        linha = linha + 1;
                        tarAnterior = tar;
                        continue;
                    }

                    //Si mesma origen, se coloca  somente o precio
                    if (tar.getCVEORIGEM().equals(tarAnterior.getCVEORIGEM())) {
                        HSSFRow rowTarifa = (HSSFRow) rows[linha + 1];
                        if (tar.getPRECIO() != null) {
                            rowTarifa.createCell(coluna).setCellValue(tar.getPRECIO().setScale(2).doubleValue());
                        }
                        rows[linha + 1] = rowTarifa;

                        linha = linha + 1;
                    } else {

                        //Se nao mostra proxima Localidade + Preço na linha
                        linhaAnterior = linhaAnterior + 1;
                        linha = linhaAnterior;
                        coluna = coluna + 1;

                        HSSFRow rowOrigem = (HSSFRow) rows[linha];
                        rowOrigem.createCell(coluna).setCellValue(tar.getCVEORIGEM());
                        rowOrigem.createCell(coluna + 1).setCellValue(tar.getDESCORIGEM());
                        rows[linha] = rowOrigem;

                        HSSFRow rowOrigemPrecio = (HSSFRow) rows[linha + 1];
                        BigDecimal taxa = tar.getTAXAEMBARQUE();
                        BigDecimal segu = tar.getSEGURO();
                        BigDecimal pedagio = tar.getPEDAGIO();
                        BigDecimal outros = tar.getOUTROS();
                        rowOrigemPrecio.createCell(coluna).setCellValue(tar.getPRECIO().setScale(2).doubleValue() + " \n"
                                + (taxa == null ? " 0 " : taxa.setScale(2).doubleValue()) + " \n"
                                + (segu == null ? " 0 " : segu.setScale(2).doubleValue()) + " \n"
                                + (pedagio == null ? " 0 " : pedagio.setScale(2).doubleValue()) + " \n"
                                + (outros == null ? " 0 " : outros.setScale(2).doubleValue()));
                        rows[linha + 1] = rowOrigemPrecio;

                        linha = linha + 1;
                    }
                    tarAnterior = tar;
                }
                //Ultima Execucao Coloca o Destino Final
                HSSFRow rowOrigem = (HSSFRow) rows[linha];
                rowOrigem.createCell(coluna + 1).setCellValue(tarAnterior.getCVEDESTINO());
                rowOrigem.createCell(coluna + 2).setCellValue(tarAnterior.getDESCDESTINO());
                rows[linha] = rowOrigem;
                linha = NUM_LINHA_INICIO;
                linhaAnterior = NUM_LINHA_INICIO;
                coluna = 0;
            } catch (Exception ex) {
                log.error("Exportação Excel Escala: ", ex);
            }
        }

        return wb;
    }

    public List<Object> pesquisaTarifaObj(List<Moneda> lsAddRmvMonedas, List<Marca> lsAddRmvMarcas,
            List<ClaseServicio> lsAddRmvClaseServico, List<Categoria> lsAddRmvCategoria,
            List<Empresa> lsAddRmvEmpresas, List<Ruta> lsAddRmvRutas,
            List<TipoPuntoVenta> lsAddRmvTipoPuntoVenta, List<VigenciaTarifa> lsAddRmvVigenciaTarifa, List<OrgaoConcedente> lsAddRmvOrgaoConcedente) {
        return rutaCombinacionDAO.pesquisaTarifaObj(lsAddRmvMonedas, lsAddRmvMarcas, lsAddRmvClaseServico,
                lsAddRmvCategoria, lsAddRmvEmpresas, lsAddRmvRutas, lsAddRmvTipoPuntoVenta, lsAddRmvVigenciaTarifa, lsAddRmvOrgaoConcedente);
    }
    
    public List<Object> pesquisaTarifaEmbObj(List<Moneda> lsAddRmvMonedas, List<Marca> lsAddRmvMarcas,
            List<ClaseServicio> lsAddRmvClaseServico, List<Categoria> lsAddRmvCategoria,
            List<Empresa> lsAddRmvEmpresas, List<Ruta> lsAddRmvRutas,
            List<TipoPuntoVenta> lsAddRmvTipoPuntoVenta, List<VigenciaTarifa> lsAddRmvVigenciaTarifa, List<OrgaoConcedente> lsAddRmvOrgaoConcedente) {
        return rutaCombinacionDAO.pesquisaTarifaEmbObj(lsAddRmvMonedas, lsAddRmvMarcas, lsAddRmvClaseServico,
                lsAddRmvCategoria, lsAddRmvEmpresas, lsAddRmvRutas, lsAddRmvTipoPuntoVenta, lsAddRmvVigenciaTarifa, lsAddRmvOrgaoConcedente);
    }

    public List<Object> pesquisaTarifaOficialObj(List<Moneda> lsAddRmvMonedas, List<Marca> lsAddRmvMarcas, List<ClaseServicio> lsAddRmvClaseServico, ArrayList<Categoria> arrayList, List<Empresa> lsAddRmvEmpresas, List<Ruta> lsAddRmvRutas, ArrayList<TipoPuntoVenta> arrayList0, List<VigenciaTarifa> lsAddRmvVigenciaTarifa) {
        return rutaCombinacionDAO.pesquisaTarifaOficialObj(lsAddRmvMonedas, lsAddRmvMarcas, lsAddRmvClaseServico,
                lsAddRmvEmpresas, lsAddRmvRutas, lsAddRmvVigenciaTarifa);
    }

	@Override
	public boolean existeTramo(Tramo tramo) {
		return rutaCombinacionDAO.existeTramo(tramo);
	}

	@Override
	public boolean isRutaCombinacionVenda(Integer rutaId, Integer origenId, Integer destinoId) {
		return rutaCombinacionDAO.isRutaCombinacionVenda(rutaId, origenId, destinoId);
	}

	@Override	
	public Set<String> rutasCombinacionVenda(List<Ruta> rutas) {
		return rutaCombinacionDAO.rutasCombinacionVenda(rutas);
	}
}
