using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using Posechaemost.Data.LocalData.Entity;
using Posechaemost.Data.RemoteData.RemoteDataBase.DAO;
using Posechaemost.Data.Repository;
using Posechaemost.Domain.Models;

namespace Posechaemost.Domain.UseCase
{
    public class PresenceUseCase
    {
        public readonly IUserRepository _userRepository;
        public readonly IPresenceRepository _presenceRepository;
        private readonly IGroupRepository _groupRepository;

        public PresenceUseCase(IPresenceRepository repositoryImpl, 
                                IUserRepository userRepositoryImpl, 
                                IGroupRepository groupRepositoryImpl) {
            _presenceRepository = repositoryImpl;
            _userRepository = userRepositoryImpl;
            _groupRepository = groupRepositoryImpl;
        }

        public List<PresenceDao> GetPresenceByGroup(int groupId) { 
            var users = _userRepository.GetAllUser().Where(x => x.GroupId == groupId).ToList();

            var presenceByGroup = _presenceRepository.GetPresenceByGroup(groupId)
                .Where(x => users.Any(user => user.UserId == x.UserId))
                .Select(presence => new PresenceDao{
                User = new UserDao{
                    UserId = presence.UserId,
                    GroupId = groupId,
                    FIO = users.First(user => user.UserId == presence.UserId).FIO, 
                },
                ClassNumber = presence.ClassNumber,
                Date = presence.Date,
                IsAttendence = presence.IsAttendence
            }).ToList();
            return presenceByGroup;
        }

        public List<PresenceDao> GetPresenceByGroupAndDate(int groupId, DateOnly date) {
            var users = _userRepository.GetAllUser().Where(x => x.GroupId == groupId).ToList();

            var presenceByGroupAndDate = _presenceRepository.GetPresenceByGroupAndDate(groupId, date)
                .Where(x => users.Any(user => user.UserId == x.UserId && x.Date == date))
                .Select(presence => new PresenceDao{
                User = new UserDao{
                    UserId = presence.UserId,
                    GroupId = groupId,
                    FIO = users.First(user => user.UserId == presence.UserId).FIO, 
                },
                ClassNumber = presence.ClassNumber,
                Date = presence.Date,
                IsAttendence = presence.IsAttendence
            }).ToList();
            return presenceByGroupAndDate;
        }

        public bool UncheckAttendence(int firstClass, int lastClass, DateOnly date, int userId) {
            return _presenceRepository.UncheckAttendence(firstClass, lastClass, date, userId);
        }

        public void AddPresence(int firstClass, int lastClass, int groupId,DateOnly date) 
        {
            var users = _userRepository.GetAllUser().Where(x => x.GroupId==groupId).ToList();
            List<PresenceDao> presenceList = new List<PresenceDao>();
            for (int i = firstClass; i < lastClass; i++) 
            {
                foreach (var user in users) 
                {
                    PresenceDao pres = new PresenceDao{ClassNumber = i, Date = date, UserId = user.UserId, User = user};
                    presenceList.Add(pres);
                }   
            }
        }
        public Dictionary<string, int> GetPresenceStatsByGroup(int groupId)
        {
            var stats = new Dictionary<string, int>();
            
            // Получаем всех студентов группы
            var users = _userRepository.GetAllUser().Where(x => x.GroupId == groupId).ToList();
            stats["Количество студентов"] = users.Count;

            // Получаем все записи посещаемости для группы
            var presences = _presenceRepository.GetPresenceByGroup(groupId);
            
            // Считаем количество уникальных занятий
            var uniqueLessons = presences
                .Select(p => new { p.Date, p.ClassNumber })
                .Distinct()
                .Count();
            stats["Количество занятий"] = uniqueLessons;

            // Считаем общую посещаемость
            var totalAttendances = presences.Count(p => p.IsAttendence);
            var totalPossibleAttendances = users.Count * uniqueLessons;
            
            if (totalPossibleAttendances > 0)
            {
                var attendancePercentage = (totalAttendances * 100) / totalPossibleAttendances;
                stats["Процент посещаемости"] = attendancePercentage;
            }
            else 
            {
                stats["Процент посещаемости"] = 0;
            }

            return stats;
        }
        public void GenerateWeeklyPresence(int firstClass, int lastClass, int groupId, DateOnly startDate)
        {
            // Получаем всех студентов группы
            var users = _userRepository.GetAllUser().Where(x => x.GroupId == groupId).ToList();
            
            // Генерируем посещаемость на 7 дней
            for (int day = 0; day < 7; day++)
            {
                var currentDate = startDate.AddDays(day);
                
                // Пропускаем выходные дни (суббота и воскресенье)
                if (currentDate.DayOfWeek == DayOfWeek.Saturday || 
                    currentDate.DayOfWeek == DayOfWeek.Sunday)
                {
                    continue;
                }

                // Для каждой пары в диапазоне
                for (int classNum = firstClass; classNum <= lastClass; classNum++)
                {
                    foreach (var user in users)
                    {
                        var presence = new PresenceDao
                        {
                            ClassNumber = classNum,
                            Date = currentDate,
                            UserId = user.UserId,
                            User = user,
                            GroupId = groupId
                        };
                        
                        _presenceRepository.AddPresence(presence);
                    }
                }
            }
        }
    }
}
