// ------------------------------------------------------------------------------------
// <copyright file="EstadosDAL.cs" company="Universidad Distrital">
// Copyright (c) Universidad Distrital. All rights reserved.
// </copyright>
// <author>Camilo Prieto</author>
// ------------------------------------------------------------------------------------
namespace Biblioteca.Datos.Clases.DAL.Repositorio
{
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Linq.Expressions;
	using System.Threading.Tasks;
	using Biblioteca.Datos.Contexto;
	using Biblioteca.Datos.Contexto.Repositorio;
	using Biblioteca.IC.Acciones.Repositorio;
	using Biblioteca.IC.DTO.Repositorio;
	using TransaccionalNet.EF.Clases;
	using UtilitariosNet.Clases.Comunes.Entidades;
	using UtilitariosNet.Clases.Mapeador.Extensiones;

	/// <summary>
	/// Clase con las acciones de repositorio para la entidad Estados
	/// </summary>
	public class EstadosDAL : AccesoComunDAL<ContextoBiblioteca>, IEstadosRepositorioAccion
	{
		/// <summary>
		/// Objeto para entidad respuesta
		/// </summary>
		Respuesta<IEstadosDTO> respuesta;

		/// <summary>
		/// Objeto para repositorio Estados
		/// </summary>
		RepositorioGenerico<Estados> repositorio;

		/// <summary>
		/// Inicializa una nueva instancia de la clase EstadosDAL
		/// </summary>
		public EstadosDAL()
		{
			this.respuesta = new Respuesta<IEstadosDTO>();
			this.repositorio = new RepositorioGenerico<Estados>(ContextoBD);
		}

		/// <summary>
		/// Metodo editar estados
		/// </summary>
		/// <param name="estados">Entidad a editar</param>
		/// <returns>Respuesta tipo Estados </returns>
		public async Task<Respuesta<IEstadosDTO>> EditarEstadosAsync(IEstadosDTO estados)
		{
			return await this.EjecutarTransaccionAsync<Respuesta<IEstadosDTO>, EstadosDAL>(async () =>
			{
				Estados EstadosEntidad = repositorio.BuscarPor(entidad => entidad
					.IdEstado == estados.IdEstado).FirstOrDefault();
				Mapeador.MapearObjetosPorPropiedad(estados, EstadosEntidad);
				repositorio.Editar(EstadosEntidad);
				repositorio.Guardar();
				return respuesta;
			});
		}

		/// <summary>
		/// Metodo editar  estados por filtro 
		/// </summary>
		/// <param name="estados">Entidad con los datos a editar</param>
		/// <param name="propiedades">Propiedades a modificar</param>
		/// <returns>Respuesta tipo Estados </returns>
		public async Task<Respuesta<IEstadosDTO>> EditarEstadosPorFiltroAsync(IEstadosDTO estados, params string[] propiedades)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IEstadosDTO>, EstadosDAL>(async () =>
            {
                Estados estadosEntidad = repositorio.BuscarPor(entidad => entidad
                .IdEstado == estados.IdEstado).FirstOrDefault();
                Mapeador.MapearObjetosPorPropiedadPorFiltro(estados, estadosEntidad, propiedades);
                repositorio.Editar(estadosEntidad);
                      repositorio.Guardar();
                return respuesta;
            });
        }


		/// <summary>
		/// Metodo editar estados por query 
		/// </summary>
		/// <param name="filtro">Filtro de las entidades </param>
		/// <param name="valor">Entidad a mofificar</param>
		/// <param name="propiedades">Propiedades a modificar</param>
		/// <returns>Respuesta tipo Estados </returns>
		public async Task<Respuesta<IEstadosDTO>> EditarPorQueryEstadosAsync(Expression<Func<IEstadosDTO, bool>> filtro, IEstadosDTO valor, List<string> propiedades)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IEstadosDTO>, EstadosDAL>(async () =>
            {
          Estados EstadosEntidad = Mapeador.MapearEntidadDTO(valor, new Estados());
                Expression<Func<Estados, bool>> filtros = Mapeador.MapearExpresion<IEstadosDTO, Estados>(filtro);
                await repositorio.EditarPorQueryAsync(filtros, EstadosEntidad, propiedades);
                await repositorio.GuardarAsync();
                return respuesta;
            });
        }


		/// <summary>
		/// Metodo editar estados lista 
		/// </summary>
		/// <param name="lista"> Lista con entidades a modificar</param>
		/// <returns>Respuesta tipo Estados </returns>
		public async Task<Respuesta<IEstadosDTO>> EditarListaEstadosAsync(List<IEstadosDTO> lista)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IEstadosDTO>, EstadosDAL>(async () =>
            {
                List<Estados> listaEstados = new List<Estados>();
                listaEstados = Mapeador.MapearALista<IEstadosDTO, Estados>(lista);
               await repositorio.EditarListaAsync(listaEstados);
               await repositorio.GuardarAsync();
                return respuesta;
            });
        }

		/// <summary>
		/// Metodo eliminar estados
		/// </summary>
		/// <param name="estados">Entidad a eliminar</param>
		/// <returns>Respuesta tipo Estados </returns>
        public async Task<Respuesta<IEstadosDTO>> EliminarEstadosAsync(IEstadosDTO estados)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IEstadosDTO>, EstadosDAL>(async () =>
            {
				Estados EstadosEntidad = repositorio.BuscarPor(entidad => entidad
					.IdEstado == estados.IdEstado).FirstOrDefault();
				Mapeador.MapearObjetosPorPropiedad(estados, EstadosEntidad);
				repositorio.Eliminar(EstadosEntidad);
                repositorio.Guardar();
                return respuesta;
            });
        }


		/// <summary>
		/// Metodo eliminar lista estados 
		/// </summary>
		/// <param name="lista">Lista de entidad a eliminar</param>
		/// <returns>Respuesta tipo Estados </returns>
        public async Task<Respuesta<IEstadosDTO>> EliminarListaEstadosAsync(List<IEstadosDTO> lista)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IEstadosDTO>, EstadosDAL>(async () =>
            {
                List<Estados> listaEstados = new List<Estados>();
                listaEstados = Mapeador.MapearALista<IEstadosDTO, Estados>(lista);
               await repositorio.EliminarListaAsync(listaEstados);
               await repositorio.GuardarAsync();
                return respuesta;
            });
        }

		/// <summary>
		/// Metodo guardar estados
		/// </summary>
		/// <param name="estados">Entidad a guardar</param>
		/// <returns>Respuesta tipo Estados </returns>
        public async Task<Respuesta<IEstadosDTO>> GuardarEstadosAsync(IEstadosDTO estados)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IEstadosDTO>, EstadosDAL>(async () =>
            {
                Estados EstadosEntidad = Mapeador.MapearEntidadDTO(estados, new Estados());
               await repositorio.AgregarAsync(EstadosEntidad);
               await repositorio.GuardarAsync();
                respuesta.Entidades.Add(EstadosEntidad);
                return respuesta;

            });
        }

		/// <summary>
		/// Metodo Guardar lista estados
		/// </summary>
		/// <param name="listaEstados">Lista de entidades a guardar</param>
		/// <returns>Respuesta tipo Estados </returns>
        public async Task<Respuesta<IEstadosDTO>> GuardarListaEstadosAsync(List<IEstadosDTO> listaEstados)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IEstadosDTO>, EstadosDAL>(async () =>
            {
                List<Estados> listaEstadosEntidad = Mapeador.MapearALista<IEstadosDTO, Estados>(listaEstados);
               await repositorio.AgregarListaAsync(listaEstadosEntidad);
                respuesta.Entidades.AddRange(listaEstadosEntidad);
                return respuesta;
            });
        }

		/// <summary>
		/// Metodo consultar lista estados
		/// </summary>
		/// <returns>Respuesta tipo Estados </returns>
        public async Task<Respuesta<IEstadosDTO>> ConsultarListaEstadosAsync()
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IEstadosDTO>, EstadosDAL>(async () =>
            {
                respuesta.Entidades = repositorio.BuscarTodos().ToList<IEstadosDTO>();
                return respuesta;

            });
        }

		/// <summary>
		/// Metodo consultar lista estados por filtro 
		/// </summary>
		/// <param name="estados">Entidad con los datos a filtrar</param>
		/// <param name="filtro">Filtro de las entidades </param>
		/// <returns>Respuesta tipo Estados </returns>
        public async Task<Respuesta<IEstadosDTO>> ConsultarListaEstadosPorFiltroAsync(Expression<Func<IEstadosDTO, bool>> filtro)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IEstadosDTO>, EstadosDAL>(async () =>
            {
                respuesta.Entidades = repositorio.BuscarPor(Mapeador.MapearExpresion<IEstadosDTO, Estados>(filtro)).ToList<IEstadosDTO>();
                return respuesta;

            });
        }

		/// <summary>
		/// Metodo consultar por llave estados
		/// </summary>
		/// <param name="estados">Entidad a consultar</param>
		/// <returns>Respuesta tipo Estados </returns>
        public async Task<Respuesta<IEstadosDTO>> ConsultarEstadosLlaveAsync(IEstadosDTO estados)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IEstadosDTO>, EstadosDAL>(async () =>
            {
                respuesta.Entidades = (from entidad in ContextoBD.Estados
                                       where entidad.IdEstado == estados.IdEstado
                                       select entidad).ToList<IEstadosDTO>();

                return respuesta;

            });
        }
    }
}

