from django.db import models
from django.db.models.deletion import SET_DEFAULT
from django.db.models.fields.related import ManyToManyField
from django.urls import reverse
import uuid
from home.models import Room, Semester, Study
from datetime import timedelta
from internal.models import Member
from django.template.defaultfilters import slugify
from django.http import HttpResponse
from django.utils import timezone
from lxml import etree
import html

from icalendar import Calendar, Event
from icalendar import vCalAddress, vText
from datetime import datetime
import pytz

from django.db.models.signals import post_save
from django.dispatch import receiver
# from embed_video.fields import EmbedVideoField


def create_slug_seminar(input):
    slug = slugify(input)
    qs = Seminar.objects.filter(slug=slug)
    exists = qs.exists()
    #if exists:
    #    slug = slug + str(qs.first().id)
    return slug



def generate_xml_file_lxml():
    root = etree.Element('events')

    for seminar in Seminar.objects.filter(showPublic=True).filter(start_time__gte=timezone.now()).filter(external=False).filter(internal_talk=False).filter(internal_status_talk=False):
        event_element = etree.SubElement(root, 'event')

        id_element = etree.SubElement(event_element, 'id')
        id_element.text = str(seminar.id)

        title_element = etree.SubElement(event_element, 'title')
        title_element.text = seminar.title

        dates = etree.SubElement(event_element, 'dates')
        date = etree.SubElement(dates, 'date')

        local_start_time = timezone.localtime(seminar.start_time)
        # Startdatum und -zeit
        date_start_element = etree.SubElement(date, 'date_start')
        date_start_element.text = local_start_time.strftime("%d.%m.%Y")

        time_start_element = etree.SubElement(date, 'time_start')
        time_start_element.text = local_start_time.strftime("%H:%M")

        # Ende-Datum und -Zeit (Hier müssen Sie Ihre eigene Logik hinzufügen)
        date_end_element = etree.SubElement(date, 'date_end')
        date_end_element.text = local_start_time.strftime("%d.%m.%Y")  # Beispielwert

        end_time = local_start_time + timedelta(hours=2)
        time_end_element = etree.SubElement(date, 'time_end')
        time_end_element.text = end_time.strftime("%H:%M")  # Beispielwert

        # Organizer
        #organizer_element = etree.SubElement(event_element, 'organizer')
        #organizer_element.text = seminar.organisator_name

        # Location (Fester Wert oder aus Modell)
        
        if seminar.room is not None:
            location_element = etree.SubElement(event_element, 'location')
            location_element.text = f'{seminar.room.building.long_name} - {seminar.room.name}'

        # Sprecher
        speaker = etree.SubElement(event_element, 'speaker')
        speaker_name = etree.SubElement(speaker, 'name')
        speaker_name.text = seminar.speaker_name if seminar.speaker_name else ''
        if seminar.speaker_affiliation:
            speaker_from = etree.SubElement(speaker, 'from')
            speaker_from.text = seminar.speaker_affiliation

        # Abstract
        if seminar.abstract:
            description = etree.SubElement(event_element, 'description')
            description.text = html.unescape(seminar.abstract)

        host_element = etree.SubElement(event_element, 'host')
        #host_element.text = 'Gianaurelio Cuniberti'
        host_element.text = seminar.organisator_name

        serie_element = etree.SubElement(event_element, 'serie')
        serie_element.text = 'SERIE_TUD_NANO'

        language_element = etree.SubElement(event_element, 'language')
        language_element.text = 'en'

        # URLs
        urls = etree.SubElement(event_element, 'urls')
        #if seminar.video_conf:
        #    url = etree.SubElement(urls, 'url')
        #    url_name = etree.SubElement(url, 'name')
        #    url_name.text = f'Zoom link'
        #    url_source = etree.SubElement(url, 'source')
        #    url_source.text = f'{seminar.video_conf}'
        url2 = etree.SubElement(urls, 'url')
        url2_name = etree.SubElement(url2, 'name')
        url2_name.text = f'More information'
        url2_source = etree.SubElement(url2, 'source')
        url2_source.text = f'https://nano.tu-dresden.de{seminar.get_absolute_url()}'
        # Topics
        maintopic= etree.SubElement(event_element, 'maintopic')
        maintopic.text=seminar.dsc_topic
        topics = etree.SubElement(event_element, 'topics')
        topic = etree.SubElement(topics, 'topic')
        topic_id = etree.SubElement(topic, 'id')
        topic_id.text=seminar.dsc_subtopic

    xml_str = etree.tostring(root, pretty_print=True, encoding='UTF-8')
    with open('/data/uploads/seminar/xml/pmn_dsc.xml', 'wb') as file:  # file for dresden science calendar
        file.write(xml_str)



class Seminar(models.Model):
    start_time = models.DateTimeField()
    title = models.TextField(max_length=500)
    abstract = models.TextField(max_length=5000, null=True, blank=True)
    speaker_name = models.CharField('Speaker name', max_length=200, null=True, help_text='Prof. Max Müller' )
    speaker_affiliation = models.CharField('Affiliation', max_length=200, help_text='', null=True, blank=True)
    speaker_url = models.URLField('Affiliation url', max_length=300, null=True, blank=True,help_text='Link to external speaker profile at institution/company webpage')
    speaker_cv = models.TextField(max_length=5000, null=True, blank=True)
    #
    chair_related_speaker = models.ManyToManyField(Member,related_name='seminar_chair_related_speaker', default=None,blank=True,verbose_name='chair related speaker',help_text='Please fill this field if the speaker is a member or an alumnus of our chair.')
    internal_talk = models.BooleanField(verbose_name='Chair internal talk?',default=False,help_text='Will not shown in Dresden Science Calendar')
    internal_status_talk = models.BooleanField(verbose_name='Chair internal status talk?',default=False,help_text='Will not shown in Dresden Science Calendar')
    alumni_talk = models.BooleanField(verbose_name='Alumnus/Alumna talk?',help_text='If yes, please add the person as "chair related speaker" in the speaker options. Then "Alumnus talk" or "Alumna talk" will be added in front of the title automatically.',default=False)
    external = models.BooleanField(verbose_name='Externally organized talk?',default=False, help_text='Externally organized seminar? (Will not shown in Dresden Science Calendar)')
    external_organized_by = models.CharField(verbose_name='Talk externally organized by ...', null=True,blank=True, max_length=200,help_text='If this seminar is organized by our chair, please leave this field blank. Else please continue the sentence "Talk externally organized by"')
    #
    tud_fis=models.URLField('FIS (TUD)', max_length = 200,default=None, null=True, blank=True)
    linkedin = models.URLField('Linkedin',max_length = 200, default=None, null=True, blank=True)
    xing = models.URLField('Xing',max_length = 200, default=None, null=True, blank=True)
    orcid = models.URLField('ORCID',max_length = 200,default=None, null=True, blank=True)
    researchgate = models.URLField('Researchgate', max_length = 200, default=None, null=True, blank=True)
    researcher_id = models.URLField('publons', max_length = 200,default=None, null=True, blank=True)
    research = models.URLField('Research.com', max_length = 200,default=None, null=True, blank=True)
    googlescholar = models.URLField('Google Scholar', max_length = 200,default=None, null=True, blank=True)
    scopus = models.URLField('Scopus', max_length = 200,default=None, null=True, blank=True)
    adscientificindex = models.URLField('Ad scientific index', max_length = 200,default=None, null=True, blank=True)
    gepris = models.URLField('Gepris', max_length = 200,default=None, null=True, blank=True)
    github = models.URLField('Github', max_length = 200,default=None, null=True, blank=True)
    twitter = models.URLField('Twitter', max_length = 200,default=None, null=True, blank=True)
    wiki = models.URLField('Wikipedia', max_length = 200,default=None, null=True, blank=True)
    #
    image = models.ImageField(upload_to='uploads/members/img/', null=True, blank=True)
    announcement = models.FileField(upload_to='uploads/seminar/announcements', null=True, blank=True)
    slides = models.FileField(upload_to='uploads/seminar/slides', null=True, blank=True)
    slides_public = models.BooleanField('Public access to slides', default=False, help_text='Offer the slides public for download')
    recorded_seminar = models.FileField(upload_to='uploads/seminar/records', null=True, blank=True)
    record_public = models.BooleanField('Public access to record', default=False, help_text='Offer the record public for download')
    room = models.ForeignKey(Room, on_delete = models.SET_NULL,null=True, blank=True)
    video_conf = models.URLField('Video conference link', blank=True, null=True, default='https://tu-dresden.zoom-x.de/j/99351537743?pwd=ck01MHE2MktNZ29NK1ZnR1VKb2ZXUT09')
    video_conf_display_name = models.CharField('Displayed name for video conference link', default='Zoom link of our Chair', max_length=200, null=True, blank=True,help_text='This is the displayed name und webpage, where you will be redirected to video conference link if you click there.' )
    showPublic = models.BooleanField(verbose_name='Show on webpage',default=True,help_text='If true show seminar on webpage')
    #
    choices = (
            ('TOPIC_BIOLOGY','TOPIC_BIOLOGY'),
            ('TOPIC_PHYSICS','TOPIC_PHYSICS'),
            ('TOPIC_MATHEMATICS','TOPIC_MATHEMATICS'),
            ('TOPIC_COMPUTER_SCIENCE','TOPIC_COMPUTER_SCIENCE'),
            ('TOPIC_CHEMISTRY','TOPIC_CHEMISTRY'),
            ('TOPIC_MEDICINE','TOPIC_MEDICINE'),
            ('TOPIC_PSYCHOLOGY','TOPIC_PSYCHOLOGY'),
            ('TOPIC_ELECENGANDINFTECH','TOPIC_ELECENGANDINFTECH'),
            ('TOPIC_MECHANICALENGINEERING','TOPIC_MECHANICALENGINEERING'),
            ('TOPIC_MATERIALS','TOPIC_MATERIALS'),
            ('TOPIC_CIVILENGINEERING','TOPIC_CIVILENGINEERING'),
            ('TOPIC_TRANSPORTATIONANDTRAFFIC','TOPIC_TRANSPORTATIONANDTRAFFIC'),
            ('TOPIC_FORESTGEOHYDRO','TOPIC_FORESTGEOHYDRO'),
            ('TOPIC_SOCIETY','TOPIC_SOCIETY'),
            ('TOPIC_LINGUISTICSLITERATURECULTURE','TOPIC_LINGUISTICSLITERATURECULTURE'),
            ('TOPIC_LAW','TOPIC_LAW'),
            ('TOPIC_ECONOMICS','TOPIC_ECONOMICS'),
            ('TOPIC_TRAINING','TOPIC_TRAINING'),
            ('TOPIC_TRANSFER','TOPIC_TRANSFER'),
            ('TOPIC_OTHER','TOPIC_OTHER'),
    )
    dsc_topic = models.CharField('Topic for Dresden Science Calendar',null=True, max_length=50,choices=choices,help_text='will displayed in Dresden Science Calendar')
    dsc_subtopic = models.CharField('Subtopic for Dresden Science Calendar',null=True, max_length=50,choices=choices,help_text='will displayed in Dresden Science Calendar')
    #
    slug=models.SlugField(max_length=50, null=True, blank=True,unique=True, help_text="URL where seminar is shown")
    #
    suggested_by = models.ManyToManyField(Member,related_name='seminar_suggested_by', default=None,blank=True)
    suggestion_date = models.DateField('Suggested on',null=True, help_text='The date when you got the suggestion.',blank=True)
    invited_by = models.ManyToManyField(Member,related_name='seminar_invited_by', default=None,blank=True)
    organisator_email = models.CharField('Contact email', max_length=200, default="seminar.nano@tu-dresden.de",help_text='will displayed in ics file (calendar event)' )
    organisator_name =  models.CharField('Contact person',null=True, max_length=200,default='Arezoo Dianat',help_text='will displayed in ics-file (calendar event) and in Dresden Science Calendar')
    notes_internal = models.TextField('Internal Notes',null=True, max_length=1000,help_text='Example: Speaker wants to talk with theory group after presentation.',blank=True)

    def get_absolute_url(self):
        """Returns the url to access a detail record for this Seminar."""
        # return reverse('seminar-detail', args=[str(self.id)])
        return reverse('seminar-detail', kwargs={'slug':self.slug})
    
        
    def __str__(self):
        """String for representing the Model object."""
        return self.speaker_name +': ' + self.title
    

    def save(self, *args, **kwargs):
        # update slug
        #
        #if not self.slug:
        try:
            new_name=self.speaker_name
            if 'Dr.-Ing. ' in new_name:
                new_name=new_name.replace('Dr.-Ing. ','')
                self.speaker_name=new_name
            if 'Dr.-Ing.' in new_name:
                new_name=new_name.replace('Dr.-Ing.','')
                self.speaker_name=new_name
            if 'Dr. ' in new_name:
                new_name=new_name.replace('Dr. ','')
                self.speaker_name=new_name
            if 'Dr.' in new_name:
                new_name=new_name.replace('Dr.','')
                self.speaker_name=new_name
            if 'Prof. ' in new_name:
                new_name=new_name.replace('Prof. ','')
                self.speaker_name=new_name
            if 'Prof.' in new_name:
                new_name=new_name.replace('Prof.','')
                self.speaker_name=new_name
            if 'Professor' in new_name:
                new_name=new_name.replace('Professor','')
                self.speaker_name=new_name
            if 'Msc. ' in new_name:
                new_name=new_name.replace('Msc. ','')
                self.speaker_name=new_name
            if 'Msc.' in new_name:
                new_name=new_name.replace('Msc.','')
                self.speaker_name=new_name
            if 'habil. ' in new_name:
                new_name=new_name.replace('habil. ','')
                self.speaker_name=new_name
            if 'habil.' in new_name:
                new_name=new_name.replace('habil.','')
                self.speaker_name=new_name
            day=self.start_time.day
            month=self.start_time.month
            if len(str(month))==1:
                month='0'+str(month)
            if len(str(day))==1:
                day='0'+str(day)
            if self.start_time == None or self.start_time=='':
                argument = str(self.speaker_name).split(' ')[-1] + '_' + self.title
            else:
                argument =str(self.start_time.year)+'_'+ str(month)+'_'+str(day)+'_'+self.speaker_name
        except:
            from random import randrange
            argument=str(randrange(1000))
        self.slug =  create_slug_seminar(argument)
        #generate_xml_file_lxml()
        #
        # update attribute 'internal_talk'
        ## Commented, because error if new seminar schould added
        #if self.chair_related_speaker.exists() and not self.alumni_talk:
        #    self.internal_talk = True
        return super().save(*args, **kwargs)
    


    class Meta:
        ordering = ['start_time']


@receiver(post_save, sender=Seminar)
def generate_xml_after_save(sender, instance, **kwargs):
    generate_xml_file_lxml()


class Teaching_course(models.Model):
    name = models.CharField('Name of course', max_length=100, null=True)
    show_public = models.BooleanField(default=True, help_text='Show public?')
    study = models.ManyToManyField(Study,'Study', max_length=100)
    description = models.TextField('Description', max_length=5000)
    module_plan_link = models.URLField('Link to module plan', max_length=800, help_text='', null=True, blank=True)
    module_ressources = models.URLField('Link to OPAL', max_length=800, help_text='', null=True, blank=True)
    image = models.ImageField(upload_to='uploads/img/', null=True, blank=True)
    announcement = models.FileField(upload_to='uploads/teaching_course/announcements', null=True, blank=True)
    responsible_person = models.ManyToManyField(Member,related_name='teaching_course_responsible_person', default=None)
    teacher = models.ManyToManyField(Member,related_name='teacher', default=None)
    tutor = models.ManyToManyField(Member,related_name='tutor', default=None,blank=True)
    semester = models.ForeignKey(Semester, default=None, blank=True,related_name='teaching_course_semester',null=True, on_delete=SET_DEFAULT)
    oldDB_schedule=models.CharField('Schedule from old website', max_length=200, null=True, blank=True)
    
    def __str__(self):
        """String for representing the Model object."""
        return self.name
    
    def get_absolute_url(self):
        """Returns the url to access a detail record for this teaching course."""
        return reverse('teaching_course-detail', args=[str(self.id)])

    class Meta:
        verbose_name_plural='Teaching courses'
        ordering = ['-semester__start_date']

class Schedule(models.Model):
    teaching_course = models.ForeignKey(Teaching_course, default=None, on_delete=models.CASCADE,related_name='schedule_teaching_course')
    lesson_choices= [ ('Lecture','Lecture'), ('Exercise','Exercise'),('Practicum','Practicum')]
    lesson = models.CharField('Kind of lesson',max_length=50, default='Lecture', choices=lesson_choices,null=True)
    day_choices = [ ('Monday','Monday'), ('Tuesday','Tuesday'),('Wednesday','Wednesday'),('Thursday','Thursday'),('Friday','Friday'),('Saturday','Saturday')]
    day = models.CharField('Course day',max_length=50, default='Monday', choices=day_choices,null=True)
    startTime = models.TimeField('Start time',help_text='formart: h:m:s (11:10:00)',default='11:10:00',null=True)
    endTime = models.TimeField('End time',help_text='formart: h:m:s (12:40:00)',default='12:40:00',null=True)
    room = models.ManyToManyField(Room,blank=True)
    video_conf = models.CharField('Video conference tool',max_length=50, default=None,null=True,help_text='e.g. Zoom, Jitsi',blank=True)

    def __str__(self):
        """String for representing the Model object."""
        return str(self.day)+' - '+str(self.startTime)+' - '+str(self.endTime)
        # return f'{self.lesson} | { self.day } | { self.startTime } - { self.endTime }'
