// ------------------------------------------------------------------------------------
// <copyright file="CiudadesDAL.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 Ciudades
	/// </summary>
	public class CiudadesDAL : AccesoComunDAL<ContextoBiblioteca>, ICiudadesRepositorioAccion
	{
		/// <summary>
		/// Objeto para entidad respuesta
		/// </summary>
		Respuesta<ICiudadesDTO> respuesta;

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

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

		/// <summary>
		/// Metodo editar ciudades
		/// </summary>
		/// <param name="ciudades">Entidad a editar</param>
		/// <returns>Respuesta tipo Ciudades </returns>
		public async Task<Respuesta<ICiudadesDTO>> EditarCiudadesAsync(ICiudadesDTO ciudades)
		{
			return await this.EjecutarTransaccionAsync<Respuesta<ICiudadesDTO>, CiudadesDAL>(async () =>
			{
				Ciudades CiudadesEntidad = repositorio.BuscarPor(entidad => entidad
					.IdCiudad == ciudades.IdCiudad).FirstOrDefault();
				Mapeador.MapearObjetosPorPropiedad(ciudades, CiudadesEntidad);
				repositorio.Editar(CiudadesEntidad);
				repositorio.Guardar();
				return respuesta;
			});
		}

		/// <summary>
		/// Metodo editar  ciudades por filtro 
		/// </summary>
		/// <param name="ciudades">Entidad con los datos a editar</param>
		/// <param name="propiedades">Propiedades a modificar</param>
		/// <returns>Respuesta tipo Ciudades </returns>
		public async Task<Respuesta<ICiudadesDTO>> EditarCiudadesPorFiltroAsync(ICiudadesDTO ciudades, params string[] propiedades)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<ICiudadesDTO>, CiudadesDAL>(async () =>
            {
                Ciudades ciudadesEntidad = repositorio.BuscarPor(entidad => entidad
                .IdCiudad == ciudades.IdCiudad).FirstOrDefault();
                Mapeador.MapearObjetosPorPropiedadPorFiltro(ciudades, ciudadesEntidad, propiedades);
                repositorio.Editar(ciudadesEntidad);
                      repositorio.Guardar();
                return respuesta;
            });
        }


		/// <summary>
		/// Metodo editar ciudades 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 Ciudades </returns>
		public async Task<Respuesta<ICiudadesDTO>> EditarPorQueryCiudadesAsync(Expression<Func<ICiudadesDTO, bool>> filtro, ICiudadesDTO valor, List<string> propiedades)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<ICiudadesDTO>, CiudadesDAL>(async () =>
            {
          Ciudades CiudadesEntidad = Mapeador.MapearEntidadDTO(valor, new Ciudades());
                Expression<Func<Ciudades, bool>> filtros = Mapeador.MapearExpresion<ICiudadesDTO, Ciudades>(filtro);
                await repositorio.EditarPorQueryAsync(filtros, CiudadesEntidad, propiedades);
                await repositorio.GuardarAsync();
                return respuesta;
            });
        }


		/// <summary>
		/// Metodo editar ciudades lista 
		/// </summary>
		/// <param name="lista"> Lista con entidades a modificar</param>
		/// <returns>Respuesta tipo Ciudades </returns>
		public async Task<Respuesta<ICiudadesDTO>> EditarListaCiudadesAsync(List<ICiudadesDTO> lista)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<ICiudadesDTO>, CiudadesDAL>(async () =>
            {
                List<Ciudades> listaCiudades = new List<Ciudades>();
                listaCiudades = Mapeador.MapearALista<ICiudadesDTO, Ciudades>(lista);
               await repositorio.EditarListaAsync(listaCiudades);
               await repositorio.GuardarAsync();
                return respuesta;
            });
        }

		/// <summary>
		/// Metodo eliminar ciudades
		/// </summary>
		/// <param name="ciudades">Entidad a eliminar</param>
		/// <returns>Respuesta tipo Ciudades </returns>
        public async Task<Respuesta<ICiudadesDTO>> EliminarCiudadesAsync(ICiudadesDTO ciudades)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<ICiudadesDTO>, CiudadesDAL>(async () =>
            {
				Ciudades CiudadesEntidad = repositorio.BuscarPor(entidad => entidad
					.IdCiudad == ciudades.IdCiudad).FirstOrDefault();
				Mapeador.MapearObjetosPorPropiedad(ciudades, CiudadesEntidad);
				repositorio.Eliminar(CiudadesEntidad);
                repositorio.Guardar();
                return respuesta;
            });
        }


		/// <summary>
		/// Metodo eliminar lista ciudades 
		/// </summary>
		/// <param name="lista">Lista de entidad a eliminar</param>
		/// <returns>Respuesta tipo Ciudades </returns>
        public async Task<Respuesta<ICiudadesDTO>> EliminarListaCiudadesAsync(List<ICiudadesDTO> lista)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<ICiudadesDTO>, CiudadesDAL>(async () =>
            {
                List<Ciudades> listaCiudades = new List<Ciudades>();
                listaCiudades = Mapeador.MapearALista<ICiudadesDTO, Ciudades>(lista);
               await repositorio.EliminarListaAsync(listaCiudades);
               await repositorio.GuardarAsync();
                return respuesta;
            });
        }

		/// <summary>
		/// Metodo guardar ciudades
		/// </summary>
		/// <param name="ciudades">Entidad a guardar</param>
		/// <returns>Respuesta tipo Ciudades </returns>
        public async Task<Respuesta<ICiudadesDTO>> GuardarCiudadesAsync(ICiudadesDTO ciudades)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<ICiudadesDTO>, CiudadesDAL>(async () =>
            {
                Ciudades CiudadesEntidad = Mapeador.MapearEntidadDTO(ciudades, new Ciudades());
               await repositorio.AgregarAsync(CiudadesEntidad);
               await repositorio.GuardarAsync();
                respuesta.Entidades.Add(CiudadesEntidad);
                return respuesta;

            });
        }

		/// <summary>
		/// Metodo Guardar lista ciudades
		/// </summary>
		/// <param name="listaCiudades">Lista de entidades a guardar</param>
		/// <returns>Respuesta tipo Ciudades </returns>
        public async Task<Respuesta<ICiudadesDTO>> GuardarListaCiudadesAsync(List<ICiudadesDTO> listaCiudades)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<ICiudadesDTO>, CiudadesDAL>(async () =>
            {
                List<Ciudades> listaCiudadesEntidad = Mapeador.MapearALista<ICiudadesDTO, Ciudades>(listaCiudades);
               await repositorio.AgregarListaAsync(listaCiudadesEntidad);
                respuesta.Entidades.AddRange(listaCiudadesEntidad);
                return respuesta;
            });
        }

		/// <summary>
		/// Metodo consultar lista ciudades
		/// </summary>
		/// <returns>Respuesta tipo Ciudades </returns>
        public async Task<Respuesta<ICiudadesDTO>> ConsultarListaCiudadesAsync()
        {
            return await this.EjecutarTransaccionAsync<Respuesta<ICiudadesDTO>, CiudadesDAL>(async () =>
            {
                respuesta.Entidades = repositorio.BuscarTodos().ToList<ICiudadesDTO>();
                return respuesta;

            });
        }

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

            });
        }

		/// <summary>
		/// Metodo consultar por llave ciudades
		/// </summary>
		/// <param name="ciudades">Entidad a consultar</param>
		/// <returns>Respuesta tipo Ciudades </returns>
        public async Task<Respuesta<ICiudadesDTO>> ConsultarCiudadesLlaveAsync(ICiudadesDTO ciudades)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<ICiudadesDTO>, CiudadesDAL>(async () =>
            {
                respuesta.Entidades = (from entidad in ContextoBD.Ciudades
                                       where entidad.IdCiudad == ciudades.IdCiudad
                                       select entidad).ToList<ICiudadesDTO>();

                return respuesta;

            });
        }
    }
}

