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

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

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

import com.mx.dla.dda.admin.catalogos.apartados.daos.ApartadosDAO;
import com.mx.dla.dda.contrato.excepcion.SuscriptorException;
import com.mx.dla.dda.contrato.generales.dtos.ApartadoDTO;
import com.mx.dla.dda.contrato.transaccion.exceptions.dtos.TransaccionException;
import com.mx.dla.dda.contrato.ws.dtos.DTOrdenInterna;
import com.mx.dla.dda.ordenesinternas.dtos.OrdenesInternasDTO;
import com.mx.dla.dda.restClient.bos.DLARestClient;
import com.mx.dla.dda.restClient.bos.DLARestClientFactory;
import com.mx.dla.dda.restClient.constants.DLARestServices;
import com.mx.dla.global.bos.BaseBO;

@Service
public class ApartadosBO extends BaseBO {

	@Autowired
	private DLARestClientFactory dlaRestClientFactory;

	@Autowired
	private ApartadosDAO apartadosDAO;

	@Value("${ordenInterna.centroCostos}")
	private String centroCostosOrdInt;

	@Value("${ordenInterna.sociedad}")
	private String sociedadOrdInt;

	public List<ApartadoDTO> selectBusquedaApartados(String operacion)
			throws ResultMapException, SQLException, TransaccionException {
		List<ApartadoDTO> apartados = null;
		try {
			if (operacion.compareTo("Amortizable") == 0 || operacion.compareTo("No Amortizable") == 0)
				apartados = apartadosDAO.getApartadosXAmortizable(operacion);
			else
				apartados = apartadosDAO.getApartados();
			return apartados;
		} 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);
		}
	}

	public List<ApartadoDTO> getApartados() {
		return apartadosDAO.getApartados();
	}

	public String generarApartado(String des, String id, String amortizable) throws ResultMapException, SQLException,
			TransaccionException, SuscriptorException, SocketTimeoutException, IOException {
		try {
			String mensaje = "";

			if (id.compareTo("null") == 0) // crea apartado
			{
				Long idA = apartadosDAO.obtenerApartadoExistente(amortizable, des);

				if (idA == null) {
					ApartadoDTO apartado = new ApartadoDTO(des, amortizable);
					apartadosDAO.guardarApartado(apartado, 1);
					mensaje = apartado.getIdApartado().toString();

					if (amortizable.compareTo("Amortizable") == 0) {
						notificarApartadoNoAmortizablesSAP(apartado);
						if (apartado.getIdSap() == null) {
							apartadosDAO.eliminarApartado(apartado.getIdApartado());
							throw new SuscriptorException("No se ha podido guardar el apartado a SAP");
						} else if (apartado.getIdSap().compareTo("0") == 0) {
							apartadosDAO.eliminarApartado(apartado.getIdApartado());
							throw new SuscriptorException("No se ha podido notificar el apartado a SAP");
						}
					}
				} else {
					throw new SuscriptorException("No se ha podido guardar el apartado, ya existe.");
				}
			} else // editar apartado
			{
				logger.debug("edita apartado");
				ApartadoDTO apartado = new ApartadoDTO(Long.parseLong(id), des, amortizable);
				apartadosDAO.editarApartado(apartado);
				mensaje = "Se ha actualizado el apartado.";
			}
			return mensaje;

		} 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);
		}
	}

	public void notificarApartadoNoAmortizablesSAP(ApartadoDTO apartado)
			throws ResultMapException, SQLException, TransaccionException, SocketTimeoutException, IOException {

		DTOrdenInterna dTOrdenInterna = new DTOrdenInterna();
		OrdenesInternasDTO ordenesInternasDTO = new OrdenesInternasDTO();

		DTOrdenInterna.Registro registro = new DTOrdenInterna.Registro();
		List<DTOrdenInterna.Registro> registros = new ArrayList<DTOrdenInterna.Registro>();

		registro.setIDDDA(String.valueOf(apartado.getIdApartado()));
		registro.setDescripcion(apartado.getDescripcion());
		registro.setSociedad(sociedadOrdInt);
		registro.setCentroCostos(centroCostosOrdInt);
		registros.add(registro);

		dTOrdenInterna.setRegistro(registros);

		try {
			logger.info("Se llama al servicio ORDENAS_INTERNAS #3");
			logger.info("IDDA: {}, DESCRIPCION: {}, SOCIEDAD: NT07, CENTROCOSTO: 07A01US602", apartado.getIdApartado(),
					apartado.getDescripcion());

			DLARestClient c = dlaRestClientFactory.getClient(DLARestServices.ORDENES_INTERNAS);
			logger.info("url {}", c.getUri());
			ordenesInternasDTO = c.get(dTOrdenInterna, OrdenesInternasDTO.class);

			logger.info("Respuesta servicio id_sap:{}, estatus:{}", ordenesInternasDTO.getR_id_sap(),
					ordenesInternasDTO.getEstatus_dda());

			if (ordenesInternasDTO.getR_id_sap() == null || ordenesInternasDTO.getR_id_sap().trim().isEmpty())
				throw new SuscriptorException("La respuesta de SAP envio un id SAP nulo o vacio");

			apartado.setIdSap(ordenesInternasDTO.getR_id_sap());
			apartadosDAO.editarSAP(apartado);

		} catch (PersistenceException e) {
			logger.error("ERROR ", e);
			logger.error("CAUSA ", e.getCause());
			apartadosDAO.eliminarApartado(apartado.getIdApartado());
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (DataAccessException e) {
			logger.error("ERROR ", e);
			logger.error("CAUSA ", e.getCause());
			apartadosDAO.eliminarApartado(apartado.getIdApartado());
			throw new TransaccionException("Error al cargar los datos de actualizacion " + e);
		} catch (SuscriptorException e) {
			logger.error("ERROR ", e);
			logger.error("CAUSA ", e.getCause());
			apartadosDAO.eliminarApartado(apartado.getIdApartado());
		}
	}
}