using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using kursovaya.Models;
using Microsoft.EntityFrameworkCore;

namespace kursovaya;

public partial class TeacherWindow : Window
{
    List<DiscGroup> discGroups = new();    
    public ObservableCollection<AttestationPresenterTeacher> AttestationsTeachers = new ObservableCollection<AttestationPresenterTeacher>();
    List<AttestationPresenterTeacher> dataSourceAttestationsTeachers;
    public TeacherWindow()
    {
        InitializeComponent();
    }

    public TeacherWindow(User user) : this()
    {
        var ctx = new DatabaseContext();
        
        var groups = ctx.Groups.ToList();
        var teacherId = ctx.Teachers.FirstOrDefault(t => t.Login == user.Login).Id;
        var disciplinesIds = ctx.Disciplines.Include(d => d.DisciplineTeachers).Where(d => d.DisciplineTeachers.Any(dt => dt.IdTeacher == teacherId)).Select(d => d.Id).ToList();
        var disciplines = ctx.Disciplines.Include(d => d.DisciplineTeachers).Where(d => d.DisciplineTeachers.Any(dt => dt.IdTeacher == teacherId)).ToList();
        dataSourceAttestationsTeachers = ctx.Attestations.Where(a => disciplinesIds.Contains(a.IdDiscipline)).Select(a => new AttestationPresenterTeacher()
        {
            IdUser = a.IdUser,
            IdDiscipline = a.IdDiscipline,
            AttestFirst = a.AttestFirst,
            AttestSecond = a.AttestSecond,
            AttestThird = a.AttestThird,
            Total = a.Total,
            Grade = a.Grade,
            StudentFIO = ctx.Students.Where(s => s.Id == a.IdUser).Select(s => s.Fio).FirstOrDefault(),
        }).ToList();
        foreach (var group in groups)
        {
            foreach (var discipline in disciplines)
            {
                var attestationsToDiscGroup = dataSourceAttestationsTeachers.Where(a => ctx.Students.Any(s => s.Id == a.IdUser && s.IdGroup == group.Id) && a.IdDiscipline == discipline.Id).ToList();
                discGroups.Add(new DiscGroup(){discipline = discipline, group = group, attestations = attestationsToDiscGroup});
            }
        }
        discGroups.RemoveAll(d => d.attestations.Count == 0);
        
        foreach (var discGroup in discGroups)
        {
            Console.WriteLine($"{discGroup.discipline.Name} - {discGroup.group.Id} - {discGroup.attestations.Count}");
        }
        
        GroupComboBox.ItemsSource = discGroups.Select(dg => dg.group.Id).Distinct().ToList();
        DisciplineComboBox.ItemsSource = discGroups.Select(dg => dg.discipline.Name).Distinct().ToList();
        FlatAttestationGrid.ItemsSource = AttestationsTeachers;
    }
    
    public class AttestationPresenterTeacher() : Attestation
    {
        public string StudentFIO { get; set; }
    }
    
    public class DiscGroup
    {
        public Discipline discipline;
        public Group group;
        public List<AttestationPresenterTeacher> attestations = new();
    }
    
    public void DisplayAttestations()
    {
        var ctx = new DatabaseContext();
        var temp = dataSourceAttestationsTeachers;
        AttestationsTeachers.Clear();
    
        if (GroupComboBox.SelectionBoxItem != null)
        {
            var selectedGroupId = Convert.ToInt32(GroupComboBox.SelectedItem);
            temp = temp.Where(ap => ctx.Students.Any(s => s.Id == ap.IdUser && s.IdGroup == selectedGroupId)).ToList();
        }
        
        if (DisciplineComboBox.SelectionBoxItem != null)
        {
            var idDiscipline = ctx.Disciplines.Where(d => d.Name == DisciplineComboBox.SelectionBoxItem)
                .Select(d => d.Id).FirstOrDefault();
            temp = temp.Where(ap => ap.IdDiscipline == idDiscipline).ToList();
        }
        
        Console.WriteLine("Добавлено элементов: " + temp.Count);
        
        foreach (var item in temp)
        {
            AttestationsTeachers.Add(item);
        }
    }

    private void ButtonBack_OnClick(object? sender, RoutedEventArgs e)
    {
        Close();
    }
    
    private void CheckAttest_OnClick(object? sender, RoutedEventArgs e)
    {
        DisplayAttestations();
    }

    private string CalculateGrade(int total, int formAttest)
    {
        string grade = "";
        switch (formAttest)
        {
            case 1:
                if (total >= 90) grade = "отлично";
                else if (total >= 80) grade = "хорошо";
                else if (total >= 70) grade = "удовлетворительно";
                else grade = "неудовлетворительно";
                break;
            case 2:
                if (total >= 90) grade = "отлично";
                else if (total >= 80) grade = "хорошо";
                else if (total >= 70) grade = "удовлетворительно";
                else grade = "неудовлетворительно";
                break;
            case 3:
                if (total >= 70) grade = "зачтено";
                else grade = "не зачтено";
                break;
        }
        return grade;
    }
    
    private async void FirstAttest_OnClick(object? sender, RoutedEventArgs e)
    {
        if (sender is Button button && button.Tag is AttestationPresenterTeacher attestation)
        {
            EditAttestWindow editAttestWindow = new EditAttestWindow(1);
            var newFirstAttest = await editAttestWindow.ShowDialog<int>(this);
            var ctx = new DatabaseContext();
            var formAttest = ctx.Disciplines.FirstOrDefault(d => d.Id == attestation.IdDiscipline).IdFormAttest;
            
            Attestation newAttestation = new Attestation()
            {
                IdUser = attestation.IdUser,
                IdDiscipline = attestation.IdDiscipline,
                AttestFirst = newFirstAttest,
                AttestSecond = attestation.AttestSecond,
                AttestThird = attestation.AttestThird,
                Total = newFirstAttest + attestation.AttestSecond + attestation.AttestThird,
                Grade = CalculateGrade(newFirstAttest + attestation.AttestSecond + attestation.AttestThird, formAttest),
            };
            
            ctx.Attestations.Update(newAttestation);
            await ctx.SaveChangesAsync();
            
            dataSourceAttestationsTeachers.Remove(attestation);
            dataSourceAttestationsTeachers.Add(new AttestationPresenterTeacher()
            {
                IdUser = newAttestation.IdUser,
                IdDiscipline = newAttestation.IdDiscipline,
                AttestFirst = newAttestation.AttestFirst,
                AttestSecond = newAttestation.AttestSecond,
                AttestThird = newAttestation.AttestThird,
                Total = newAttestation.Total,
                Grade = newAttestation.Grade,
                StudentFIO = ctx.Students.Where(s => s.Id == newAttestation.IdUser).Select(s => s.Fio).FirstOrDefault()
            });
            DisplayAttestations();
        }
    }
    
    private async void SecondAttest_OnClick(object? sender, RoutedEventArgs e)
    {
        if (sender is Button button && button.Tag is AttestationPresenterTeacher attestation)
        {
            EditAttestWindow editAttestWindow = new EditAttestWindow(2);
            var newSecondAttest = await editAttestWindow.ShowDialog<int>(this);
            var ctx = new DatabaseContext();
            var formAttest = ctx.Disciplines.FirstOrDefault(d => d.Id == attestation.IdDiscipline).IdFormAttest;
            
            Attestation newAttestation = new Attestation()
            {
                IdUser = attestation.IdUser,
                IdDiscipline = attestation.IdDiscipline,
                AttestFirst = attestation.AttestFirst,
                AttestSecond = newSecondAttest,
                AttestThird = attestation.AttestThird,
                Total = attestation.AttestFirst + newSecondAttest + attestation.AttestThird,
                Grade = CalculateGrade(attestation.AttestFirst + newSecondAttest + attestation.AttestThird, formAttest),
            };
            
            ctx.Attestations.Update(newAttestation);
            await ctx.SaveChangesAsync();
            
            dataSourceAttestationsTeachers.Remove(attestation);
            dataSourceAttestationsTeachers.Add(new AttestationPresenterTeacher()
            {
                IdUser = newAttestation.IdUser,
                IdDiscipline = newAttestation.IdDiscipline,
                AttestFirst = newAttestation.AttestFirst,
                AttestSecond = newAttestation.AttestSecond,
                AttestThird = newAttestation.AttestThird,
                Total = newAttestation.Total,
                Grade = newAttestation.Grade,
                StudentFIO = ctx.Students.Where(s => s.Id == newAttestation.IdUser).Select(s => s.Fio).FirstOrDefault()
            });
            DisplayAttestations();
        }
    }
    
    private async void ThirdAttest_OnClick(object? sender, RoutedEventArgs e)
    {
        if (sender is Button button && button.Tag is AttestationPresenterTeacher attestation)
        {
            EditAttestWindow editAttestWindow = new EditAttestWindow(3);
            var newThirdAttest = await editAttestWindow.ShowDialog<int>(this);
            var ctx = new DatabaseContext();
            var formAttest = ctx.Disciplines.FirstOrDefault(d => d.Id == attestation.IdDiscipline).IdFormAttest;
            
            Attestation newAttestation = new Attestation()
            {
                IdUser = attestation.IdUser,
                IdDiscipline = attestation.IdDiscipline,
                AttestFirst = attestation.AttestFirst,
                AttestSecond = attestation.AttestSecond,
                AttestThird = newThirdAttest,
                Total = attestation.AttestFirst + attestation.AttestSecond + newThirdAttest,
                Grade = CalculateGrade(attestation.AttestFirst + attestation.AttestSecond + newThirdAttest, formAttest),
            };
            
            ctx.Attestations.Update(newAttestation);
            await ctx.SaveChangesAsync();
            
            dataSourceAttestationsTeachers.Remove(attestation);
            dataSourceAttestationsTeachers.Add(new AttestationPresenterTeacher()
            {
                IdUser = newAttestation.IdUser,
                IdDiscipline = newAttestation.IdDiscipline,
                AttestFirst = newAttestation.AttestFirst,
                AttestSecond = newAttestation.AttestSecond,
                AttestThird = newAttestation.AttestThird,
                Total = newAttestation.Total,
                Grade = newAttestation.Grade,
                StudentFIO = ctx.Students.Where(s => s.Id == newAttestation.IdUser).Select(s => s.Fio).FirstOrDefault()
            });
            DisplayAttestations();
        }
    }
}