using ClosedXML.Excel;
using Demo.Data.Repository;
using Demo.Domain.Models;
using DocumentFormat.OpenXml.Office.Word;
using DocumentFormat.OpenXml.Wordprocessing;

namespace Demo.Domain.UseCase
{
    public class AdminUseCase : IAdminUseCase
    {
        private readonly IAdminRepository _repositoryAdminImpl;
        private readonly IUserRepository _repositoryUserImpl;
        private readonly IPresenceRepository _repositoryPresenceImpl;
        public AdminUseCase(IAdminRepository repositoryAdminImpl, IUserRepository repositoryUserImpl, IPresenceRepository repositoryPresenceImpl)
        {
            _repositoryAdminImpl = repositoryAdminImpl;
            _repositoryUserImpl = repositoryUserImpl;
            _repositoryPresenceImpl = repositoryPresenceImpl;
        }

        public bool ExcelExport(int groupID){
            var users = _repositoryUserImpl.GetUsersByGroupID(groupID);
            var groupPresences = GetPresenceByGroup(groupID);
            var dates = new List<DateOnly>();
            foreach(var presence in groupPresences){
                if (!dates.Contains(presence.Date)){
                    dates.Add(presence.Date);
                }
            }
            using (var workbook = new XLWorkbook()){
                var worksheet = workbook.Worksheets.Add(groupID);
                worksheet.Cell(1, 1).Value = "FIO";
                worksheet.Range(1, 1, 2, 1).Merge();

                var colIndex = 2;
                foreach (var date in dates) {
                    worksheet.Cell(1, colIndex).Value = date.ToString("dd.MM.yy");
                    worksheet.Range(1, colIndex, 1, colIndex + 8).Merge();
                    colIndex += 9;
                }

                var k = 2;
                foreach(var date in dates){
                    for (int lesson = 1; lesson <= 9; lesson++){
                        worksheet.Cell(2, k).Value = lesson;
                        k++;
                    }
                }

                var lessonColIndex = 2;
                var rowIndex = 3;
                foreach(var user in users){
                    worksheet.Cell(rowIndex, 1).Value = user.FIO;

                    var userPresences = GetPresenceByUser(user.Guid);

                    foreach(var date in dates){
                        for (int lesson = 1; lesson <= 9; lesson++){
                            var presence = userPresences.FirstOrDefault(p => p.Date == date && p.LessonNumber == lesson);
                            if (presence != null){
                                worksheet.Cell(rowIndex, lessonColIndex).Value = presence.IsAttedance ? "Истина" : "Ложь";
                            } else{
                                worksheet.Cell(rowIndex, lessonColIndex).Value = "-";
                            }
                            lessonColIndex++;
                        }
                    }

                    rowIndex++;
                    lessonColIndex = 2;
                }

                workbook.SaveAs($"gruop_{groupID}.xlsx");
            }
            return true;
        }

        public List<Presence> GetPresenceByUser(Guid userGuid){
            var user = _repositoryUserImpl.GetUserByGuid(userGuid);

            var presenceByUser = _repositoryPresenceImpl.GetAllPresences()
            .Where(user => userGuid == user.UserGuid)
            .Select(presence => new Presence{
                User = new User{
                    Guid = user.Guid,
                    Group = new Group{
                        ID = user.GroupID,
                        Name = _repositoryAdminImpl.GetAllGroup().First(group => group.ID == user.GroupID).Name
                    },
                    FIO = user.FIO
                },
                LessonNumber = presence.LessonNumber,
                Date = presence.Date,
                IsAttedance = presence.IsAttedance
            }).ToList();

            return presenceByUser;
        }

        public List<Presence> GetPresenceByGroup(int groupID){
            var usersByGroup = _repositoryUserImpl.GetAllUser()
            .Where(user => user.GroupID == groupID).ToList();

            var presenceByGroup = _repositoryPresenceImpl.GetAllPresences()
            .Where(x => usersByGroup.Any(user => user.Guid == x.UserGuid))
            .Select(presence => new Presence{
                User = new User{
                    Guid = presence.UserGuid,
                    Group = new Group{
                        ID = groupID,
                        Name = _repositoryAdminImpl.GetAllGroup().First(group => group.ID == groupID).Name
                    },
                    FIO = usersByGroup.First(user => user.Guid == presence.UserGuid).FIO, 
                },
                LessonNumber = presence.LessonNumber,
                Date = presence.Date,
                IsAttedance = presence.IsAttedance
            }).ToList();

            return presenceByGroup;
        }
    }
}