from django.db import models
from django.contrib.auth.models import User
from colorfield.fields import ColorField
from datetime import datetime
from django.db.models import Max
from django.utils import timezone
from django.db.models import Sum, F
from datetime import timedelta


# Create your models here.

class Reference(models.Model):
    name = models.CharField(max_length=50)
    date = models.CharField(max_length=200)
    def __str__(self):
        return self.name
    def formatted_date(self):
        # Assuming start_date is stored as "day-month-year"
        parts = self.date.split('-')
        return f"{parts[2]}-{parts[1]}-{parts[0]}"


class Tag(models.Model):
    name = models.CharField(max_length=50)


class BusinessType(models.Model):
    name = models.CharField(max_length=50)


class Business(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField(unique=True)
    financial_number = models.CharField(max_length=50)
    vat = models.BooleanField(default=False)
    commercial_registration = models.CharField(max_length=50)
    phone_number = models.CharField(max_length=50)
    website =  models.URLField(null=True)
    type = models.ForeignKey(BusinessType, on_delete=models.CASCADE, null=True, blank=True)
    logo = models.ImageField()
    business_id = models.CharField(max_length=20, null=True, blank=True)  # Allow null and blank for initial creation
    class Meta:
        verbose_name_plural = u'Businesses'
    def __str__(self):
        return self.name
    def save(self, *args, **kwargs):
        if not self.business_id:
            # Get the last two digits of the current year
            current_year = str(datetime.now().year)[-2:]
            # Find the maximum project ID in the database and increment it
            max_id = Business.objects.aggregate(models.Max('business_id'))['business_id__max']
            new_id = str(int(max_id[-4:]) + 1).zfill(4) if max_id else '0001'  # If no existing records, start with '0001'
            self.business_id = 'B' + current_year + new_id  # Add 'p' prefix
        super(Business, self).save(*args, **kwargs)





class CustomerProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, blank=True)
    mobile_number = models.CharField(max_length=50, blank=True)
    personal_website = models.URLField(null=True, blank=True)
    STATUS_CHOICES = (
        ('Active', 'Active'),
        ('Suspended', 'Suspended'),
        ('Terminated', 'Terminated'),
    )
    status = models.CharField(max_length=200, choices=STATUS_CHOICES, blank=True)
    reference = models.ForeignKey(Reference, on_delete=models.CASCADE, null=True, blank=True)
    business = models.ForeignKey(Business, on_delete=models.CASCADE, null=True, blank=True)
    customer_id = models.CharField(max_length=20, null=True, blank=True) 
    def __str__(self):
        return self.user.username
    def save(self, *args, **kwargs):
        if not self.customer_id:
            # Get the last two digits of the current year
            current_year = str(datetime.now().year)[-2:]
            # Find the maximum project ID in the database and increment it
            max_id = CustomerProfile.objects.aggregate(models.Max('customer_id'))['customer_id__max']
            new_id = str(int(max_id[-4:]) + 1).zfill(4) if max_id else '0001'  # If no existing records, start with '0001'
            self.customer_id =  current_year + new_id  # Add 'p' prefix
        super(CustomerProfile, self).save(*args, **kwargs)

        


class StaffPosition(models.Model):
    name = models.CharField(max_length=100)
    def __str__(self):
        return self.name




class StaffProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    image = models.ImageField(null=True, blank=True)
    mobile_number = models.CharField(max_length=50)
    staff_position = models.ForeignKey(StaffPosition, on_delete=models.CASCADE, null=True, blank=True)
    intern = models.BooleanField(default=False)
    active = models.BooleanField(default=True)
    staff_id = models.CharField(max_length=20, null=True, blank=True)  # Allow null and blank for initial creation

    def __str__(self):
        return self.user.username
    def save(self, *args, **kwargs):
        if not self.staff_id:
            # Get the last two digits of the current year
            current_year = str(datetime.now().year)[-2:]
            # Find the maximum project ID in the database and increment it
            max_id = StaffProfile.objects.aggregate(models.Max('staff_id'))['staff_id__max']
            new_id = str(int(max_id[-4:]) + 1).zfill(4) if max_id else '0001'  # If no existing records, start with '0001'
            self.staff_id = 'O' + current_year + new_id  # Add 'p' prefix
        super(StaffProfile, self).save(*args, **kwargs)



class ProjectType(models.Model):
    name = models.CharField(max_length=50)
   


class Project(models.Model):
    name = models.CharField(max_length=50)
    customer = models.ForeignKey(CustomerProfile, on_delete=models.CASCADE, null=True)
    manager = models.ForeignKey(StaffProfile, on_delete=models.CASCADE, null=True)
    project_type = models.ManyToManyField('ProjectType', default='', related_name='manager_project')
    details = models.TextField()
    members = models.ManyToManyField('StaffProfile', default='', related_name='members_project')
    STATUS_CHOICES = (
        ('Active', 'Active'),
        ('Completed', 'Completed'),
        ('Pending', 'Pending'),
        ('Cancelled', 'Cancelled'),
    )
    status = models.CharField(max_length=200, choices=STATUS_CHOICES)
    start_date = models.CharField(max_length=200)
    end_date = models.CharField(max_length=200)
    project_id = models.CharField(max_length=20, null=True, blank=True)  # Allow null and blank for initial creation
    def save(self, *args, **kwargs):
        if not self.project_id:
            # Get the last two digits of the current year
            current_year = str(datetime.now().year)[-2:]
            # Find the maximum project ID in the database and increment it
            max_id = Project.objects.aggregate(models.Max('project_id'))['project_id__max']
            new_id = str(int(max_id[-4:]) + 1).zfill(4) if max_id else '0001'  # If no existing records, start with '0001'
            self.project_id = 'P' + current_year + new_id  # Add 'p' prefix
        super(Project, self).save(*args, **kwargs)


class Milestone(models.Model):
    title = models.CharField(max_length=150)
    description = models.TextField()
    project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True)
    start_date = models.DateField()
    end_date = models.DateField()


class Epic(models.Model):
    title = models.CharField(max_length=150)
    STATUS_CHOICES = (
        ('Open', 'Open'),
        ('Closed', 'Closed')
    )
    status = models.CharField(max_length=200, choices=STATUS_CHOICES, null=True)
    description = models.TextField()
    project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True)
    start_date = models.CharField(max_length=200)
    end_date = models.CharField(max_length=200)


class ProjectRequirement(models.Model):
    content = models.CharField(max_length=350)
    project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True)
    date = models.DateField(null=True, auto_now=True)
    added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)


class ProjectFile(models.Model):
    name = models.CharField(max_length=350)
    file = models.FileField(blank=True)
    date = models.DateField()
    project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True)

class ProjectCredential(models.Model):
    emailorusername = models.CharField(max_length=350)
    password = models.CharField(max_length=350)
    usedfor =  models.CharField(max_length=350)
    project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True)
    

class Note(models.Model):
    text = models.TextField(blank=True)
    date = models.DateTimeField(null=True,blank=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True,blank=True)
    color = ColorField(default='#FF0000',blank=True)
    project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True, blank=True)


class Task(models.Model):
    name = models.CharField(max_length=250)
    project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True)
    epic = models.ForeignKey(Epic, on_delete=models.CASCADE, null=True)
    STATUS_CHOICES = (
        ('Open', 'Open'),
        ('Working On', 'Working On'),
        ('Closed', 'Closed')
    )
    status = models.CharField(max_length=200, choices=STATUS_CHOICES, null=True)
    status_date = models.DateTimeField(default=timezone.now)
    extra = models.BooleanField(default=False)
    description = models.TextField()
    start_date = models.DateField(null=True)
    end_date = models.DateField(null=True)
    assigned_to =  models.ForeignKey(StaffProfile, on_delete=models.CASCADE, null=True)
    requirement =  models.ForeignKey(ProjectRequirement, on_delete=models.SET_NULL, null=True, blank=True)
    task_id = models.CharField(max_length=20, null=True, blank=True)  
    def save(self, *args, **kwargs):
        if not self.task_id:
            # Get the last two digits of the current year
            current_year = str(datetime.now().year)[-2:]
            # Find the maximum project ID in the database and increment it
            max_id = Task.objects.aggregate(models.Max('task_id'))['task_id__max']
            new_id = str(int(max_id[-4:]) + 1).zfill(4) if max_id else '0001'  # If no existing records, start with '0001'
            self.task_id = 'T' + current_year + new_id  # Add 'p' prefix

        if self.pk is not None:
            original_task = Task.objects.get(pk=self.pk)
            if original_task.status != self.status:
                self.status_date = timezone.now()
                
        super(Task, self).save(*args, **kwargs)

    def total_task_time(self):
        total_time_seconds = 0
        for point in self.point_set.all(): 
            if point:
                point_hours, point_minutes, point_seconds = point.total_activity_time()
                total_time_seconds += (point_hours * 3600) + (point_minutes * 60) + point_seconds

        total_time_hours = total_time_seconds // 3600
        total_time_minutes = (total_time_seconds % 3600) // 60
        total_time_seconds = total_time_seconds % 60
        
        return total_time_hours, total_time_minutes, total_time_seconds




class Point(models.Model):
    text = models.TextField(blank=True)
    STATUS_CHOICES = (
        ('Not Completed', 'Not Completed'),
        ('Working On', 'Working On'),
        ('Paused', 'Paused'),
        ('Completed', 'Completed')
    )
    status = models.CharField(max_length=200, choices=STATUS_CHOICES, null=True)
    task = models.ForeignKey(Task, on_delete=models.CASCADE, null=True)
    def total_activity_time(self):
        total_time_seconds = 0
        for activity in self.pointactivity_set.all():
            if activity.total_time:
                total_time_seconds += activity.total_time.total_seconds()
        total_time_hours = int(total_time_seconds // 3600)
        total_time_minutes = int((total_time_seconds % 3600) // 60)
        total_time_seconds = int(total_time_seconds % 60)
        return total_time_hours, total_time_minutes, total_time_seconds



class PointActivity(models.Model):
    point = models.ForeignKey(Point, on_delete=models.CASCADE, null=True)
    start_time = models.DateTimeField()
    end_time = models.DateTimeField(null=True, blank=True)
    total_time = models.DurationField(null=True, blank=True)
    def save(self, *args, **kwargs):
        if self.start_time and not self.end_time:
            self.total_time = datetime.now() - self.start_time
        elif self.start_time and self.end_time:
            self.total_time = self.end_time - self.start_time
        super(PointActivity, self).save(*args, **kwargs)
        
    def total_time_in_hours_minutes_seconds(self):
        if self.total_time:
            total_seconds = self.total_time.total_seconds()
            hours = int(total_seconds // 3600)
            minutes = int((total_seconds % 3600) // 60)
            seconds = int(total_seconds % 60)
            return hours, minutes, seconds
        return 0, 0, 0






class Status(models.Model):
    text = models.TextField(blank=True)
    date = models.CharField(max_length=40)
    time = models.CharField(max_length=40)
    staff = models.ForeignKey(StaffProfile, on_delete=models.CASCADE, null=True,blank=True, related_name='staff')




class DailyReport(models.Model):
    text = models.TextField(blank=True)
    date = models.CharField(max_length=40)
    time = models.CharField(max_length=40)
    staff = models.ForeignKey(StaffProfile, on_delete=models.CASCADE, null=True,blank=True, related_name='dailyreport_staff')



class Connection(models.Model):
    STATUS_CHOICES = (
        ('Online', 'Online'),
        ('Offline', 'Offline'),
    )
    status = models.CharField(max_length=200, choices=STATUS_CHOICES, null=True)
    date = models.DateTimeField(null=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)