using ClosedXML.Excel;
using data.RemoteData.RemoteDataBase.DAO;
using data.Repository;
using data.domain.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using data.RemoteData.RemoteDatabase.DAO;
using data.RemoteData.RemoteDataBase;

namespace data.Domain.UseCase
{
    public class UseCaseGeneratePresence
    {
        public readonly IUserRepository _userRepository;
        public readonly IPresenceRepository _presenceRepository;
        public readonly IGroupRepository _groupRepository;

        public UseCaseGeneratePresence(IUserRepository userRepository, IPresenceRepository presenceRepository, IGroupRepository groupRepository)
        {
            _userRepository = userRepository;
            _presenceRepository = presenceRepository;
            _groupRepository = groupRepository;
        }

        public Dictionary<string, List<AttendanceRecord>> GetAllAttendanceByGroups()
        {
            var attendanceByGroup = new Dictionary<string, List<AttendanceRecord>>();
            var allGroups = _groupRepository.GetAllGroups();

            foreach (var group in allGroups)
            {
                var groupAttendance = _presenceRepository.GetAttendanceByGroup(group.Id);
                var attendanceRecords = new List<AttendanceRecord>();

                foreach (var record in groupAttendance)
                {
                    var names = _userRepository.GetUserNames().Where(u => u.UserId == record.UserId);
                    foreach (var name in names)
                    {
                        attendanceRecords.Add(new AttendanceRecord
                        {
                            UserName = name.FIO,
                            UserId = name.UserId,
                            Date = record.Date,
                            IsAttedance = record.IsAttedance,
                            LessonNumber = record.LessonNumber,
                            GroupName = group.Name
                        });
                    }
                }

                attendanceByGroup.Add(group.Name, attendanceRecords);
            }

            return attendanceByGroup;
        }

        public void ExportAttendanceToExcel()
        {
            var attendanceByGroup = GetAllAttendanceByGroups();
            string projectDirectory = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.FullName;
            string reportsFolderPath = Path.Combine(projectDirectory, "Reports");
            string filePath = Path.Combine(reportsFolderPath, "AttendanceReport.xlsx");

            // Создаем папку, если она не существует
            if (!Directory.Exists(reportsFolderPath))
            {
                Directory.CreateDirectory(reportsFolderPath);
            }
            using (var workbook = new XLWorkbook())
            {
                foreach (var group in attendanceByGroup)
                {
                    var worksheet = workbook.Worksheets.Add($"{group.Key}");
                    worksheet.Cell(1, 1).Value = "ФИО";
                    worksheet.Cell(1, 2).Value = "Группа";
                    worksheet.Cell(1, 3).Value = "Дата";
                    worksheet.Cell(1, 4).Value = "Занятие";
                    worksheet.Cell(1, 5).Value = "Статус";

                    int row = 2;
                    int lesNum = 1;
                    foreach (var record in group.Value.OrderBy(r => r.Date).ThenBy(r => r.LessonNumber).ThenBy(r => r.UserId))
                    {
                        if (lesNum != record.LessonNumber)
                        {
                            row++;
                        }
                        worksheet.Cell(row, 1).Value = record.UserName;
                        worksheet.Cell(row, 2).Value = record.GroupName;
                        worksheet.Cell(row, 3).Value = record.Date.ToString("dd.MM.yyyy");
                        worksheet.Cell(row, 4).Value = record.LessonNumber;
                        worksheet.Cell(row, 5).Value = record.IsAttedance ? "Присутствует" : "Отсутствует";
                        row++;



                        lesNum = record.LessonNumber;
                    }

                    worksheet.Columns().AdjustToContents();
                }

                workbook.SaveAs(filePath);
            }
        }




        public List<PresenceDao> GetPresenceByDateAndGroup(DateTime date, int groupId)
        {
            return _presenceRepository.GetPresenceByDateAndGroup(date, groupId);
        }

        public void GeneratePresenceDaily(int firstLesson, int lastLesson, int groupId)
        {
            var users = _userRepository.GetAllUsers().Where(u => u.GroupId == groupId).ToList();

            // Находим последнюю дату посещаемости для данной группы
            DateOnly startDate = _presenceRepository.GetLastDateByGroupId(groupId)?.AddDays(1)
                                 ?? DateOnly.FromDateTime(DateTime.Today);

            List<PresenceDao> presences = new List<PresenceDao>();
            for (int lessonNumber = firstLesson; lessonNumber <= lastLesson; lessonNumber++)
            {
                foreach (var user in users)
                {
                    var presence = new PresenceDao
                    {
                        UserId = user.UserId,
                        GroupId = user.GroupId,
                        Date = startDate,
                        LessonNumber = lessonNumber,
                        IsAttedance = true
                    };
                    _presenceRepository.SavePresence(new List<PresenceDao> { presence });
                }
            }
        }




        public void GenerateWeeklyPresence(int firstLesson, int lastLesson, int groupId, DateTime startTime)
        {
            for (int i = 0; i < 7; i++)
            {
                DateTime currentTime = startTime.AddDays(i);
                GeneratePresenceDaily(firstLesson, lastLesson, groupId);
            }
        }



        // Отметить пользователя как отсутствующего на диапазоне занятий
        public bool MarkUserAbsentForLessons(int userId, int groupId, int firstLesson, int lastLesson, DateTime date)
        {
            List<PresenceDao> presences = _presenceRepository.GetPresenceForAbsent(date, groupId);
            if (presences.Where(p => p.UserId == userId).Count() > 0)
            {
                // Обновляем состояние присутствия для указанных занятий
                foreach (var presence in presences.Where(p => p.UserId == userId && p.LessonNumber >= firstLesson && p.LessonNumber <= lastLesson))
                {
                    presence.IsAttedance = false; // Устанавливаем отсутствие
                }
                // Сохраняем изменения в репозитории
                _presenceRepository.UpdateAtt(userId, groupId, firstLesson, lastLesson, DateOnly.FromDateTime(date), false);
                return true;
            }
            else
            {
                return false;
            }
        }

        public List<PresenceDao> GetAllPresenceByGroup(int groupId)
        {
            return _presenceRepository.GetPresenceByGroup(groupId);
        }

        public GroupAttendanceStatistics GetGeneralPresence(int groupId)
        {
            return _presenceRepository.GetGeneralPresenceForGroup(groupId);
        }

        public List<AllPresence> GetPresenceAll(DateOnly dateStart, DateOnly dateEnd, int GroupId, int UserId)
        {
            return _presenceRepository.AllPresence(GroupId, dateEnd, dateStart, UserId); ;
        }

        public void UpdateAttendance(List<AttendanceInputModel>attList)
        {
            _presenceRepository.UpdateAttendance(attList);
        }

        // Удаление посещаемости для группы
        public void DeletePresenceByGroup(int groupId)
        {
            var presences = _presenceRepository.GetPresenceByGroup(groupId);
            _presenceRepository.DeletePresences(presences);
        }

        // Удаление посещаемости для пользователя
        public void DeletePresenceByUser(int groupId, int userId)
        {
            var presences = _presenceRepository.GetPresenceByUserAndGroup(userId, groupId);
            _presenceRepository.DeletePresences(presences);
        }

        // Удаление посещаемости по диапазону дат
        public void DeletePresenceByDateRange(int groupId, DateOnly startDate, DateOnly endDate)
        {
            var presences = _presenceRepository.GetPresenceByDateRange(groupId, startDate, endDate);
            _presenceRepository.DeletePresences(presences);
        }

        public void MarkUserAbsent(int userId, int groupId, DateOnly date, int lessonNumber)
        {
            _presenceRepository.UpdateAttendance(userId, groupId, date, lessonNumber, false);  // false — отсутствие
        }

    }
}
