from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.db import models


class UserManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError('Email is required')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        return self.create_user(email, password, **extra_fields)


class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    display_name = models.CharField(max_length=100, blank=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_therapist = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    def __str__(self):
        return self.email


BREATHING_MODE_CHOICES = [
    ('custom', 'Custom'),
    # Unused modes — kept for potential future use
    # ('boxBreathing',      'Box Breathing'),
    # ('fourSevenEight',    '4-7-8 Technique'),
    # ('deepCalm',          'Deep Calm'),
    # ('energizing',        'Energizing'),
    # ('coherence',         'Coherence'),
    # ('physiologicalSigh', 'Physiological Sigh'),
    # ('wimHof',            'Wim Hof'),
    # ('tummo',             'Tummo'),
    # ('twoToOne',          '2:1 Breathing'),
    # ('alternate',         'Alternate Nostril'),
    # ('resonance',         'Resonance'),
]

VISUALIZATION_CHOICES = [
    ('circle', 'Circle'),
    ('triangle', 'Triangle'),
    ('lotus', 'Lotus'),
    ('waveform', 'Wave'),
    ('ripple', 'Ripple'),
    ('petals', 'Petals'),
    ('zigzag', 'Zigzag'),
]


class UserPrescription(models.Model):
    """A therapist-assigned breathing configuration for a patient."""
    patient = models.OneToOneField(
        User, on_delete=models.CASCADE, related_name='prescription'
    )
    therapist = models.ForeignKey(
        User, on_delete=models.SET_NULL, null=True, related_name='prescribed_to'
    )
    breathing_mode = models.CharField(max_length=30, choices=BREATHING_MODE_CHOICES, default='custom')
    visualization_type = models.CharField(max_length=20, choices=VISUALIZATION_CHOICES, default='circle')
    bpm = models.FloatField(default=6.0, help_text='Breaths per minute prescribed by therapist')
    duration_seconds = models.PositiveIntegerField(default=300, help_text='Session length in seconds')
    locked = models.BooleanField(
        default=True,
        help_text='When True the patient cannot change these settings.'
    )
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return f"{self.patient.email} ← {self.therapist.email if self.therapist else 'unassigned'}"


class RegistrationCode(models.Model):
    """A single-use code generated by a therapist that allows one patient to register."""
    code = models.CharField(max_length=10, unique=True)
    therapist = models.ForeignKey(User, on_delete=models.CASCADE, related_name='registration_codes')
    created_at = models.DateTimeField(auto_now_add=True)
    used_by = models.OneToOneField(
        User, on_delete=models.SET_NULL, null=True, blank=True, related_name='registered_via_code'
    )

    def is_valid(self):
        from django.utils import timezone
        from datetime import timedelta
        if self.used_by_id is not None:
            return False
        return timezone.now() < self.created_at + timedelta(hours=28)

    def __str__(self):
        return f"{self.code} (by {self.therapist.email})"


class ExerciseLog(models.Model):
    """Records a completed (or stopped) exercise session for a patient."""
    patient = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name='exercise_logs'
    )
    breathing_mode = models.CharField(max_length=30, choices=BREATHING_MODE_CHOICES)
    visualization_type = models.CharField(max_length=20, choices=VISUALIZATION_CHOICES)
    duration_seconds = models.PositiveIntegerField(help_text='Elapsed time in seconds')
    prescribed_duration_seconds = models.PositiveIntegerField(null=True, blank=True, help_text='Prescribed session length; null if no prescription')
    breath_count = models.PositiveIntegerField(default=0)
    completed_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-completed_at']

    def __str__(self):
        return f"{self.patient.email} — {self.breathing_mode} {self.duration_seconds}s"
