namespace Generator_Class_BD.Clases.Consultas
{
    using Generator_Class_BD.Clases.Utilitarios;
    using System.Globalization;
    using System.Linq;
    using System.Text;
    using System.Threading;

    public class Relaciones
    {
        public static string GenerarConsultaLINQ(Consulta objetoConsulta)
        {
            CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
            TextInfo textInfo = cultureInfo.TextInfo;
            StringBuilder script = new StringBuilder();

            script.AppendLine($"from {objetoConsulta.TablaPrincipal} in ContextoBD.{objetoConsulta.TablaPrincipal}");
            objetoConsulta.ListaTablasRelacionadas.ForEach(rel =>
            {
                if (rel.TablaNombre != objetoConsulta.TablaPrincipal)
                {
                    // Si se referencia dos tablas más de una vez, se establece el prefijo al objeto
                    bool tablaMultipleReferencia = objetoConsulta.ListaTablasRelacionadas.Where(tab => tab.TablaNombre == rel.TablaNombre).Count() > 1;

                    script.AppendLine(tablaMultipleReferencia ? $"join {rel.TablaNombre}_{rel.IdFK} in ContextoBD.{rel.TablaNombre}" : $"join {rel.TablaNombre} in ContextoBD.{rel.TablaNombre}");

                    // Establecer campos que conforman el join
                    if (rel.ListaColumnasRelacion.Count > 1)
                    {
                        script.Append("on new { ");

                        rel.ListaColumnasRelacion.ForEach(columna =>
                        {
                            int indice = rel.ListaColumnasRelacion.IndexOf(columna) + 1;
                            script.Append(tablaMultipleReferencia ? $"Campo{indice} = {objetoConsulta.TablaPrincipal}_{columna.IdLlaveForanea}.{columna.ColumnaOrigen}," : $"Campo{indice} = {objetoConsulta.TablaPrincipal}.{columna.ColumnaOrigen},");
                        });
                        script.Append("} equals new { ");
                        rel.ListaColumnasRelacion.ForEach(columna =>
                        {
                            int indice = rel.ListaColumnasRelacion.IndexOf(columna) + 1;
                            script.Append(tablaMultipleReferencia ? $"Campo{indice} = {rel.TablaNombre}_{columna.IdLlaveForanea}.{columna.ColumnaDestino}," : $"Campo{indice} = {rel.TablaNombre}.{columna.ColumnaDestino},");
                        });
                        script.Append("}");
                    }
                    else
                    {
                        if (tablaMultipleReferencia)
                        {
                            script.AppendLine($"on {objetoConsulta.TablaPrincipal}.{rel.ListaColumnasRelacion[0].ColumnaOrigen} equals {rel.TablaNombre}_{rel.IdFK}.{rel.ListaColumnasRelacion[0].ColumnaDestino}");
                        }
                        else
                        {
                            script.AppendLine($"on {objetoConsulta.TablaPrincipal}.{rel.ListaColumnasRelacion[0].ColumnaOrigen} equals {rel.TablaNombre}.{rel.ListaColumnasRelacion[0].ColumnaDestino}");
                        }
                    }
                }
            });

            script.AppendLine($"select new {objetoConsulta.NombreObjeto}");
            script.AppendLine("{");
            objetoConsulta.ListaTablasRelacionadas.ForEach(rel =>
            {
                // Si se referencia dos tablas más de una vez, se establece el prefijo al objeto
                bool tablaMultipleReferencia = objetoConsulta.ListaTablasRelacionadas.Where(tab => tab.TablaNombre == rel.TablaNombre).Count() > 1;

                rel.ListaCampos.ForEach(campo =>
                {
                    bool campoMultipleReferencia = objetoConsulta.ListaTablasRelacionadas.SelectMany(x => x.ListaCampos).Where(x => x.Alias == campo.Alias).Count() > 1;

                    if (campoMultipleReferencia)
                    {
                        int indiceCampo = objetoConsulta.ListaTablasRelacionadas.IndexOf(rel) + 1;
                        script.AppendLine(tablaMultipleReferencia ? $"\t {campo.Nombre}{indiceCampo.ToString()} = {rel.TablaNombre}_{rel.IdFK}.{campo.Nombre}," : $"\t {campo.Nombre}{indiceCampo.ToString()} = {rel.TablaNombre}.{campo.Nombre},");
                    }
                    else
                    {
                        script.AppendLine(tablaMultipleReferencia ? $"\t {campo.Nombre} = {rel.TablaNombre}_{rel.IdFK}.{campo.Nombre}," : $"\t {campo.Nombre} = {rel.TablaNombre}.{campo.Nombre},");
                    }
                });
            });
            script.AppendLine("}");

            return script.ToString();
        }
    }
}
