package com.rjconsultores.ventaboletos.service.impl;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.zkoss.zul.Comboitem;

import com.rjconsultores.ventaboletos.dao.CorridaTramoDAO;
import com.rjconsultores.ventaboletos.dao.TarjetaViajeDAO;
import com.rjconsultores.ventaboletos.entidad.Corrida;
import com.rjconsultores.ventaboletos.entidad.CorridaTramo;
import com.rjconsultores.ventaboletos.entidad.RhPagoConductor;
import com.rjconsultores.ventaboletos.entidad.TarjetaViaje;
import com.rjconsultores.ventaboletos.service.CorridaService;
import com.rjconsultores.ventaboletos.service.RhPagoConductorService;
import com.rjconsultores.ventaboletos.service.RutaService;
import com.rjconsultores.ventaboletos.service.TarjetaViajeService;
import com.rjconsultores.ventaboletos.utilerias.UsuarioLogado;

@Service("tarjetaViajeService")
public class TarjetaViajeServiceImpl implements TarjetaViajeService {

    @Autowired
    private TarjetaViajeDAO tarjetaViajeDAO;
    @Autowired
    private CorridaTramoDAO corridaTramoDAO;
    @Autowired
    private CorridaService corridaService;
    @Autowired
    private RhPagoConductorService rhPagoConductorService;
    @Autowired
    private RutaService rutaService;
    private static final Logger log = LogManager.getLogger(TarjetaViajeServiceImpl.class);

    @Override
    public List<TarjetaViaje> obtenerTodos() {
        return tarjetaViajeDAO.obtenerTodos();
    }

    @Override
    public TarjetaViaje obtenerID(Integer id) {
        return tarjetaViajeDAO.obtenerID(id);
    }

    @Transactional
    public TarjetaViaje suscribir(TarjetaViaje entidad) {
        entidad.setActivo(true);
        entidad.setFecmodif(Calendar.getInstance().getTime());
        entidad.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
        return tarjetaViajeDAO.suscribir(entidad);
    }

    @Transactional
    public TarjetaViaje actualizacion(TarjetaViaje entidad) {
        entidad.setActivo(true);
        entidad.setFecmodif(Calendar.getInstance().getTime());
        entidad.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
        return tarjetaViajeDAO.actualizacion(entidad);
    }

    @Transactional
    public void borrar(TarjetaViaje entidad) {
        if (entidad.getIndstatustarjeta().equals("M")) {
            tarjetaViajeDAO.borrar(entidad);
        } else {
            entidad.setUsuarioId(UsuarioLogado.getUsuarioLogado().getUsuarioId());
            entidad.setFecmodif(Calendar.getInstance().getTime());
            entidad.setActivo(false);
            entidad.setIndstatustarjeta("B");
            tarjetaViajeDAO.actualizacion(entidad);
        }
    }

    @Transactional
    public void grabarTarjetaViaje(List<CorridaTramo> lsCorridaTramo) {
        try {
            TarjetaViaje tarjeta = null;
            for (CorridaTramo ct : lsCorridaTramo) {

                if (ct.getCorrida() == null) {
                    log.debug("Corrida Tramo sem Corrida: " + ct.getCorridatramoId());
                    continue;
                }

                tarjeta = new TarjetaViaje();
                tarjeta.setActivo(true);
                if (ct.getCorrida().getCorridaRebote() != null) {
                    tarjeta.setIndRebote(1);
                } else {
                    tarjeta.setIndRebote(0);
                }
                tarjeta.setFecenvionomina(null);
                tarjeta.setFecmodif(new Date());
                tarjeta.setFoliotarjetaviaje(ct.getFolioTarjeta() == null ? null : ct.getFolioTarjeta().toString());// checar
                tarjeta.setIndstatustarjeta("N");
                tarjeta.setNumsecuencia(ct.getNumsecuencia() != null ? Integer.getInteger(ct.getNumsecuencia().toString()) : null);
                tarjeta.setUsuarioId(ct.getUsuarioId());
                tarjeta.setAutobus(ct.getAutobus());
                tarjeta.setClaseServicio(ct.getCorrida().getClaseServicio());
                tarjeta.setConductor(ct.getConductor());
                tarjeta.setConductor1(ct.getConductor1());
                tarjeta.setEmpresa(ct.getCorrida().getEmpresa());
                tarjeta.setMarca(ct.getCorrida().getMarca());

                tarjeta.setFecInicial(ct.getCorrida().getId().getFeccorrida());
                tarjeta.setFecHorSalida(ct.getCorrida().getFechorsalida());

                tarjeta.setNumCorrida(ct.getCorrida().getId().getCorridaId());

                BigDecimal kmPagoCondutor = new BigDecimal(BigInteger.ZERO);
                BigDecimal kmReal = new BigDecimal(BigInteger.ZERO);
//                BigDecimal teste = corridaTramoDAO.buscarSumTarjetaMesmaCorrida(ct);
//                tarjeta.setKmPagoConductor(teste);
//                tarjeta.setKmReal(teste);
//
                List<CorridaTramo> lsCorridasAdicionais = corridaTramoDAO.buscarTarjetaMesmaCorrida(ct);
                if (!lsCorridasAdicionais.isEmpty()) {
                    for (CorridaTramo ct2 : lsCorridasAdicionais) {
                        if (ct2.getTramo() == null) {
                            log.debug("Corrida Tramo Sem Tramo: " + ct2.getCorridatramoId().toString());
                            continue;
                        }
                        if (ct2.getTramo().getKmPagoConductor() != null) {

                            log.debug("Corrida Tramo Id: " + ct2.getCorridatramoId().toString());
                            kmPagoCondutor = kmPagoCondutor.add(ct2.getTramo().getKmPagoConductor());
                            kmReal = kmReal.add(ct2.getTramo().getKmReal());
                        }
                    }
                }

                tarjeta.setKmPagoConductor(kmPagoCondutor);
                tarjeta.setKmReal(kmReal);

                //Origem Destino Inicial e Final da Corrida
                Corrida corrida = ct.getCorrida();
                tarjeta.setOrigen(corrida.getOrigem().getCveparada());
                tarjeta.setDestino(corrida.getDestino().getCveparada());

                tarjetaViajeDAO.suscribir(tarjeta);
                ct.setIndmanttarjeta(true);
                corridaTramoDAO.actualizacion(ct);

            }
        } catch (Exception e) {
            log.error("Geracao de Tarjetas");
            log.error(e);
        }
    }

    @Override
    public void verificaCorridaDuplicada(List<TarjetaViaje> lsTarjetaViaje, boolean todasTarjetas) {

        for (TarjetaViaje t : lsTarjetaViaje) {
            List<TarjetaViaje> ls = tarjetaViajeDAO.buscarTarjetaPorFiltros(t);
            if (ls.size() > 1) {
                //Vermelho
                t.seteCorridaDuplicada(true);

                //Esse teste checa se houve uma volta para o autobus/condutor,
                //Se teve volta a TarjetaViaje tem que ser preta
                boolean existeCorridaVolta = tarjetaViajeDAO.buscarTarjetaExisteVolta(t);

                //Se não existe corrida de volta Vermelho
                t.seteCorridaDuplicada(!existeCorridaVolta);
            }
        }

    }

    @Override
    public List<TarjetaViaje> buscarTarjetaPorFiltros(Integer autoIni,
            Integer autoFin, Date dataIni, Date dataFin, Comboitem empresa) {

        return tarjetaViajeDAO.buscarTarjetaPorFiltros(autoIni, autoFin,
                dataIni, dataFin, empresa);
    }

    @Override
    public List<TarjetaViaje> generarArchivoNomina(Date fecIni, Date fecFin) {
        Calendar c = Calendar.getInstance();
        c.setTime(fecFin);
        c.add(Calendar.HOUR, 23);
        c.add(Calendar.MINUTE, 59);
        c.add(Calendar.SECOND, 59);
        fecFin = c.getTime();
        List<TarjetaViaje> lsTarjetas = tarjetaViajeDAO.buscarTarjetasParaEnvioNomina(fecIni, fecFin);

        try {
            for (TarjetaViaje tv : lsTarjetas) {
                RhPagoConductor rh = new RhPagoConductor();

                Corrida.Id id = new Corrida.Id();
                id.setCorridaId(tv.getNumCorrida());
                id.setFeccorrida(tv.getFecInicial());
                Corrida corrida = corridaService.obtenerID(id);

                if (tv.getAutobus() != null) {
                    rh.setNumautobus(Integer.parseInt(tv.getAutobus().getNumautobus()));
                }
                rh.setNumcorrida(tv.getNumCorrida());
                rh.setFechorsalida(tv.getFecHorSalida());

                rh.setCantkmsoperador1(tv.getKmPagoConductor());
                rh.setCantkmsoperador2(tv.getKmPagoConductor());

                if (tv.getConductor() != null) {
                    if (tv.getConductor().getEmpleado() != null) {
                        rh.setCveoperador1(tv.getConductor().getEmpleado().getCveEmpleado());
                        rh.setNombreoperador1(tv.getConductor().getEmpleado().getNombEmpleado());
                    }
                }
                if (tv.getConductor1() != null) {
                    if (tv.getConductor1().getEmpleado() != null) {
                        rh.setCveoperador2(tv.getConductor1().getEmpleado().getCveEmpleado());
                        rh.setNombreoperador2(tv.getConductor1().getEmpleado().getNombEmpleado());
                    }
                }
                if (tv.getMarca() != null) {
                    rh.setMarca(tv.getMarca().getMarcaId());
                }
                if (corrida != null) {
                    if (corrida.getRuta() != null) {
                        rh.setRuta(corrida.getRuta().getRutaId());
                        String descRuta = corrida.getRuta().getDescruta();
                        rh.setDescruta(descRuta.length() > 29 ? descRuta.substring(0, 30) : descRuta);
                        rh.setCveOrigen(rutaService.getOrigem(corrida.getRuta()).getCveparada());
                        rh.setCveDestino(rutaService.getDestino(corrida.getRuta()).getCveparada());
                    }

                    boolean pisoExtra = (corrida.getNumPiso() == null) ? false
                            : corrida.getNumPiso() == 2 ? true : false;
                    rh.setIndextra(pisoExtra);
                }
                log.debug("RH_SALIDAS: NUMAUTOBUS: " + rh.getNumautobus() + " NUMCORRIDA: " + rh.getNumcorrida()
                        + " DESCRUTA: " + rh.getDescruta() + " FECHORSALIDA: " + rh.getFechorsalida()
                        + " CVEOPERADOR1: " + rh.getCveoperador1() + " NOMBREOPERADOR1: " + rh.getNombreoperador1() + " CANTKMSOPERADOR1: " + rh.getCantkmsoperador1()
                        + " CVEOPERADOR2: " + rh.getCveoperador2() + " NOMBREOPERADOR2: " + rh.getNombreoperador2() + " CANTKMSOPERADOR2: " + rh.getCantkmsoperador2()
                        + " INDEXTRA: " + rh.getIndextra() + " CVEORIGEN: " + rh.getCveOrigen() + " CVEDESTINO: " + rh.getCveDestino() + " RUTA_ID: " + rh.getRuta());
                rhPagoConductorService.suscribir(rh);
            }

        } catch (Exception e) {
            log.error(e);
            return null;
        }

        return lsTarjetas;
    }

    @Transactional
    public void actulizarTarjetasEnviadas(List<TarjetaViaje> lsTarjetas) {
        for (TarjetaViaje tarjeta : lsTarjetas) {
            tarjeta.setFecenvionomina(new Date());
            tarjetaViajeDAO.actualizacion(tarjeta);
        }
    }
}
