using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using bdHerramientaCACOA.db;
using bdHerramientaCACOA.extensiones;
using bdHerramientaCACOA.HerramientaUrban;
using static bdHerramientaCACOA.CASA;
using static bdHerramientaCACOA.HerramientaURBAN.URBAN;
using static bdHerramientaCACOA.LICITACIONES;

namespace bdHerramientaCACOA
{
    public class LicitacionesURBAN
    {

        public string NombreSimulacion { get; set; } = "Licitación Urbanismo " + DateTime.Now;
        public List<ConvenioColectivoConcurso> ListaConvenioColectivo { get; set; } = new List<ConvenioColectivoConcurso>();
        public List<SolvenciaTecnica> ListaSolvenciaTecnica { get; set; } = new List<SolvenciaTecnica>();
        //public int minimoGradoSuperior { get; set; } = 1;
        //public int minimoGradoMedio { get; set; } = 0;
        public string idProvincia { get; set; } = "";
        public int idGradSup { get; set; } = 0;
        public int idGradMed { get; set; } = 0;
        public int idDelin { get; set; } = 0;

        public double PlazoPresentacionDocumentos { get; set; } = 6;
        public double CosteHP { get; set; } = 0;
        public double CostesProduccionTrabProf { get; set; } = 0;
        public double Beneficio { get; set; } = 19;
        public double PrecioDelTrabajo { get; set; } = 0;

        public bool EsPorUsos { get; set; } = true;

        private URBANTrabajoProfesional _TrabajoProfesional = new URBANTrabajoProfesional();
        public URBANTrabajoProfesional TrabajoProfesional
        {
            get { return _TrabajoProfesional; }
            set { _TrabajoProfesional = value; }
        }

        public EnumeradosLicitacionesURBAN Enumerados { get; set; } = new EnumeradosLicitacionesURBAN();
        public VariablesLICITACIONES Variables { get; set; } = new VariablesLICITACIONES();

        public class EnumeradosLicitacionesURBAN
        {
            public List<puntosinformacion> PuntosInformacion { get; set; } = new List<puntosinformacion>();

            public List<ConvenioColectivoConcurso> ListaConvenioColectivo { get; set; } = new List<ConvenioColectivoConcurso>();
            public List<CosteDirectoIndirecto> ListaCDCI { get; set; } = new List<CosteDirectoIndirecto>();

            public List<enumeracionesCASA> TiposDeDocumentos { get; set; } = new List<enumeracionesCASA>();

            public List<FasesURBAN> FasesTrabajo { get; set; } = new List<FasesURBAN>();

            public List<tipoproyectosURBAN> TiposProyecto { get; set; } = new List<tipoproyectosURBAN>();

            public List<tipoproyecto_documentacionURBAN> TipoProy_Documentacion { get; set; } = new List<tipoproyecto_documentacionURBAN>();

            public List<DocumentacionURBAN> documentacion { get; set; } = new List<DocumentacionURBAN>();
            public List<tipoproyectosURBAN> ProyectosPorTipo(int idTipoDocumento)
            {
                return TiposProyecto.Where(x => x.idTipoDocumento == idTipoDocumento).ToList();
            }
            public List<enumeracionesCASA> ListaInstrumentos { get; set; } = new List<enumeracionesCASA>();

            public List<enumeracionesCASA> ListaGrupoTrabajadores { get; set; } = new List<enumeracionesCASA>();
        }
        public class VariablesLICITACIONES
        {
            public double CostesVariables { get; set; } = 0.035;
            public int JornadaLaboral { get; set; } = 1800;
            public int HorasProduccionMedia { get; set; } = 80;
            public double IPCCosteIndirecto { get; set; } = 1;
        }

        public void CargarVariables(bdHerramientaCACOA.dbcontext.tsHerramientasCACOA bd)
        {
            Variables.CostesVariables = (double)bd.enumeraciones.First(x => x.Codigo == "VARCASA.COSTESVARIABLES").ValorNumerico1;
            Variables.JornadaLaboral = (int)bd.enumeraciones.First(x => x.Codigo == "VARCASA.JORLABANUAL").ValorNumerico1;
            Variables.HorasProduccionMedia = (int) bd.enumeraciones.First(x => x.Codigo == "VARCASA.HORPRODMEDIA").ValorNumerico1;
            Variables.IPCCosteIndirecto = (double)bd.enumeraciones.First(x => x.Codigo == "VARCASA.IPCCD").ValorNumerico1;
            Beneficio = (double)bd.enumeraciones.First(x => x.Codigo == "VARCASA.GG+BI").ValorNumerico1;

            idGradSup = bd.enumeraciones.First(x => x.Codigo == "PUESTOTRABAJO.TECGRADSUP").idEnumeracion;
            idGradMed = bd.enumeraciones.First(x => x.Codigo == "PUESTOTRABAJO.GESTPROY").idEnumeracion;
            idDelin = bd.enumeraciones.First(x => x.Codigo == "PUESTOTRABAJO.DELINPROY").idEnumeracion;
        }
        public void CargarEnumerados(dbcontext.tsHerramientasCACOA bd)
        {
            var grupoPuestoTrabajo = bd.gruposenumeraciones.FirstOrDefault(x => x.Grupo == "PUESTOTRABAJO");
            Enumerados.ListaGrupoTrabajadores = ListaEnumeracionCASA(bd.enumeraciones.Where(x => x.idGrupoEnumeracion == grupoPuestoTrabajo.idGrupoEnumeracion).ToList());

            var grupoTipDocumento = bd.gruposenumeraciones.FirstOrDefault(x => x.Grupo == "TIPODOCU");
            Enumerados.TiposDeDocumentos = ListaEnumeracionCASA(bd.enumeraciones.Where(x => x.idGrupoEnumeracion == grupoTipDocumento.idGrupoEnumeracion).ToList());

            var grupoInstrumentos = bd.gruposenumeraciones.FirstOrDefault(x => x.Grupo == "INNINSTR");
            if(Enumerados.ListaInstrumentos.Count == 0)
            {
                Enumerados.ListaInstrumentos = ListaEnumeracionCASA(bd.enumeraciones.Where(x => x.idGrupoEnumeracion == grupoInstrumentos.idGrupoEnumeracion).ToList());
            }

            List<tipoproyectos> lp = bd.tipoproyectos.ToList();
            List<tipoproyectosURBAN> lpu = new List<tipoproyectosURBAN>();
            foreach (tipoproyectos tp in lp)
            {
                tipoproyectosURBAN tpu = new tipoproyectosURBAN();
                tpu.idtipoproyectos = tp.idtipoproyectos;
                tpu.idTipoDocumento = tp.idTipoDocumento;
                tpu.Descripcion = tp.Descripcion;
                tpu.Abreviatura = tp.Abreviatura;
                lpu.Add(tpu);
            }
            Enumerados.TiposProyecto = lpu;

            List<tipoproyecto_documentacion> ltpd = bd.tipoproyecto_documentacion.ToList();
            List<tipoproyecto_documentacionURBAN> ltpdu = new List<tipoproyecto_documentacionURBAN>();
            foreach (tipoproyecto_documentacion tpd in ltpd)
            {
                tipoproyecto_documentacionURBAN tpdu = new tipoproyecto_documentacionURBAN();
                tpdu.idtipoproyecto_documentacion = tpd.idtipoproyecto_documentacion;
                tpdu.idtipoproyecto = tpd.idtipoproyecto;
                tpdu.iddocumentacion = tpd.iddocumentacion;
                tpdu.esMinima = tpd.esMinima;
                tpdu.esOpcional = tpd.esOpcional;
                tpdu.esNecesario = tpd.esNecesario;
                ltpdu.Add(tpdu);
            }

            Enumerados.TipoProy_Documentacion = ltpdu;

            Enumerados.documentacion = documentacionAUrban(bd.documentacion.ToList());


            //Esto es para la tabla de CDCI matematica, en configuracion puede verse como "calculo CD+CI"
            var lisConvCol = bd.conveniocolectivo.ToList();
            Enumerados.ListaConvenioColectivo = ListaConvenioColectivoCASA(lisConvCol);
            Enumerados.ListaCDCI = CalcularTabla("");
        }
        public void RellenarCamposExtra(dbcontext.tsHerramientasCACOA bd)
        {
            CargarVariables(bd);
            CargarEnumerados(bd);
            //Cargamos las Fases
            var grupoFases = bd.gruposenumeraciones.FirstOrDefault(x => x.Grupo == "FASURB");
            var listaFases = bd.enumeraciones.Where(x => x.idGrupoEnumeracion == grupoFases.idGrupoEnumeracion).ToList();
            foreach (enumeraciones enu in listaFases)
            {
                if (!TrabajoProfesional.FasesTrabajoProfesional.Any(x => x.idFase == enu.idEnumeracion))
                {
                    FasesURBAN ft = new FasesURBAN();
                    ft.idFase = enu.idEnumeracion;
                    ft.Codigo = enu.Codigo;
                    ft.Denominacion = enu.ValorAlfabetico1;
                    ft.Porcentaje = (double)enu.ValorNumerico1;

                    TrabajoProfesional.FasesTrabajoProfesional.Add(ft);
                }
            }

            checkListFasesURBAN(listaFases);

            Enumerados.PuntosInformacion = bd.puntosinformacion.Where(x => x.idTipoHerramienta == 35).ToList();


            Enumerados.FasesTrabajo = JsonSerializer.Deserialize<List<FasesURBAN>>(JsonSerializer.Serialize(TrabajoProfesional.FasesTrabajoProfesional));
        }

        private void checkListFasesURBAN(List<enumeraciones> listaFases)
        {
            var itemsAEliminar = TrabajoProfesional.FasesTrabajoProfesional
                .Where(item => !listaFases.Any(x => x.idEnumeracion == item.idFase))
                .ToList();

            foreach (var item in itemsAEliminar)
            {
                TrabajoProfesional.FasesTrabajoProfesional.Remove(item);
            }
        }

        public void CalcularLicitacion() {
            var horasAnualesDes = Math.Round(TrabajoProfesional.horasTrabProfesional * 12 / PlazoPresentacionDocumentos,2,MidpointRounding.AwayFromZero);
            var CD = ObtenerCDTabla(horasAnualesDes);
            var CI = ObtenerCITabla(horasAnualesDes);
            var CV = 0.025;

            CosteHP = ((CD+CI)*(1+CV)).DosDecimales();
            CostesProduccionTrabProf = (TrabajoProfesional.horasTrabProfesional*CosteHP).DosDecimales();
            //Beneficio = 0.19;
            PrecioDelTrabajo = (CostesProduccionTrabProf*(1+(Beneficio/100))).DosDecimales();
        }

        private double ObtenerCDTabla(double horas)
        {
            double valor = 0;
            var a = Enumerados.ListaCDCI.OrderByDescending(x => x.NumeroTrabajadores);
            if (Enumerados.ListaCDCI.Count > 0) {
                valor = a.First().CostesDirectos;
                if (a.Count() > 0)
                {
                    foreach (CosteDirectoIndirecto cdp in a)
                    {
                        if (horas <= cdp.HorasProduccionAnuales)
                        {
                            valor = cdp.CostesDirectos;
                        }
                    }
                }
            }
            return valor;
        }
        private double ObtenerCITabla(double horas)
        {
            double valor = 0;
            var a = Enumerados.ListaCDCI.OrderByDescending(x => x.NumeroTrabajadores);
            if (Enumerados.ListaCDCI.Count > 0)
            {
                valor = a.First().CostesIndirectos;
                if (a.Count() > 0)
                {
                    foreach (CosteDirectoIndirecto cdp in a)
                    {
                        if (horas <= cdp.HorasProduccionAnuales)
                        {
                            valor = cdp.CostesIndirectos;
                        }
                    }
                }
            }
            return valor;
        }

        public void ActualizarDocumentacionOpcional(DocumentacionURBAN doc)
        {
            int indice = TrabajoProfesional.DocumentacionOpcional.ToList().IndexOf(doc);
            TrabajoProfesional.DocumentacionOpcional[indice] = doc;
            CalcularHorasTrabajoProfesional();
        }
        public void ActualizarDatoNecesario(DocumentacionURBAN doc)
        {
            int indice = TrabajoProfesional.DatosNecesarios.ToList().IndexOf(doc);
            TrabajoProfesional.DatosNecesarios[indice] = doc;
            CalcularHorasTrabajoProfesional();
        }
        public void CalcularHorasTrabajoProfesional()
        {
            if (EsPorUsos)
            {
                double valorhoras = ObtenerHoraTipoDocumento();
                double totalEncargo = TrabajoProfesional.FasesTrabajoProfesional.Sum(x => x.Porcentaje);
                double porcentajeInnovacion = TrabajoProfesional.valorInstrumentos;

                TrabajoProfesional.horasTrabProfesional = (valorhoras * (totalEncargo / 100) * (porcentajeInnovacion / 100)).DosDecimales();
                TrabajoProfesional.horasTrabProfesionalEstimacion = TrabajoProfesional.horasTrabProfesional;
            }
            else {
            
            }
            CalcularLicitacion();
        }
        public double ObtenerHoraTipoDocumento()
        {
            int datos = TrabajoProfesional.DatosNecesarios.Count;
            var colcoef = "?";
            var formHP = "?";
            double TPCOEF1 = obtenerTPCOEF1();
            double TPCOEF2 = 0;
            if (TrabajoProfesional.DatosNecesarios.Count >= 2)
            {
                if (TrabajoProfesional.DatosNecesarios[1].esCheckbox)
                {
                    if (TrabajoProfesional.DatosNecesarios[1].Checkeada)
                    {
                        TPCOEF2 = TrabajoProfesional.DatosNecesarios[1].CoefHoras;
                    }
                }
                else
                {
                    double TPdato2 = TrabajoProfesional.DatosNecesarios[1].ValorNecesario;
                    TPCOEF2 = TrabajoProfesional.DatosNecesarios[1].CoefHoras * TPdato2;
                }
            }
            double TPCOEF3 = 0;
            if (TrabajoProfesional.DatosNecesarios.Count >= 3)
            {
                if (TrabajoProfesional.DatosNecesarios[2].Checkeada)
                {
                    TPCOEF3 = TrabajoProfesional.DatosNecesarios[2].CoefHoras;
                }

            }


            return ((TPCOEF1 + TPCOEF2) * (1 + TPCOEF3)).DosDecimales();
        }
        public double obtenerTPCOEF1()
        {
            if (TrabajoProfesional.idTipoProyecto != 0)
            {
                int minimo = TrabajoProfesional.DocumentacionMinima.Count;
                int opciones = TrabajoProfesional.DocumentacionOpcional.Count;
                int opcSel = TrabajoProfesional.DocumentacionOpcional.Where(x => x.Checkeada == true).Count();
                string abreviatura = Enumerados.TiposProyecto.First(x => x.idtipoproyectos == TrabajoProfesional.idTipoProyecto).Abreviatura;
                double TPdato1 = TrabajoProfesional.DatosNecesarios[0].ValorNecesario;
                double formDato1 = 0;
                if (TPdato1 != 0)
                {
                    switch (abreviatura)
                    {
                        case "PGOM":
                            if (TPdato1 < 1)
                            {
                                formDato1 = 0.7 * 77.14;
                            }
                            else
                            {
                                formDato1 = 0.7 * (95.413 * Math.Pow(TPdato1, -0.328));
                            }
                            break;
                        case "POI":
                            if (TPdato1 > 50)
                            {
                                formDato1 = 70.6;
                            }
                            else
                            {
                                formDato1 = 56.703 * Math.Pow(TPdato1, 0.0554);
                            }
                            break;
                        case "PBOM":
                            if (TPdato1 < 1)
                            {
                                formDato1 = 0.7 * 77.14;
                            }
                            else
                            {
                                formDato1 = (95.413 * Math.Pow(TPdato1, -0.328));
                            }
                            break;
                        case "POU":
                            if (TPdato1 < 1)
                            {
                                formDato1 = 0.3 * 77.14;
                            }
                            else
                            {
                                formDato1 = 0.3 * (95.413 * Math.Pow(TPdato1, -0.328));
                            }
                            break;
                        case "PPO":
                            if (TPdato1 <= 5)
                            {
                                formDato1 = 9.44;
                            }
                            else
                            {
                                if (TPdato1 > 100)
                                {
                                    formDato1 = 2.3;
                                }
                                else
                                {
                                    formDato1 = 24.911 * Math.Pow(TPdato1, -0.473);
                                }
                            }
                            break;
                        case "PRI":
                            if (TPdato1 <= 5)
                            {
                                formDato1 = 17.08;
                            }
                            else
                            {
                                if (TPdato1 > 100)
                                {
                                    formDato1 = 3.67;
                                }
                                else
                                {
                                    formDato1 = 50.413 * Math.Pow(TPdato1, -0.524);
                                }
                            }
                            break;
                        case "EO":
                            if (TPdato1 <= 5)
                            {
                                formDato1 = 12.2;
                            }
                            else
                            {
                                if (TPdato1 > 100)
                                {
                                    formDato1 = 3.17;
                                }
                                else
                                {
                                    formDato1 = 31.953 * Math.Pow(TPdato1, -0.475);
                                }
                            }
                            break;
                        case "PE":
                            if (TPdato1 <= 5)
                            {
                                formDato1 = 6.8;
                            }
                            else
                            {
                                if (TPdato1 > 100)
                                {
                                    formDato1 = 1.81;
                                }
                                else
                                {
                                    formDato1 = 17.536 * Math.Pow(TPdato1, -0.468);
                                }
                            }
                            break;
                        case "PEP":
                            if (TPdato1 <= 5)
                            {
                                formDato1 = 22.65;
                            }
                            else
                            {
                                if (TPdato1 > 100)
                                {
                                    formDato1 = 6;
                                }
                                else
                                {
                                    formDato1 = 58.555 * Math.Pow(TPdato1, -0.468);
                                }
                            }
                            break;
                        case "ED":
                            if (TPdato1 < 10)
                            {
                                formDato1 = 10.085 * Math.Pow(TPdato1, -0.4);
                            }
                            else
                            {
                                formDato1 = 4.2;
                            }
                            break;
                        case "CAT":
                            formDato1 = TrabajoProfesional.DatosNecesarios.First().CoefHoras;
                            break;
                        case "PPAR":
                            if (TPdato1 > 50)
                            {
                                formDato1 = 0.88;
                            }
                            else
                            {
                                formDato1 = 4.7193 * Math.Pow(TPdato1, -0.34);
                            }
                            break;
                        case "UE":
                            if (TPdato1 >= 100)
                            {
                                formDato1 = 0.26;
                            }
                            else
                            {
                                formDato1 = 2.1598 * Math.Pow(TPdato1, -0.468);
                            }
                            break;
                        case "PREP":
                            if (TPdato1 >= 100)
                            {
                                formDato1 = 0.94;
                            }
                            else
                            {
                                formDato1 = 4.9615 * Math.Pow(TPdato1, -0.328);
                            }
                            break;
                        case "PNF":
                            if (TPdato1 >= 100)
                            {
                                formDato1 = 0.94;
                            }
                            else
                            {
                                formDato1 = 4.9615 * Math.Pow(TPdato1, -0.328);
                            }
                            break;
                        case "PDCU":
                            if (TPdato1 >= 100)
                            {
                                formDato1 = 0.94;
                            }
                            else
                            {
                                formDato1 = 4.9615 * Math.Pow(TPdato1, -0.328);
                            }
                            break;
                        case "PETC":
                            if (TPdato1 >= 100)
                            {
                                formDato1 = 1.85;
                            }
                            else
                            {
                                formDato1 = 8.97 * Math.Pow(TPdato1, -0.322);
                            }
                            break;
                        case "PU":
                            if (TPdato1 >= 100)
                            {
                                formDato1 = 50;
                            }
                            else
                            {
                                formDato1 = -27.14 * Math.Log(TPdato1) + 189.88;
                            }
                            break;
                        case "POOU":
                            if (TPdato1 >= 100)
                            {
                                formDato1 = 50;
                            }
                            else
                            {
                                formDato1 = -27.14 * Math.Log(TPdato1) + 189.88;
                            }
                            break;
                        case "PDATU":
                            if (TPdato1 <= 100)
                            {
                                formDato1 = 1.65;
                            }
                            else
                            {
                                formDato1 = 25.451 * Math.Pow(TPdato1, -0.328);
                            }
                            break;
                        case "PEAAT":
                            if (TPdato1 <= 1)
                            {
                                formDato1 = 10.14;
                            }
                            else
                            {
                                formDato1 = 13.898 * Math.Pow(TPdato1, -0.383);
                            }
                            break;
                        case "PA":
                            if (TPdato1 <= 1)
                            {
                                formDato1 = 10.14;
                            }
                            else
                            {
                                formDato1 = 13.898 * Math.Pow(TPdato1, -0.383);
                            }
                            break;
                    }
                }
                double TPdatoXformula = (TPdato1 * formDato1).DosDecimales();
                return ((minimo + (0.5 * opcSel)) * TPdatoXformula).DosDecimales();
            }
            else
            {
                return 0;
            }

        }
        public void ActualizarFase(FasesURBAN ft)
        {
            int indice = TrabajoProfesional.FasesTrabajoProfesional.ToList().IndexOf(ft);
            TrabajoProfesional.FasesTrabajoProfesional[indice] = ft;
            CalcularHorasTrabajoProfesional();
        }

        public List<DocumentacionURBAN> DocumentacionMinima(int idTipoProyecto)
        {

            List<tipoproyecto_documentacionURBAN> lista = Enumerados.TipoProy_Documentacion.Where(x => x.idtipoproyecto == idTipoProyecto && x.esMinima == true).ToList();
            List<DocumentacionURBAN> ldm = new List<DocumentacionURBAN>();

            foreach (tipoproyecto_documentacionURBAN tpd in lista)
            {
                DocumentacionURBAN d = Enumerados.documentacion.First(x => x.iddocumentacion == tpd.iddocumentacion);
                ldm.Add(d);
            }

            return ldm;
        }
        public List<DocumentacionURBAN> DocumentacionOpcional(int idTipoProyecto)
        {

            List<tipoproyecto_documentacionURBAN> lista = Enumerados.TipoProy_Documentacion.Where(x => x.idtipoproyecto == idTipoProyecto && x.esOpcional == true).ToList();
            List<DocumentacionURBAN> ldm = new List<DocumentacionURBAN>();

            foreach (tipoproyecto_documentacionURBAN tpd in lista)
            {
                DocumentacionURBAN d = Enumerados.documentacion.First(x => x.iddocumentacion == tpd.iddocumentacion);
                ldm.Add(d);
            }

            return ldm;
        }
        public List<DocumentacionURBAN> DatosNecesarios(int idTipoProyecto)
        {

            List<tipoproyecto_documentacionURBAN> lista = Enumerados.TipoProy_Documentacion.Where(x => x.idtipoproyecto == idTipoProyecto && x.esNecesario == true).ToList();
            List<DocumentacionURBAN> ldm = new List<DocumentacionURBAN>();

            foreach (tipoproyecto_documentacionURBAN tpd in lista)
            {
                DocumentacionURBAN d = Enumerados.documentacion.First(x => x.iddocumentacion == tpd.iddocumentacion);
                ldm.Add(d);
            }

            return ldm;
        }
        private List<DocumentacionURBAN> documentacionAUrban(List<documentacion> lista)
        {
            var listaDoc = new List<DocumentacionURBAN>();
            foreach (var documentacion in lista)
            {
                var d = new DocumentacionURBAN();
                d.iddocumentacion = documentacion.iddocumentacion;
                d.Descripcion = documentacion.Descripcion.ToString();
                if (documentacion.CoeficienteHoras.HasValue)
                {
                    d.CoefHoras = (double)documentacion.CoeficienteHoras;
                }
                d.esCheckbox = documentacion.Checkeable;
                listaDoc.Add(d);
            }

            return listaDoc;
        }

        public List<CosteDirectoIndirecto> CalcularTabla(string idProvincia)
        {
            List<CosteDirectoIndirecto> listaCDCI = new List<CosteDirectoIndirecto>();
            if (ListaSolvenciaTecnica.Count > 0) {
                //Obtenemos variables a utilizar
                if (idProvincia == "") { idProvincia = null; }

                double ValorTecSuperior = Enumerados.ListaConvenioColectivo.FirstOrDefault(x => x.idProvincia == idProvincia && x.idEnumeracion == idGradSup) != null ? Enumerados.ListaConvenioColectivo.First(x => x.idProvincia == idProvincia && x.idEnumeracion == idGradSup).CosteAnualTrabajador : 0;
                double ValorTecMedio = Enumerados.ListaConvenioColectivo.FirstOrDefault(x => x.idProvincia == idProvincia && x.idEnumeracion == idGradMed) != null ? Enumerados.ListaConvenioColectivo.First(x => x.idProvincia == idProvincia && x.idEnumeracion == idGradMed).CosteAnualTrabajador : 0;
                double ValorDelineante = Enumerados.ListaConvenioColectivo.FirstOrDefault(x => x.idProvincia == idProvincia && x.idEnumeracion == idDelin) != null ? Enumerados.ListaConvenioColectivo.First(x => x.idProvincia == idProvincia && x.idEnumeracion == idDelin).CosteAnualTrabajador : 0; ;

                double masCaro = Math.Max(ValorTecSuperior, Math.Max(ValorTecMedio, ValorDelineante));
                double masBarato = Math.Min(ValorTecSuperior, Math.Min(ValorTecMedio, ValorDelineante));

                var minimoGradoSuperior = ListaSolvenciaTecnica.Where(x=> x.idConvenioColectivo==idGradSup).Sum(x => x.Cantidad);
                var minimoGradoMedio = ListaSolvenciaTecnica.Where(x => x.idConvenioColectivo == idGradMed).Sum(x => x.Cantidad);
                var resto= ListaSolvenciaTecnica.Where(x => x.idConvenioColectivo != idGradMed  && x.idConvenioColectivo != idGradSup).Sum(x => x.Cantidad);

                int minimoTrabajadores = minimoGradoMedio + minimoGradoSuperior + resto;
                //Se calcula 
                //CosteDirectoIndirecto cdci = new CosteDirectoIndirecto(i, costeMinimo, costeMaximo, Variables.JornadaLaboral, Variables.HorasProduccionMedia, Variables.CostesVariables, Variables.IPCCosteIndirecto);
                if (minimoTrabajadores == 1 && minimoGradoSuperior == 1)
                {//Se calcula como siempre, el calculo de licitaciones CASA
                    for (int i = 1; i <= 20; i++)
                    {
                        double costeMinimo = ValorTecSuperior + (masBarato * (i - 1));
                        double costeMaximo = ValorTecSuperior + (masCaro * (i - 1));
                        listaCDCI.Add(new CosteDirectoIndirecto(i, costeMinimo, costeMaximo, Variables.JornadaLaboral, Variables.HorasProduccionMedia, Variables.CostesVariables, Variables.IPCCosteIndirecto));
                    }
                }
                else
                {//Se calcula con minimos, por si ponen minimos en licitaciones URBAN
                 //var resto= minimoTrabajadores-minimoGradoMedio
                    double costeMinimo1 = (ValorTecSuperior * minimoGradoSuperior) + (ValorTecMedio * minimoGradoMedio)+(masBarato * resto); //+ (masBarato * numresto);
                    double costeMaximo1 = (ValorTecSuperior * minimoGradoSuperior) + (ValorTecMedio * minimoGradoMedio)+(masBarato * resto); //+ (masCaro * (numresto));
                    listaCDCI.Add(new CosteDirectoIndirecto(minimoTrabajadores, costeMinimo1, costeMaximo1, Variables.JornadaLaboral, Variables.HorasProduccionMedia, Variables.CostesVariables, Variables.IPCCosteIndirecto));
                    for (int i = minimoTrabajadores + 1; i <= 20; i++)
                    {
                        var numresto = i - minimoTrabajadores;
                        double costeMinimo = (ValorTecSuperior * minimoGradoSuperior) + (ValorTecMedio * minimoGradoMedio) + (masBarato * numresto);
                        double costeMaximo = (ValorTecSuperior * minimoGradoSuperior) + (ValorTecMedio * minimoGradoMedio) + (masCaro * (numresto));
                        listaCDCI.Add(new CosteDirectoIndirecto(i, costeMinimo, costeMaximo, Variables.JornadaLaboral, Variables.HorasProduccionMedia, Variables.CostesVariables, Variables.IPCCosteIndirecto));
                    }
                }
            }
            return listaCDCI;
        }
        public void InsertarSolvenciaTecnica(SolvenciaTecnica ot)
        {
            ListaSolvenciaTecnica.Add(ot);
            Enumerados.ListaCDCI = CalcularTabla(idProvincia);
            CalcularHorasTrabajoProfesional();
        }
        public void EliminarSolvenciaTecnica(SolvenciaTecnica ot)
        {
            ListaSolvenciaTecnica.Remove(ot);
            Enumerados.ListaCDCI = CalcularTabla(idProvincia);
            CalcularHorasTrabajoProfesional();
        }
        public void ActualizarSolvenciaTecnica(SolvenciaTecnica ot)
        {
            int indice = ListaSolvenciaTecnica.ToList().IndexOf(ot);
            ListaSolvenciaTecnica[indice] = ot;

            Enumerados.ListaCDCI = CalcularTabla(idProvincia);
            CalcularHorasTrabajoProfesional();
        }
        public List<ConvenioColectivoConcurso> ListaConvenioColectivoCASA(List<conveniocolectivo> lista)
        {
            List<ConvenioColectivoConcurso> lcc = new List<ConvenioColectivoConcurso>();
            foreach (conveniocolectivo enu in lista)
            {
                lcc.Add(convenioColectivoACASA(enu));
            }
            return lcc;
        }
        public ConvenioColectivoConcurso convenioColectivoACASA(conveniocolectivo cc)
        {
            return new ConvenioColectivoConcurso()
            {
                idConvenioColectivo = cc.idConvenioColectivo,
                idEnumeracion = cc.idEnumeracion,
                idProvincia = cc.idProvincia,
                SalarioBase = cc.SalarioBase,
                OtrosCostes = cc.OtrosCostes,
                CosteAnualTrabajador = cc.CosteAnualTrabajador
            };
        }

        public class SolvenciaTecnica
        {
            public int idSolvencia { get; set; } = 0;
            public int idConvenioColectivo { get; set; } = 0;
            public string TipoConvenio { get; set; } = "";
            public int Cantidad { get; set; } = 0;
            public string Descripcion { get; set; } = "";
        }


        #region parsearObjetos
        public List<enumeracionesCASA> ListaEnumeracionCASA(List<enumeraciones> lista)
        {

            List<enumeracionesCASA> lu = new List<enumeracionesCASA>();
            foreach (enumeraciones enu in lista)
            {
                lu.Add(EnumeracionACASA(enu));
            }
            return lu;
        }
        public enumeracionesCASA EnumeracionACASA(enumeraciones enu)
        {
            return new enumeracionesCASA()
            {
                idEnumeracion = enu.idEnumeracion,
                idGrupoEnumeracion = enu.idGrupoEnumeracion,
                Codigo = enu.Codigo,
                Descripcion = enu.Descripcion,
                ValorAlfabetico1 = enu.ValorAlfabetico1,
                ValorAlfabetico2 = enu.ValorAlfabetico2,
                ValorNumerico1 = enu.ValorNumerico1
            };
        }
        #endregion
    }
}
