from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.core.mail import send_mail
from django.utils.encoding import force_bytes
from django.template.loader import render_to_string
from django.contrib.auth.tokens import default_token_generator
from django.conf import settings
from django.utils.http import urlsafe_base64_encode


class Service(models.Model):
    name = models.CharField(max_length=20)
    description = models.CharField(max_length=100, blank=True, null=True)
    def __str__(self):
        return self.name

class UserManager(BaseUserManager):
    def create_user(self, first_name, last_name, email, password=None, **extra_fields):
        """
        Creates and saves a User with the given first name, last name, email, and password.
        """
        if not email:
            raise ValueError('Users must have an email address')

        email = self.normalize_email(email)
        user = self.model(
            first_name=first_name,
            last_name=last_name,
            email=email,
            **extra_fields
        )
        user.set_password(password)
        user.save(using=self._db)

        try:
            self.send_verification_email(user)
        except:
            print("Couldnot send verification email.")

        return user

    def create_superuser(self, first_name, last_name, email, password=None, **extra_fields):
        """
        Creates and saves a superuser with the given first name, last name, email, and password.
        """
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self.create_user(first_name, last_name, email, password, **extra_fields)

    def send_verification_email(self, user):
        token = default_token_generator.make_token(user)
        uid = urlsafe_base64_encode(force_bytes(user.pk))
        verification_url = f"{settings.FRONTEND_URL}/verify-email/{uid}/{token}/"

        subject = "Verify Your Email Address"
        message = render_to_string('emails/verification_email.html', {
            'user': user,
            'verification_url': verification_url,
        })

        send_mail(
            subject,    
            message,
            settings.DEFAULT_FROM_EMAIL,
            [user.email],
            fail_silently=False,
        )


OPTIONS = [
        ('NORMAL','Normal User'),
        ('SERVICE', 'Service Provider'),
        ('ADMIN', 'Admin User'),
    ]

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    profile = models.ImageField(blank=True,null=True, upload_to="profile-images/")
    price = models.PositiveBigIntegerField(blank=True, null=True)
    bio = models.CharField(max_length=200, blank=True, null=True)
    member_since = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateField(auto_now=True)
    phone_number = models.CharField(max_length=15, blank=True, null=True)
    service_offered = models.ForeignKey(Service, on_delete=models.CASCADE,blank=True,null=True)
    login_profile = models.CharField(
        max_length=15,
        choices=OPTIONS,
        default='NORMAL',
    )
    USERNAME_FIELD = 'email'  
    REQUIRED_FIELDS = ['first_name', 'last_name','price','bio'] 

    objects = UserManager()

    def __str__(self):
        return self.email

    def get_full_name(self):
        return f"{self.first_name} {self.last_name}"

    def get_short_name(self):
        return self.first_name
    @property
    def url(self):
        if self.profile_picture:
            return self.profile_picture.url
        return None

class ServiceRequest(models.Model):
    client = models.ForeignKey(User,on_delete=models.CASCADE,related_name="client")
    service_provider = models.ForeignKey(User,on_delete=models.CASCADE,related_name="service_provider")
    agreed_price = models.DecimalField(max_digits=999,decimal_places=2 , default=0)
    service_hour = models.PositiveIntegerField(default=1)
    agreed_on =  models.DateField(auto_now_add=True)
    is_approved = models.BooleanField(blank=True, null=True,default=False)
    remarks = models.TextField(blank=True, null=True)
    is_completed = models.BooleanField(default=False)
    completed_date = models.DateTimeField(null=True,blank=True)
    service = models.ForeignKey(Service, on_delete=models.CASCADE, related_name="service_offered")
    

    def __str__(self):
        return self.service.name 

    @property
    def get_full_price(self):
        return self.agreed_price * self.service_hour