import uuid
from django.db import models
from django.contrib.auth import get_user_model

User = get_user_model()
from django.utils.text import slugify

class TimeStampedModel(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    class Meta:
        abstract = True

class Service(TimeStampedModel):
    title = models.CharField(max_length=140)
    slug = models.SlugField(max_length=160, unique=True, blank=True)
    short_description = models.TextField()
    who_its_for = models.TextField(blank=True)
    benefits = models.TextField(blank=True)
    icon = models.CharField(max_length=60, default="🩺")
    is_featured = models.BooleanField(default=False)
    sort_order = models.PositiveIntegerField(default=0)

    class Meta:
        ordering = ["sort_order", "title"]

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)[:160]
        super().save(*args, **kwargs)

    def __str__(self):
        return self.title

class Testimonial(TimeStampedModel):
    name = models.CharField(max_length=120, blank=True, help_text="Optional (can be anonymized)")
    relation = models.CharField(max_length=120, blank=True, help_text="e.g., Son, Daughter, Patient")
    content = models.TextField()
    is_published = models.BooleanField(default=True)

    class Meta:
        ordering = ["-created_at"]

    def __str__(self):
        return (self.name or "Anonymous")[:40]

class BlogPost(TimeStampedModel):
    title = models.CharField(max_length=200)
    slug = models.SlugField(max_length=220, unique=True, blank=True)
    excerpt = models.TextField(blank=True)
    body = models.TextField()
    cover_image = models.ImageField(upload_to="blog/", blank=True, null=True)
    is_published = models.BooleanField(default=True)
    published_at = models.DateTimeField(blank=True, null=True)

    class Meta:
        ordering = ["-published_at", "-created_at"]

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)[:220]
        super().save(*args, **kwargs)

    def __str__(self):
        return self.title

class CareerPosition(TimeStampedModel):
    ROLE_CHOICES = (
        ("nurse", "Nurse"),
        ("caregiver", "Caregiver"),
        ("other", "Other"),
    )
    title = models.CharField(max_length=160)
    role_type = models.CharField(max_length=20, choices=ROLE_CHOICES, default="caregiver")
    location = models.CharField(max_length=120, blank=True)
    description = models.TextField(blank=True)
    requirements = models.TextField()
    is_open = models.BooleanField(default=True)
    is_active = models.BooleanField(default=True)

    class Meta:
        ordering = ["-is_open", "title"]

    def __str__(self):
        return self.title

class Enquiry(TimeStampedModel):
    ENQUIRY_TYPE = (
        ("care", "Request Care"),
        ("partner", "Partnership / Corporate"),
        ("career", "Career"),
        ("general", "General"),
        ("mental_pickup", "Mental Health Facility Transfer (Non-emergency)"),
        ("event_coverage", "Event Medical Coverage"),
    )

    full_name = models.CharField(max_length=140)
    phone = models.CharField(max_length=30)
    email = models.EmailField(blank=True)
    enquiry_type = models.CharField(max_length=30, choices=ENQUIRY_TYPE, default="care")
    message = models.TextField()

    location = models.CharField(max_length=160, blank=True)
    preferred_contact_time = models.CharField(max_length=80, blank=True)

    is_resolved = models.BooleanField(default=False)

    def __str__(self):
        return f"{self.full_name} - {self.enquiry_type}"

class CareerApplication(TimeStampedModel):
    STATUS_CHOICES = (
        ("new", "New"),
        ("review", "In Review"),
        ("shortlisted", "Shortlisted"),
        ("rejected", "Rejected"),
        ("hired", "Hired"),
    )

    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="new")

    position = models.ForeignKey(CareerPosition, on_delete=models.SET_NULL, null=True, blank=True)
    full_name = models.CharField(max_length=140)
    phone = models.CharField(max_length=30)
    email = models.EmailField()
    cv = models.FileField(upload_to="applications/")
    notes = models.TextField(blank=True)

    def __str__(self):
        return self.full_name


class CareRequest(TimeStampedModel):
    REQUEST_TYPES = (
        ("telehealth_video", "Telehealth (Video Consultation)"),
        ("telehealth_phone", "Telehealth (Phone Consultation)"),
        ("telehealth_chat", "Telehealth (Chat Consultation)"),
        ("telehealth_nursing", "Telehealth Nursing Assessment / Follow-up"),
        ("telehealth_mental", "Mental Health & Psychosocial Support"),
        ("home_care", "Home Care"),
        ("post_hospital", "Post-hospital Recovery"),
        ("elderly", "Elderly / Geriatric Care"),
        ("palliative", "Palliative Support"),
        ("event_medical", "Event Medical Team / Event Medics"),
        ("other", "Other"),
    )
    STATUS_CHOICES = (
        ("new", "New"),
        ("assessment", "Assessment"),
        ("matched", "Caregiver Matched"),
        ("active", "Active"),
        ("completed", "Completed"),
        ("cancelled", "Cancelled"),
    )

    request_type = models.CharField(max_length=30, choices=REQUEST_TYPES, default="home_care")
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="new")

    assigned_to = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL, related_name='assigned_care_requests')

    # Client
    full_name = models.CharField(max_length=140)
    phone = models.CharField(max_length=30)
    email = models.EmailField(blank=True)
    location = models.CharField(max_length=160, blank=True)

    # Care needs
    patient_age = models.PositiveIntegerField(blank=True, null=True)
    care_needs = models.TextField(help_text="Brief description of care needs")
    preferred_start_date = models.DateField(blank=True, null=True)
    schedule_notes = models.CharField(max_length=220, blank=True, help_text="e.g., Day, Night, 24/7, Weekends")

    # Matching / notes
    preference_notes = models.TextField(blank=True, help_text="Language/culture preferences, gender preference, etc.")
    risk_notes = models.TextField(blank=True, help_text="Any safety or clinical considerations (non-emergency)")

    def __str__(self):
        return f"{self.full_name} ({self.get_request_type_display()})"



class TelehealthBooking(TimeStampedModel):
    STATUS_CHOICES = (
        ("new", "New"),
        ("confirmed", "Confirmed"),
        ("completed", "Completed"),
        ("cancelled", "Cancelled"),
    )

    CONSULTATION_MODES = (
        ("video", "Video Consultation"),
        ("phone", "Phone Consultation"),
        ("chat", "Online Chat"),
    )

    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="new")

    full_name = models.CharField(max_length=140)
    phone = models.CharField(max_length=30)
    email = models.EmailField(blank=True)

    consultation_mode = models.CharField(max_length=10, choices=CONSULTATION_MODES, default="video")

    # Admin-managed availability slot (recommended)
    slot = models.ForeignKey(
        "website.TelehealthAvailabilitySlot",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="bookings",
        help_text="Select an available slot (admin-managed calendar).",
    )
    preferred_date = models.DateField(blank=True, null=True)
    preferred_time = models.CharField(max_length=40, blank=True, help_text="e.g., 10:00am – 11:00am")
    symptoms_or_reason = models.TextField(blank=True)


    # Payment
    fee_ngn = models.PositiveIntegerField(default=0)
    is_paid = models.BooleanField(default=False)
    paystack_reference = models.CharField(max_length=64, blank=True)

    # Optional EMR link
    patient = models.ForeignKey("Patient", null=True, blank=True, on_delete=models.SET_NULL, related_name="telehealth_bookings")

    def __str__(self):
        return f"{self.full_name} ({self.get_consultation_mode_display()})"


class TelehealthProvider(TimeStampedModel):
    ROLE_CHOICES = (
        ("doctor", "Doctor / Specialist"),
        ("nurse", "Registered Nurse"),
        ("mental", "Mental Health Professional"),
        ("pharmacist", "Pharmacist"),
        ("dietitian", "Dietitian"),
    )
    full_name = models.CharField(max_length=140)
    role = models.CharField(max_length=20, choices=ROLE_CHOICES, default="doctor")
    specialization = models.CharField(max_length=140, blank=True)
    is_active = models.BooleanField(default=True)
    sort_order = models.PositiveIntegerField(default=0)
    license_number = models.CharField(max_length=100, blank=True)
    license_authority = models.CharField(max_length=120, blank=True)
    is_verified = models.BooleanField(default=False)
    auto_schedule = models.BooleanField(default=False)
    working_days = models.CharField(max_length=20, default="0,1,2,3,4", help_text="Weekdays 0=Monday to 6=Sunday, comma separated")
    work_start = models.TimeField(default="09:00")
    work_end = models.TimeField(default="17:00")
    slot_minutes = models.PositiveSmallIntegerField(default=60)

    def __str__(self):
        return self.full_name


class TelehealthAvailabilitySlot(TimeStampedModel):
    provider = models.ForeignKey(TelehealthProvider, on_delete=models.CASCADE, related_name="slots")
    start_at = models.DateTimeField()
    end_at = models.DateTimeField()
    is_active = models.BooleanField(default=True)

    capacity = models.PositiveIntegerField(default=1)
    booked_count = models.PositiveIntegerField(default=0)

    class Meta:
        ordering = ("start_at",)
        indexes = [
            models.Index(fields=["start_at"]),
            models.Index(fields=["provider", "start_at"]),
        ]

    @property
    def is_full(self):
        return self.booked_count >= self.capacity

    def __str__(self):
        return f"{self.provider.full_name} | {self.start_at:%Y-%m-%d %H:%M}"


class CaregiverProfile(TimeStampedModel):
    user = models.OneToOneField("auth.User", on_delete=models.CASCADE, related_name="caregiver_profile")
    phone = models.CharField(max_length=30, blank=True)
    location = models.CharField(max_length=160, blank=True)
    skills = models.TextField(blank=True, help_text="Comma-separated skills/certifications")
    availability = models.TextField(blank=True, help_text="e.g., Mon–Fri (Day), Weekends, Night shifts")
    is_active = models.BooleanField(default=True)

    def __str__(self):
        return self.user.get_full_name() or self.user.username

class CareAssignment(TimeStampedModel):
    STATUS_CHOICES = (
        ("proposed", "Proposed"),
        ("accepted", "Accepted"),
        ("active", "Active"),
        ("completed", "Completed"),
        ("cancelled", "Cancelled"),
    )
    care_request = models.ForeignKey(CareRequest, on_delete=models.CASCADE, related_name="assignments")
    caregiver = models.ForeignKey(CaregiverProfile, on_delete=models.CASCADE, related_name="assignments")
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="proposed")
    start_date = models.DateField(blank=True, null=True)
    end_date = models.DateField(blank=True, null=True)
    notes = models.TextField(blank=True)

    class Meta:
        ordering = ["-created_at"]

    def __str__(self):
        return f"{self.caregiver} → {self.care_request}"


# -----------------------------------------------------------------------------
# Support Tickets (public + staff)
# -----------------------------------------------------------------------------

# -----------------------------------------------------------------------------
# PAYMENTS (Paystack)
# -----------------------------------------------------------------------------
class PaymentTransaction(TimeStampedModel):
    PURPOSE_CHOICES = (
        ("telehealth", "Telehealth Consultation"),
        ("care_request", "Care / Home Service Request"),
    )
    STATUS_CHOICES = (
        ("initiated", "Initiated"),
        ("success", "Success"),
        ("failed", "Failed"),
    )

    purpose = models.CharField(max_length=40, choices=PURPOSE_CHOICES)
    amount_ngn = models.PositiveIntegerField(default=0)
    email = models.EmailField(blank=True)
    reference = models.CharField(max_length=64, unique=True)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="initiated")
    notes = models.TextField(blank=True)
    paid_at = models.DateTimeField(null=True, blank=True)
    raw_response = models.JSONField(default=dict, blank=True)

    telehealth_booking = models.ForeignKey("TelehealthBooking", null=True, blank=True, on_delete=models.SET_NULL, related_name="payments")
    care_request = models.ForeignKey("CareRequest", null=True, blank=True, on_delete=models.SET_NULL, related_name="payments")

    def __str__(self):
        return f"{self.purpose} {self.amount_ngn} NGN ({self.status})"


# -----------------------------------------------------------------------------
# EMR (Minimal)
# -----------------------------------------------------------------------------
class Patient(TimeStampedModel):
    full_name = models.CharField(max_length=140)
    phone = models.CharField(max_length=40, db_index=True)
    email = models.EmailField(blank=True)
    date_of_birth = models.DateField(null=True, blank=True)
    gender = models.CharField(max_length=20, blank=True)
    address = models.CharField(max_length=240, blank=True)

    def __str__(self):
        return f"{self.full_name} ({self.phone})"


class EMRNote(TimeStampedModel):
    patient = models.ForeignKey(Patient, on_delete=models.CASCADE, related_name="notes")
    title = models.CharField(max_length=140, blank=True)
    note = models.TextField()
    created_by = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL)

    def __str__(self):
        return f"{self.patient.full_name} - {self.title or 'Note'}"


# -----------------------------------------------------------------------------
# ACTIVITY LOG (for staff dashboard)
# -----------------------------------------------------------------------------
class ActivityLog(TimeStampedModel):
    action = models.CharField(max_length=80)
    summary = models.CharField(max_length=240)
    meta = models.JSONField(default=dict, blank=True)

    def __str__(self):
        return f"{self.action}: {self.summary}"


class SupportTicket(models.Model):
    STATUS_CHOICES = [
        ("open", "Open"),
        ("pending", "Pending"),
        ("closed", "Closed"),
    ]

    public_id = models.CharField(max_length=12, unique=True, db_index=True)
    secret = models.CharField(max_length=36, db_index=True)  # for public access link
    full_name = models.CharField(max_length=120)
    email = models.EmailField(blank=True)
    phone = models.CharField(max_length=40, blank=True)
    subject = models.CharField(max_length=180, default="Support Request")
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="open")
    priority = models.CharField(max_length=20, default="normal")
    created_at = models.DateTimeField(auto_now_add=True)

    assigned_to = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL, related_name='assigned_tickets')
    sla_minutes = models.PositiveIntegerField(default=15)
    due_at = models.DateTimeField(null=True, blank=True)
    first_response_at = models.DateTimeField(null=True, blank=True)
    last_client_message_at = models.DateTimeField(null=True, blank=True)
    last_staff_message_at = models.DateTimeField(null=True, blank=True)

    def __str__(self):
        return f"{self.public_id} - {self.subject}"

    @staticmethod
    def new_id():
        # 12-char ticket code
        return uuid.uuid4().hex[:12].upper()

class SupportMessage(models.Model):
    ticket = models.ForeignKey(SupportTicket, on_delete=models.CASCADE, related_name="messages")
    sender = models.CharField(max_length=20, default="client")  # client/staff/system
    message = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["created_at"]

    def __str__(self):
        return f"{self.ticket.public_id} ({self.sender})"


class StaffNotification(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="staff_notifications")
    kind = models.CharField(max_length=40, default="support")
    title = models.CharField(max_length=140)
    body = models.TextField(blank=True)
    url = models.CharField(max_length=240, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    is_read = models.BooleanField(default=False)

    class Meta:
        ordering = ["-created_at"]

    def __str__(self):
        return f"{self.user} - {self.title}"
