using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Kreta.BusinessLogic.Classes;
using Kreta.BusinessLogic.HelperClasses;
using Kreta.BusinessLogic.Helpers.SystemSettings;
using Kreta.Core;
using Kreta.Core.ConnectionType;
using Kreta.DataAccess.Interfaces;
using Kreta.DataAccessManual;
using Kreta.DataAccessManual.Interfaces;
using Kreta.DataAccessManual.Util;
using Kreta.Enums;
using Kreta.Enums.ManualEnums;
using SDA.DataProvider;

namespace Kreta.BusinessLogic.Helpers
{
    public class CsengetesiRendHelper : LogicBase
    {
        public CsengetesiRendHelper(IConnectionType connectionType) : base(connectionType) { }

        public IEnumerable<int> GetOsztalyCsoportIdsForCsengetesiRend(DateTime datum, int hanyadikOra, IEnumerable<int> osztalyCsoportIds)
        {
            return Dal.CustomConnection.Run(ConnectionType, (h) =>
            {
                var aktivCsengetesiRendId = GetAktivCsengetesiRendId(h);

                var date = datum.Date;

                var datumCsengetesiRendList = GetCsengetesiRendekIdoszakra(h, date, date);

                var connectionType = new DalHandlerConnectionType(ConnectionType, h);

                var foglalkozasok_Rogzitese_Hetvegere = new SystemSettingsHelper(connectionType).GetSystemSettingValue<FoglalkozasokRogziteseHetvegere>(RendszerBeallitasTipusEnum.Foglalkozasok_Rogzitese_Hetvegere);

                var orarendHelper = new OrarendHelper(connectionType);
                var csengetesiRendOrakHelper = new CsengetesiRendOrakHelper(connectionType);

                var osztalyCsoportIdsForCsengetesiRend = new List<int>();

                foreach (var osztalyCsoportId in osztalyCsoportIds)
                {
                    var csengetesiRendId = orarendHelper.GetCsengetesiRendForDate(date, datumCsengetesiRendList, aktivCsengetesiRendId, foglalkozasok_Rogzitese_Hetvegere, osztalyCsoportId);

                    if (csengetesiRendId.HasValue)
                    {
                        var csengetesiRendOrak = csengetesiRendOrakHelper.GetCsengetesiRendOraCoList(csengetesiRendId.Value);

                        var csengetesiRendOrakbanSzerepel = csengetesiRendOrak.Any(x => x.Oraszam == hanyadikOra);

                        if (csengetesiRendOrakbanSzerepel)
                        {
                            osztalyCsoportIdsForCsengetesiRend.Add(osztalyCsoportId);
                        }
                    }
                }

                return osztalyCsoportIdsForCsengetesiRend;
            });
        }

        public DataSet GetCsengetesiRendek()
        {
            return Dal.CustomConnection.Run(ConnectionType, (h) =>
            {
                var dal = h.CsengetesiRend(GridParameters);
                return dal.GetCsengetesiRendekByMukodesiHely(TanevId);
            });
        }

        public CsengetesiRendCO GetCsengetesiRendById(int cId)
        {
            return Dal.CustomConnection.Run(ConnectionType, (h) =>
            {
                var dal = h.CsengetesiRend();
                var co = new CsengetesiRendCO();
                var entity = dal.Get(cId);

                co.ID = entity.ID;
                co.Nev = entity.Nev;
                co.Aktiv = entity.Aktiv ?? false;

                return co;
            });
        }

        public List<CsengetesiRendIdoszakraCO> GetCsengetesiRendekIdoszakra(DateTime kezdoDatum, DateTime vegDatum, int? osztalyCsoportId = null)
        {
            return Dal.CustomConnection.Run(ConnectionType, (h) =>
            {
                return GetCsengetesiRendekIdoszakra(h, kezdoDatum, vegDatum, osztalyCsoportId);
            });
        }

        private List<CsengetesiRendIdoszakraCO> GetCsengetesiRendekIdoszakra(IDalHandler h, DateTime kezdoDatum, DateTime vegDatum, int? osztalyCsoportId = null)
        {
            var result = new List<CsengetesiRendIdoszakraCO>();

            var dal = h.CsengetesiRend();
            var ds = dal.GetCsengetesiRendek(kezdoDatum, vegDatum, osztalyCsoportId, IntezmenyId, TanevId);

            foreach (DataRow row in ds.Tables[0].Rows)
            {
                var co = new CsengetesiRendIdoszakraCO();
                co.Date = SDAConvert.ToDateTime(row["Datum"]) ?? default(DateTime);
                co.CsengetesiRendId = row["CsengetesiRendId"] == DBNull.Value ? (int?)null : SDAConvert.ToInt32(row["CsengetesiRendId"]);
                co.TanevRendTipus = SDAConvert.ToInt32(row["TanevRendTipus"]);
                co.IsOrarendiNap = SDAConvert.ToBooleanFromTF(row["OrarendiNap"]);
                co.IsOsszesCsoport = SDAConvert.ToBooleanFromTF(row["IsOsszesCsoport"]);
                co.OsztalyCsoportId = SDAConvert.ToNullableInt32(row["OsztalyCsoportId"]);
                co.HetNapja = SDAConvert.ToInt32(row["HetNapja"]);
                co.OsztalyCsoportNev = SDAConvert.ToString(row["OsztalyCsoportNev"]);
                result.Add(co);
            }

            return result;
        }

        public int SaveOrUpdateCsengetesiRend(CsengetesiRendCO co)
        {
            return Dal.CustomConnection.Run(ConnectionType, (h) =>
            {
                var dal = h.CsengetesiRend(GridParameters);
                var ds = dal.GetCsengetesiRendekByMukodesiHely(TanevId);

                if (ds.Tables[0].Rows.Count < 1)
                {
                    co.Aktiv = true;
                }

                if (co.ID.HasValue && co.ID > 0)
                {
                    if (dal.IsCsengetesiRendNevExists(co.ID.Value, co.Nev, TanevId))
                    {
                        throw new UniqueKeyViolationException();
                    }

                    ICsengetesiRend entity = dal.Get(co.ID.Value);
                    entity.Nev = co.Nev;
                    entity.Aktiv = Convert.ToBoolean(co.Aktiv);
                    dal.FullUpdate(entity);
                    return entity.ID;
                }
                else
                {
                    var entity = dal.Get();
                    entity.Nev = co.Nev;
                    entity.Aktiv = Convert.ToBoolean(co.Aktiv);
                    entity.TanevId = TanevId;
                    dal.Insert(entity);
                    return entity.ID;
                }
            });
        }

        public void DeleteCsengetesiRend(int csId)
        {
            Dal.CustomConnection.Run(ConnectionType, (h) =>
            {
                var dal = h.CsengetesiRend(GridParameters);
                dal.Delete(csId);
            });
        }

        public void SetCsengetesirend(int csRendId, bool aktiv)
        {
            Dal.CustomConnection.Run(ConnectionType, (h) =>
            {
                var dal = h.CsengetesiRend(GridParameters);
                dal.SetCsengetesirend(csRendId, aktiv, TanevId);
                var OrarendDal = h.OrarendiOra();
                OrarendDal.UpdateOrarend(IntezmenyId, TanevId, idoszakKezdete: null, idoszakVege: null, orarendioraId: null, osztalyCsoportId: null);
            });
        }

        public (int csengetesiRendId, int oraSzam) GetCsengetesiRendAndOraszam(int csengetesirendOraId)
        {
            return Dal.CustomConnection.Run(ConnectionType, (h) =>
            {
                var dal = h.CsengetesiRend();
                return dal.GetCsengetesiRendAndOraszam(csengetesirendOraId, IntezmenyId, TanevId);
            });
        }

        public DataSet GetCsengetesiRendEsOrak(string csengetesiRendId, int oraszamId)
        {
            return Dal.CustomConnection.Run(ConnectionType, h =>
            {
                var dal = h.CsengetesiRend();
                return dal.GetCsengetesiRendEsOrak(csengetesiRendId, oraszamId, TanevId);
            });
        }

        public int GetAktivCsengetesiRendId()
        {
            return Dal.CustomConnection.Run(ConnectionType, (h) =>
            {
                return GetAktivCsengetesiRendId(h);
            });
        }

        private int GetAktivCsengetesiRendId(IDalHandler h)
        {
            var dal = h.CsengetesiRend();
            return dal.GetAktivCsengetesiRendId(TanevId, IntezmenyId);
        }

        public int GetCsengetesiRendId(int csengetesirendOraId)
        {
            return Dal.CustomConnection.Run(ConnectionType, (h) =>
            {
                var dal = h.CsengetesiRendOrak();
                var csOra = dal.Get(csengetesirendOraId);
                return csOra.CsengetesiRendId;
            });
        }

        private bool IsValidRow(DataRow row, int csengetesiRendId)
        {
            if (row.Field<int?>("C_AKTIVCSENGETESIRENDID") != null && row.Field<int?>("C_AKTIVCSENGETESIRENDID") == csengetesiRendId)
            {
                return true;
            }

            if (row.Field<int?>("ID") != null && row.Field<int?>("ID") == csengetesiRendId)
            {
                return true;
            }

            return false;
        }

        public void FollowUpCsengetesiRend(int kovTanevId, int csengetesiRendId)
        {
            Dal.CustomConnection.Run(ConnectionType, (h) =>
            {
                var dal = h.CsengetesiRend();
                dal.FollowUpCsengetesiRend(IntezmenyId, TanevId, kovTanevId, csengetesiRendId);
            });
        }

        public bool CheckCsengRendNevEgyezes(int csengRendId, string csengRendNev)
        {
            if (csengRendId.IsEntityId())
            {
                return false;
            }

            var ds = Dal.CustomConnection.Run(ConnectionType, (h) =>
            {
                var dal = h.CsengetesiRend();
                return dal.GetCsengetesiRendekByMukodesiHely(TanevId);
            });

            foreach (DataRow row in ds.Tables[0].Rows)
            {
                if (SDAConvert.ToString(row["Nev"]) == csengRendNev && csengRendId == 0)
                {
                    return true;
                }
            }
            return false;
        }

        public List<CsengetesiRendItemCo> GetCsengetesiRendCoList()
        {
            DataSet dataSet = GetCsengetesiRendek();

            var result = new List<CsengetesiRendItemCo>();
            foreach (DataRow dataRow in dataSet.Tables[0].Rows)
            {
                var item = new CsengetesiRendItemCo(dataRow);
                result.Add(item);
            }

            return result;
        }

        public (int minOraszam, int maxOraszam) GetMinMaxOraszam(int csengetesirendId)
        {
            return Dal.CustomConnection.Run(ConnectionType, (h) =>
            {
                var dal = h.CsengetesiRend();
                return dal.GetMinMaxOraszam(TanevId, csengetesirendId);
            });
        }
    }
}