using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Text;
using System.Diagnostics;
using System.Windows;

namespace Sched.CustomClasses
{
    public class Lesson : INotifyPropertyChanged
    {
        //Database lesson
        int _id;
        int _courseId;
        int _lessonTypeId;
        int _periodicity;
        int _nhours;
        int _periodStart;
        //private string _startDate;
        DateTime _startDateDT;
        string _note;
        int _semesterId;

        //Intermediary Tables in DB
        ObservableCollection<int> _teachers = new ObservableCollection<int>();
        ObservableCollection<int> _rooms = new ObservableCollection<int>();
        ObservableCollection<int> _groups = new ObservableCollection<int>();

        //Additional
        string _infoString = "";

        public int Id
        {
            get { return _id; }
            set { _id = value; OnPropertyChanged("Id"); }
        }
        public int CourseId
        {
            get { return _courseId; }
            set { _courseId = value; OnPropertyChanged("CourseId"); }
        }
        public int LessonTypeId
        {
            get { return _lessonTypeId; }
            set { _lessonTypeId = value; OnPropertyChanged("LessonTypeId"); }
        }
        public int Periodicity
        {
            get { return _periodicity; }
            set
            {
                if ((value >= 0) && (value <= 2))
                {
                    _periodicity = value;
                    OnPropertyChanged("Periodicity");
                }
            }

        }
        public int PeriodStart
        {
            get { return _periodStart; }
            set { _periodStart = value; OnPropertyChanged("PeriodStart"); }
        }
        public int Hours
        {
            get { return _nhours; }
            set
            {
                if ((value > 0) && (value <= 15))
                {
                    _nhours = value;
                    OnPropertyChanged("nHours");
                }
            }
        }
        public DateTime StartDateDT
        {
            get { return _startDateDT; }
            set
            {
                _startDateDT = value;
                //_startDate = value.ToString("s", System.Globalization.CultureInfo.InvariantCulture);
                OnPropertyChanged("StartDateDT");
            }
        }
        public string Note
        {
            get { return _note; }
            set { _note = value; OnPropertyChanged("Note"); }
        }

        public int SemesterId
        {
            get { return _semesterId; }
            set { _semesterId = value; OnPropertyChanged("SemesterId"); }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string info)
        {
            var handler = PropertyChanged;
            handler?.Invoke(this, new PropertyChangedEventArgs(info));
        }

        public Lesson()
        {
            this.Id = 0;
            this.CourseId = -1;
            this.LessonTypeId = -1;
            this.Periodicity = 1;
            this.Hours = 2;
            this.PeriodStart = 0;
            this.StartDateDT = DateTime.Today;
            this.Note = string.Empty;
            this.SemesterId = 0;
        }

        public Lesson(Lesson lsn2)
        {
            this.Id = lsn2.Id;
            this.CourseId = lsn2.CourseId;
            this.LessonTypeId = lsn2.LessonTypeId;
            this.Periodicity = lsn2.Periodicity;
            this.Hours = lsn2.Hours;
            this.PeriodStart = lsn2.PeriodStart;
            this.StartDateDT = lsn2.StartDateDT;
            this.Note = lsn2.Note;
            this.SemesterId = lsn2.SemesterId;

            foreach (int Id in lsn2.GetEntities("Teacher"))
            {
                this._teachers.Add(Id);
            }
            foreach (int Id in lsn2.GetEntities("Room"))
            {
                this._rooms.Add(Id);
            }
            foreach (int Id in lsn2.GetEntities("StudentGroup"))
            {
                this._groups.Add(Id);
            }
        }

        public override string ToString()
        {
            string courseAbbreviation = DBI.SelectReturnSingleValue("Course", "Abbreviation", _courseId);
            string lessonTypeAbbreviation = DBI.SelectReturnSingleValue("LessonType", "Abbreviation", _lessonTypeId);
            return $"{courseAbbreviation} {lessonTypeAbbreviation} ({_id})";
        }

        private void ConstructInfoText()
        {
            string _courseAbbreviation = DBI.SelectReturnSingleValue("Course", "Abbreviation", _courseId);
            string _lessonTypeAbbreviation = DBI.SelectReturnSingleValue("LessonType", "Abbreviation", _lessonTypeId);

            string txt = "";
            txt += $"{_courseAbbreviation} ({_lessonTypeAbbreviation}) ";

            
            if (_periodicity == 0)
            {
                txt += $"{StartDateDT.Day}.{StartDateDT.Month}.";
            }
            else if (_periodicity == 2)
            {
                int nthWeek = Semester.GetWeekParity(StartDateDT);
                if ((nthWeek % 2) == 0) //even week
                {
                    txt += "Str_Even";
                }
                else
                {
                    txt += "Str_Odd";
                }  
            }
            txt += "\n";
            

            string allRooms = "";
            foreach (int Id in _rooms)
            {
                if (allRooms != "")
                {
                    allRooms += ", ";
                }
                allRooms += DBI.SelectReturnSingleValue("Room", "Name", Id);
                //Debug.WriteLine(allRooms);
            }
            txt += allRooms + "\n";

            string allTeachers = "";
            foreach (int Id in _teachers)
            {
                if (allTeachers != "")
                {
                    allTeachers += "\n";
                }
                allTeachers += DBI.SelectFullName(Id);
                //Debug.WriteLine(allTeachers);
            }
            txt += allTeachers + "\n";

            string allGroups = "";
            foreach (int Id in _groups)
            {
                if (allGroups != "")
                {
                    allGroups += ", ";
                }
                allGroups += DBI.SelectReturnSingleValue("StudentGroup", "Name", Id);
                //Debug.WriteLine(allGroups);
            }
            txt += allGroups;

            if(_note.Length > 0)
            {
                txt += "\n" + _note;
            }

            _infoString = txt;
        }

        /*
         All classes are saved to DB by reading their properties.
         Fields that are taken from other tables must thus be accessed differently.
         */
        public string GetInfoString()
        {
            ConstructInfoText();
            return _infoString;
        }
        public string GetInfoStringExtended()
        {
            string infoExtended = GetInfoString();
            infoExtended += "\nStr_StartDateDT: " + StartDateDT.ToShortDateString();
            infoExtended += "\nStr_PeriodStart: " + (PeriodStart + 1).ToString();
            infoExtended += "\nStr_Periodicity: " + Periodicity.ToString();
            return infoExtended;
        }
        public ObservableCollection<int> GetEntities(string categoryName)
        {
            if (categoryName == "Teacher")
            {
                return _teachers;
            }
            if (categoryName == "Room")
            {
                return _rooms;
            }
            if (categoryName == "StudentGroup")
            {
                return _groups;
            }


            return _groups;
        }
        public void SetEntities(string categoryName, List<int> idsList)
        {
            ObservableCollection<int> coll = GetEntities(categoryName);
            coll.Clear();
            foreach(int id in idsList)
            {
                coll.Add(id);
            }

            ConstructInfoText();
        }
        
    }

    public class LessonType : INotifyPropertyChanged
    {
        private int _id = 0;
        private string _abbreviation = string.Empty;
        private string _description = string.Empty;
        private string _colorHexcode = "#ff0000";
        public int Id
        {
            get { return _id; }
            set { _id = value; OnPropertyChanged("Id"); }
        }
        public string Abbreviation
        {
            get { return _abbreviation; }
            set { _abbreviation = value; OnPropertyChanged("Abbreviation"); }
        }
        public string Description
        {
            get { return _description; }
            set { _description = value; OnPropertyChanged("Description"); }
        }
        public string ColorHexcode
        {
            get { return _colorHexcode; }
            set
            {
                if ((value.Length == 7) && (value.StartsWith('#')))  // e.g. #ff00ff
                {
                    int tryNum = 0;
                    if (int.TryParse(value.Substring(1), System.Globalization.NumberStyles.HexNumber, null, out tryNum))
                    {
                        _colorHexcode = value;
                        OnPropertyChanged("ColorHexcode");
                    }
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string info)
        {
            var handler = PropertyChanged;
            handler?.Invoke(this, new PropertyChangedEventArgs(info));
        }

        public LessonType()
        {
        }
        public LessonType(int Id, string Abbreviation, string Description, string ColorHexcode)
        {
            this.Id = Id;
            this.Abbreviation = Abbreviation;
            this.Description = Description;
            this.ColorHexcode = ColorHexcode;
        }

        public override string ToString()
        {
            return $"{_abbreviation} - {_description}";
        }
    }

    /*
    public class LessonRoom : INotifyPropertyChanged
    {
        private int _lessonId = 0;
        private int _roomId = 0;
        public int LessonId
        {
            get { return _lessonId; }
            set { _lessonId = value; OnPropertyChanged("LessonId"); }
        }
        public int RoomId
        {
            get { return _roomId; }
            set { _roomId = value; OnPropertyChanged("RoomId"); }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string info)
        {
            var handler = PropertyChanged;
            handler?.Invoke(this, new PropertyChangedEventArgs(info));
        }

        public LessonRoom()
        {
        }
        public LessonRoom(int LessonId, int RoomId)
        {
            this.LessonId = LessonId;
            this.RoomId = RoomId;
        }
        public override string ToString()
        {
            return $"LessonId {_lessonId}, RoomId {_roomId}";
        }
    }
    public class LessonTeacher : INotifyPropertyChanged
    {
        private int _lessonId = 0;
        private int _teacherId = 0;
        public int LessonId
        {
            get { return _lessonId; }
            set { _lessonId = value; OnPropertyChanged("LessonId"); }
        }
        public int TeacherId
        {
            get { return _teacherId; }
            set { _teacherId = value; OnPropertyChanged("TeacherId"); }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string info)
        {
            var handler = PropertyChanged;
            handler?.Invoke(this, new PropertyChangedEventArgs(info));
        }

        public LessonTeacher()
        {
        }
        public LessonTeacher(int LessonId, int TeacherId)
        {
            this.LessonId = LessonId;
            this.TeacherId = TeacherId;
        }
        public override string ToString()
        {
            return $"LessonId {_lessonId}, RoomId {_teacherId}";
        }
    }
    public class LessonStudentGroup : INotifyPropertyChanged
    {
        private int _lessonId = 0;
        private int _studentGroupId = 0;
        public int LessonId
        {
            get { return _lessonId; }
            set { _lessonId = value; OnPropertyChanged("LessonId"); }
        }
        public int StudentGroupId
        {
            get { return _studentGroupId; }
            set { _studentGroupId = value; OnPropertyChanged("StudentGroupId"); }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string info)
        {
            var handler = PropertyChanged;
            handler?.Invoke(this, new PropertyChangedEventArgs(info));
        }

        public LessonStudentGroup()
        {
        }
        public LessonStudentGroup(int LessonId, int StudentGroupId)
        {
            this.LessonId = LessonId;
            this.StudentGroupId = StudentGroupId;
        }
        public override string ToString()
        {
            return $"LessonId {_lessonId}, RoomId {_studentGroupId}";
        }
    }
    */
}
