using System;
using System.Collections.Generic;
using System.Linq;

namespace EgtBEAMWALL.StressTest
{
    public class Simulator
    {
        #region Public Fields

        public List<Core.BTLPartM> BtlPartList = new List<Core.BTLPartM>();
        public List<Core.MyMachGroupM> MachGroupList = new List<Core.MyMachGroupM>();
        public List<Core.PartM> PartList = new List<Core.PartM>();
        public List<Core.ProjectFileM> ProdList = new List<Core.ProjectFileM>();
        public List<Core.ProjectFileM> ProjList = new List<Core.ProjectFileM>();

        #endregion Public Fields

        #region Public Methods

        /// <summary>
        /// Generazione set di dati
        /// </summary>
        /// <param name="numProj"></param>
        /// <returns></returns>
        public bool GenerateData(int numProj)
        {
            bool done = false;

            SimParams currRandom = RandomParamSet;
            int currProjId = 0;
            int currProdId = 0;
            int numMG = 1;
            int BPIdx = 0;

            for (int i = 0; i < numProj; i++)
            {
                // genero i PROJ
                currProjId = ProjCtr.GetNextIndex();
                var currProjRecord = ProjCtr.FindByProjId(currProjId);
                List<DataLayer.DatabaseModels.BTLPartModel> currPartList = new List<DataLayer.DatabaseModels.BTLPartModel>();
                List<Core.MyMachGroupM> currMachGroupList = new List<Core.MyMachGroupM>();
                List<Core.PartM> currMGPartList = new List<Core.PartM>();
                ProjCtr.UpdateInfo(currProjId, "TestBTL", $"{DateTime.Now:yyyyMMdd_HHmmssfff}", $"LN_{DateTime.Now:yyyyMMdd_HHmm}", DateTime.Now.AddSeconds(15), Core.ConstBeam.BWType.BEAM, "SIM01");
                // genero le BTLParts ed assegno..
                for (int j = 0; j < currRandom.BtlPart2Proj; j++)
                {
                    currPartList.Add(new DataLayer.DatabaseModels.BTLPartModel() { CNT = currRandom.BtlPart2Proj, H = 10 * j, L = 50 * j, W = 5 * j, PDN = j, PartId = j });
                }
                BtlPartCtr.Create(currProjId, currPartList);

                // genero il PROD x PROJ
                currProdId = ProdCtr.GetNextIndex(currProjId);
                var currProdRecord = ProdCtr.FindByProdId(currProdId);

                // Genero le MachGroup x PROD (con num max di Parts da parametro SIM)
                int numPart2make = currRandom.BtlPart2Proj * currPartList.Count;
                numMG = (numPart2make / currRandom.Part2MachGroup) + 1;
                for (int k = 0; k < numMG; k++)
                {
                    currMGPartList = new List<Core.PartM>();

                    if (BPIdx >= currPartList.Count)
                    {
                        BPIdx = 0;
                    }
                    var currBTLPart = BtlPartCtr.FindByPartIdProjDbId(currPartList[BPIdx].PartId, currProjRecord.ProjDbId);
                    if (currBTLPart != null)
                    {
                        for (int l = 0; l < currRandom.Part2MachGroup; l++)
                        {
                            // FixME!!! non può creare x loop in CreateBeamDL che vuole
                            // nParentMachGroup genero le Part x MachGroup ed assegno
                            Core.PartM currPart = Core.PartM.CreatePart(Core.ConstBeam.BWType.BEAM, currMachGroupList.FirstOrDefault(), currPartList[BPIdx].PartId, 1);
                            currMGPartList.Add(currPart);
                            //currMGPartList.Add(new DataLayer.DatabaseModels.PartModel() { BTLPartDbId = currBTLPart.BTLPartDbId, PDN = l * k * currRandom.Part2MachGroup, PartId = l, H = 10 * l, L = 50 * l, W = 5 * l });
                        }
                    }
                    BPIdx++;

                    //Core.MachGroupM currMGroup = new Core.BeamMachGroupM.CreateBeamMachGroupDL(1, $"MG{k:000}", "MAC01", currMGPartList);

                    //currMGroup.PartMList

                    //currMachGroupList.Add(new DataLayer.DatabaseModels.MachGroupModel() { Locked = true, LogRev = k, MachGroupId = k, Name = $"MG{k:000}", H = 20 * k, L = 100 * k, W = 10 * k, State = Core.ItemState.Assigned, ProdDbId = currProdRecord.ProdDbId });
                }
                // salvo in blocco!
                ProdCtr.UpdateMachGroup(currProdId, currMachGroupList);
                ProdCtr.UpdateMachGroup(currProdId, currMachGroupList);

                //ProdCtr.UpdateMachGroupDB(currProdId, currMachGroupList, currMGPartList);
                //ProdCtr.UpdateMachGroupDB(currProdId, currMachGroupList, currMGPartList);

                // nuovo random!
                currRandom = RandomParamSet;
            }

            return done;
        }

        public void initDb()
        {
            var firstData = ProjCtr.GetLastDesc(1, true);
        }

        #endregion Public Methods

        #region Protected Fields

        protected DataLayer.Controllers.BTLPartController BtlPartCtr = new DataLayer.Controllers.BTLPartController();
        protected DataLayer.Controllers.MachGroupController MachGroupCtr = new DataLayer.Controllers.MachGroupController();
        protected SimParams MaxParams = new SimParams();

        protected DataLayer.Controllers.PartController PartCtr = new DataLayer.Controllers.PartController();
        protected DataLayer.Controllers.ProdController ProdCtr = new DataLayer.Controllers.ProdController();
        protected DataLayer.Controllers.ProjController ProjCtr = new DataLayer.Controllers.ProjController();

        #endregion Protected Fields

        #region Protected Properties

        /// <summary>
        /// restituisce un set di parametri simulazione generando a caso dal set di base
        /// </summary>
        protected SimParams RandomParamSet
        {
            get
            {
                Random rndGen = new Random();
                SimParams answ = new SimParams()
                {
                    BtlPart2Proj = rndGen.Next(MaxParams.BtlPart2Proj) + 1,
                    BtlRepeat = rndGen.Next(MaxParams.BtlRepeat) + 1,
                    Part2MachGroup = rndGen.Next(MaxParams.Part2MachGroup) + 1,
                    Proj2Prod = rndGen.Next(MaxParams.Proj2Prod) + 1
                };

                return answ;
            }
        }

        #endregion Protected Properties
    }
}