from django.conf import settings
from django.db import models
from django.urls import reverse
from django.utils.text import slugify


class SeekerProfile(models.Model):
    class Availability(models.TextChoices):
        ACTIVE = 'active', 'Actively Looking'
        PASSIVE = 'passive', 'Open to Offers'
        NOT_LOOKING = 'not_looking', 'Not Looking'

    class Tier(models.TextChoices):
        FREE = 'free', 'Free'
        SILVER = 'silver', 'Silver'
        GOLD = 'gold', 'Gold'

    class ExperienceLevel(models.TextChoices):
        ENTRY = 'entry', 'Entry Level (0–2 yrs)'
        MID = 'mid', 'Mid Level (3–5 yrs)'
        SENIOR = 'senior', 'Senior (6–10 yrs)'
        EXECUTIVE = 'executive', 'Executive (10+ yrs)'

    class ProfessionalStatus(models.TextChoices):
        EMPLOYED = 'employed', 'Employed'
        SELF_EMPLOYED = 'self_employed', 'Self-Employed'
        UNEMPLOYED = 'unemployed', 'Unemployed'
        STUDENT = 'student', 'Student'
        GRADUATE = 'graduate', 'Recent Graduate'
        FREELANCER = 'freelancer', 'Freelancer'
        CONSULTANT = 'consultant', 'Consultant'
        OTHER = 'other', 'Other'

    class Timeline(models.TextChoices):
        NOW = 'now', 'Immediately'
        W1 = '1w', 'Within 1 week'
        W2 = '2w', 'Within 2 weeks'
        M1 = '1m', 'Within 1 month'
        M2 = '2m', 'Within 2 months'
        M3 = '3m+', 'More than 3 months'
        DATE = 'date', 'Available from a specific date'

    class Visibility(models.TextChoices):
        PUBLIC = 'public', 'Public'
        RECRUITERS = 'recruiters', 'Employers & Recruiters Only'
        PRIVATE = 'private', 'Private'

    show_photo = models.BooleanField(default=True)
    current_job_title = models.CharField(max_length=120, blank=True)
    current_employer = models.CharField(max_length=150, blank=True)
    industry = models.CharField(max_length=100, blank=True)
    sub_industry = models.CharField(max_length=100, blank=True)
    country = models.CharField(max_length=80, blank=True, default='Zambia')
    professional_status = models.CharField(max_length=20, choices=ProfessionalStatus.choices, blank=True)
    products_experience = models.TextField(blank=True, help_text='One per line')
    target_titles = models.TextField(blank=True, help_text='One per line')
    preferred_industries = models.TextField(blank=True, help_text='One per line')
    preferred_categories = models.TextField(blank=True, help_text='One per line')
    preferred_locations = models.TextField(blank=True, help_text='One per line')
    employment_types = models.TextField(blank=True, help_text='One per line')
    work_arrangements = models.TextField(blank=True, help_text='One per line')
    willing_to_relocate = models.BooleanField(default=False)
    relocation_locations = models.CharField(max_length=255, blank=True)
    availability_timeline = models.CharField(max_length=10, choices=Timeline.choices, blank=True)
    available_from = models.DateField(null=True, blank=True)
    salary_currency = models.CharField(max_length=5, default='ZMW')
    salary_negotiable = models.BooleanField(default=False)
    salary_private = models.BooleanField(default=False)
    authorised_countries = models.TextField(blank=True, help_text='One per line')
    work_authorisation = models.TextField(blank=True, help_text='One per line')
    allow_cv_access = models.BooleanField(default=True)
    linkedin_url = models.URLField(blank=True)
    website_url = models.URLField(blank=True)
    portfolio_url = models.URLField(blank=True)
    github_url = models.URLField(blank=True)
    other_link_url = models.URLField(blank=True)
    contact_employers = models.BooleanField(default=True)
    contact_team = models.BooleanField(default=True)
    visibility = models.CharField(max_length=12, choices=Visibility.choices, default=Visibility.PUBLIC)
    consent_contact = models.BooleanField(default=False)
    consent_present = models.BooleanField(default=False)
    consent_matching = models.BooleanField(default=False)
    confirm_accuracy = models.BooleanField(default=False)

    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name='seeker_profile',
    )
    slug = models.SlugField(max_length=180, unique=True)
    full_name = models.CharField(max_length=120)
    headline = models.CharField(max_length=150, help_text='Professional title')
    job_category = models.ForeignKey(
        'jobs.JobCategory',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='seeker_profiles',
    )
    category = models.CharField(max_length=100)
    category_slug = models.SlugField(max_length=120, blank=True)
    location = models.CharField(max_length=120)
    years_experience = models.PositiveSmallIntegerField(default=0)
    experience_level = models.CharField(
        max_length=20,
        choices=ExperienceLevel.choices,
        default=ExperienceLevel.MID,
    )
    availability = models.CharField(
        max_length=20,
        choices=Availability.choices,
        default=Availability.ACTIVE,
    )
    tier = models.CharField(max_length=20, choices=Tier.choices, default=Tier.FREE)
    skills = models.TextField(blank=True, help_text='One skill per line')
    bio = models.TextField(blank=True)
    education = models.TextField(blank=True, help_text='One entry per line')
    experience_summary = models.TextField(blank=True, help_text='One role per line')
    qualification = models.CharField(max_length=120, blank=True)
    cover_image_url = models.URLField(blank=True)
    cover_image = models.ImageField(upload_to='seekers/covers/', max_length=255, blank=True, null=True)
    avatar_url = models.URLField(blank=True)
    salary_min = models.PositiveIntegerField(null=True, blank=True)
    salary_max = models.PositiveIntegerField(null=True, blank=True)
    cv_file = models.FileField(upload_to='seekers/cv/', max_length=255, blank=True, null=True)
    is_public = models.BooleanField(
        default=True,
        help_text='When off, your profile is hidden from the talent directory and public URL.',
    )
    is_online = models.BooleanField(
        default=True,
        help_text='When off, you appear as offline and are hidden from the homepage carousel.',
    )
    is_featured = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['-is_featured', '-tier', 'full_name']

    def __str__(self):
        return self.full_name

    def save(self, *args, **kwargs):
        if not self.slug:
            base = slugify(self.full_name)
            slug = base
            counter = 1
            while SeekerProfile.objects.filter(slug=slug).exclude(pk=self.pk).exists():
                slug = f'{base}-{counter}'
                counter += 1
            self.slug = slug
        if self.job_category_id:
            self.category = self.job_category.name
            self.category_slug = self.job_category.slug
        elif not self.category_slug and self.category:
            self.category_slug = slugify(self.category)
        super().save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('seekers:detail', kwargs={'slug': self.slug})

    @property
    def skill_list(self):
        import re
        parts = re.split(r'[\n\r;,]+', self.skills or '')
        return [part.strip() for part in parts if part.strip()]

    @staticmethod
    def _lines(text):
        import re
        return [part.strip() for part in re.split(r'[\n\r;]+', text or '') if part.strip()]

    @property
    def product_list(self):
        return self._lines(self.products_experience)

    @property
    def target_title_list(self):
        return self._lines(self.target_titles)

    @property
    def preferred_industry_list(self):
        return self._lines(self.preferred_industries)

    @property
    def preferred_category_list(self):
        return self._lines(self.preferred_categories)

    @property
    def preferred_location_list(self):
        return self._lines(self.preferred_locations)

    @property
    def employment_type_list(self):
        return self._lines(self.employment_types)

    @property
    def work_arrangement_list(self):
        return self._lines(self.work_arrangements)

    @property
    def authorised_country_list(self):
        return self._lines(self.authorised_countries)

    @property
    def work_authorisation_list(self):
        return self._lines(self.work_authorisation)

    @property
    def first_name(self):
        return (self.full_name or '').split(' ', 1)[0]

    @property
    def last_name(self):
        parts = (self.full_name or '').split(' ', 1)
        return parts[1] if len(parts) > 1 else ''

    @property
    def salary_display(self):
        if self.salary_private:
            return 'Not disclosed'
        if self.salary_min and self.salary_max:
            return f'K {self.salary_min:,}–{self.salary_max:,} /month'
        if self.salary_min:
            return f'K {self.salary_min:,}+ /month'
        return 'Negotiable'

    @property
    def availability_css_class(self):
        return {
            self.Availability.ACTIVE: 'open',
            self.Availability.PASSIVE: 'passive',
            self.Availability.NOT_LOOKING: 'not-looking',
        }.get(self.availability, 'passive')

    @property
    def presence_label(self):
        return 'Online' if self.is_online else 'Offline'

    @property
    def presence_css_class(self):
        return 'online' if self.is_online else 'offline'

    @property
    def initials(self):
        parts = self.full_name.split()
        if len(parts) >= 2:
            return f'{parts[0][0]}{parts[-1][0]}'.upper()
        return self.full_name[:2].upper()

    @property
    def contact_phone(self):
        if self.user_id and self.user.phone:
            return self.user.phone.strip()
        return ''

    @property
    def contact_email(self):
        if self.user_id and self.user.email:
            return self.user.email.strip()
        return ''

    @property
    def uploaded_cover_url(self):
        if self.cover_image:
            try:
                return self.cover_image.url
            except (ValueError, AttributeError):
                pass
        return ''

    @property
    def display_cover_url(self):
        from home.cover_images import is_demo_image_url

        uploaded = self.uploaded_cover_url
        if uploaded:
            return uploaded
        if self.cover_image_url and not is_demo_image_url(self.cover_image_url):
            return self.cover_image_url
        return ''

    @property
    def display_avatar_url(self):
        from home.cover_images import is_demo_image_url

        if not self.show_photo:
            return ''

        if self.user_id and getattr(self.user, 'avatar', None):
            try:
                if self.user.avatar:
                    return self.user.avatar.url
            except (ValueError, AttributeError):
                pass
        if self.avatar_url and not is_demo_image_url(self.avatar_url):
            return self.avatar_url
        return ''


class SeekerCategory(models.Model):
    """Curated profession/category taxonomy for CV library browsing."""

    name = models.CharField(max_length=100, unique=True)
    slug = models.SlugField(max_length=120, unique=True)
    icon = models.CharField(max_length=50, blank=True, default='fa-briefcase')
    sort_order = models.PositiveSmallIntegerField(default=0)
    is_active = models.BooleanField(default=True)

    class Meta:
        ordering = ['sort_order', 'name']
        verbose_name_plural = 'seeker categories'

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)


class SeekerCVRecord(models.Model):
    """Indexed CV file for admin/employer library search and bulk download."""

    seeker_profile = models.ForeignKey(
        SeekerProfile,
        on_delete=models.CASCADE,
        related_name='cv_records',
    )
    category = models.ForeignKey(
        SeekerCategory,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='cv_records',
    )
    category_name = models.CharField(max_length=100, blank=True)
    category_slug = models.SlugField(max_length=120, blank=True, db_index=True)
    full_name = models.CharField(max_length=120)
    seeker_email = models.EmailField(blank=True)
    headline = models.CharField(max_length=150, blank=True)
    skills = models.TextField(blank=True)
    location = models.CharField(max_length=120, blank=True)
    cv_file = models.FileField(upload_to='seekers/cv/library/', max_length=255)
    original_filename = models.CharField(max_length=255, blank=True)
    file_size = models.PositiveIntegerField(default=0)
    is_current = models.BooleanField(default=True, db_index=True)
    indexed_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-indexed_at']
        indexes = [
            models.Index(fields=['is_current', '-indexed_at']),
            models.Index(fields=['category_slug', '-indexed_at']),
        ]

    def __str__(self):
        label = self.original_filename or f'CV #{self.pk}'
        return f'{self.full_name} – {label}'

    @property
    def file_exists(self):
        return bool(self.cv_file and self.cv_file.name)


class SeekerInterest(models.Model):
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='interests',
    )
    name = models.CharField(max_length=120)
    created_at = models.DateTimeField()

    class Meta:
        ordering = ['name']
        unique_together = [('user', 'name')]

    def __str__(self):
        return f'{self.user_id}: {self.name}'


class ProfileView(models.Model):
    """Profile view tracking from legacy profile_store_profileview."""
    profile_user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='profile_views_received',
    )
    viewer = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='profile_views_made',
    )
    account_type = models.CharField(max_length=30, blank=True)
    ip_address = models.CharField(max_length=45, blank=True)
    viewed_at = models.DateTimeField()

    class Meta:
        ordering = ['-viewed_at']

    def __str__(self):
        return f'Profile view: {self.profile_user_id} at {self.viewed_at:%Y-%m-%d}'


class ProfileMessage(models.Model):
    """Direct profile messages from legacy profile_store_message."""
    sender = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='profile_messages_sent',
    )
    recipient = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='profile_messages_received',
    )
    msg_type = models.CharField(max_length=30, blank=True)
    subject = models.CharField(max_length=200, blank=True)
    message = models.TextField(blank=True)
    view_cv = models.BooleanField(default=False)
    is_read = models.BooleanField(default=False)
    read_by_sender = models.BooleanField(default=False)
    created_at = models.DateTimeField()

    class Meta:
        ordering = ['-created_at']

    def __str__(self):
        return self.subject or f'Message #{self.pk}'


class ProfileMessageReply(models.Model):
    parent = models.ForeignKey(
        ProfileMessage,
        on_delete=models.CASCADE,
        related_name='replies',
    )
    sender = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='profile_message_replies_sent',
    )
    recipient = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='profile_message_replies_received',
    )
    message = models.TextField(blank=True)
    image = models.CharField(max_length=255, blank=True)
    is_read = models.BooleanField(default=False)
    created_at = models.DateTimeField()

    class Meta:
        ordering = ['created_at']

    def __str__(self):
        return f'Reply to message #{self.parent_id}'


class PortfolioStat(models.Model):
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='portfolio_stats',
    )
    total_views = models.PositiveIntegerField(default=0)
    total_likes = models.PositiveIntegerField(default=0)
    total_comments = models.PositiveIntegerField(default=0)
    total_items = models.PositiveIntegerField(default=0)
    last_updated = models.DateTimeField(null=True, blank=True)

    def __str__(self):
        return f'Portfolio stats: user {self.user_id}'


def _month_year(month, year):
    names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    if not year:
        return ''
    return f'{names[month - 1]} {year}' if month else str(year)


class ProfileItem(models.Model):
    """Base for the repeatable sections of a professional profile."""

    seeker = models.ForeignKey(SeekerProfile, on_delete=models.CASCADE, related_name='+')
    position = models.PositiveIntegerField(default=0)

    class Meta:
        abstract = True
        ordering = ['position', '-id']


class WorkExperience(ProfileItem):
    class EmploymentType(models.TextChoices):
        FULL = 'full', 'Full-Time'
        PART = 'part', 'Part-Time'
        CONTRACT = 'contract', 'Contract'
        TEMP = 'temporary', 'Temporary'
        INTERN = 'internship', 'Internship'
        FREELANCE = 'freelance', 'Freelance'
        CONSULT = 'consultancy', 'Consultancy'

    seeker = models.ForeignKey(SeekerProfile, on_delete=models.CASCADE, related_name='experiences')
    company = models.CharField(max_length=150)
    title = models.CharField(max_length=150)
    job_category = models.CharField(max_length=100, blank=True)
    industry = models.CharField(max_length=100, blank=True)
    sub_industry = models.CharField(max_length=100, blank=True)
    employment_type = models.CharField(max_length=15, choices=EmploymentType.choices, blank=True)
    location = models.CharField(max_length=120, blank=True)
    start_month = models.PositiveSmallIntegerField(null=True, blank=True)
    start_year = models.PositiveSmallIntegerField(null=True, blank=True)
    is_current = models.BooleanField(default=False)
    end_month = models.PositiveSmallIntegerField(null=True, blank=True)
    end_year = models.PositiveSmallIntegerField(null=True, blank=True)
    responsibilities = models.TextField(blank=True)
    achievements = models.TextField(blank=True)

    class Meta:
        ordering = ['-is_current', '-start_year', '-start_month', '-id']

    @property
    def period(self):
        start = _month_year(self.start_month, self.start_year)
        end = 'Present' if self.is_current else _month_year(self.end_month, self.end_year)
        return ' - '.join(x for x in (start, end) if x)

    @property
    def summary_line(self):
        return f'{self.title} at {self.company}'

    def __str__(self):
        return self.summary_line


class Education(ProfileItem):
    class Level(models.TextChoices):
        SECONDARY = 'secondary', 'Secondary School'
        CERTIFICATE = 'certificate', 'Certificate'
        DIPLOMA = 'diploma', 'Diploma'
        BACHELOR = 'bachelor', "Bachelor's Degree"
        MASTER = 'master', "Master's Degree"
        DOCTORATE = 'doctorate', 'Doctorate'
        PROFESSIONAL = 'professional', 'Professional Qualification'
        OTHER = 'other', 'Other'

    seeker = models.ForeignKey(SeekerProfile, on_delete=models.CASCADE, related_name='education_items')
    institution = models.CharField(max_length=150)
    qualification = models.CharField(max_length=150)
    field_of_study = models.CharField(max_length=150, blank=True)
    level = models.CharField(max_length=15, choices=Level.choices, blank=True)
    start_year = models.PositiveSmallIntegerField(null=True, blank=True)
    end_year = models.PositiveSmallIntegerField(null=True, blank=True)

    class Meta:
        ordering = ['-end_year', '-start_year', '-id']

    @property
    def period(self):
        return ' - '.join(str(y) for y in (self.start_year, self.end_year) if y)

    @property
    def summary_line(self):
        return f'{self.qualification}, {self.institution}'

    def __str__(self):
        return self.summary_line


class Certification(ProfileItem):
    seeker = models.ForeignKey(SeekerProfile, on_delete=models.CASCADE, related_name='certifications')
    name = models.CharField(max_length=150)
    issuer = models.CharField(max_length=150, blank=True)
    date_obtained = models.DateField(null=True, blank=True)
    expiry_date = models.DateField(null=True, blank=True)
    credential_number = models.CharField(max_length=100, blank=True)

    class Meta:
        ordering = ['-date_obtained', '-id']

    @property
    def summary_line(self):
        return f'{self.name}' + (f', {self.issuer}' if self.issuer else '')

    def __str__(self):
        return self.summary_line


class SpokenLanguage(ProfileItem):
    class Proficiency(models.TextChoices):
        BASIC = 'basic', 'Basic'
        CONVERSATIONAL = 'conversational', 'Conversational'
        PROFESSIONAL = 'professional', 'Professional'
        FLUENT = 'fluent', 'Fluent'
        NATIVE = 'native', 'Native'

    seeker = models.ForeignKey(SeekerProfile, on_delete=models.CASCADE, related_name='languages')
    language = models.CharField(max_length=60)
    proficiency = models.CharField(max_length=15, choices=Proficiency.choices)

    class Meta:
        ordering = ['id']

    @property
    def summary_line(self):
        return f'{self.language} ({self.get_proficiency_display()})'

    def __str__(self):
        return self.summary_line


class Project(ProfileItem):
    seeker = models.ForeignKey(SeekerProfile, on_delete=models.CASCADE, related_name='projects')
    name = models.CharField(max_length=150)
    role = models.CharField(max_length=120, blank=True)
    organisation = models.CharField(max_length=150, blank=True)
    date = models.CharField(max_length=40, blank=True)
    description = models.TextField(blank=True)
    link = models.URLField(blank=True)

    @property
    def summary_line(self):
        return self.name

    def __str__(self):
        return self.name


class Membership(ProfileItem):
    seeker = models.ForeignKey(SeekerProfile, on_delete=models.CASCADE, related_name='memberships')
    organisation = models.CharField(max_length=150)
    membership_type = models.CharField(max_length=100, blank=True)
    membership_number = models.CharField(max_length=60, blank=True)

    @property
    def summary_line(self):
        return self.organisation + (f' ({self.membership_type})' if self.membership_type else '')

    def __str__(self):
        return self.summary_line


class Achievement(ProfileItem):
    seeker = models.ForeignKey(SeekerProfile, on_delete=models.CASCADE, related_name='achievements')
    title = models.CharField(max_length=150)
    organisation = models.CharField(max_length=150, blank=True)
    year = models.PositiveSmallIntegerField(null=True, blank=True)
    description = models.TextField(blank=True)

    class Meta:
        ordering = ['-year', '-id']

    @property
    def summary_line(self):
        return self.title

    def __str__(self):
        return self.title


class VolunteerExperience(ProfileItem):
    seeker = models.ForeignKey(SeekerProfile, on_delete=models.CASCADE, related_name='volunteering')
    organisation = models.CharField(max_length=150)
    role = models.CharField(max_length=120, blank=True)
    start_date = models.CharField(max_length=40, blank=True)
    end_date = models.CharField(max_length=40, blank=True)
    description = models.TextField(blank=True)

    @property
    def period(self):
        return ' - '.join(x for x in (self.start_date, self.end_date) if x)

    @property
    def summary_line(self):
        return f'{self.role} at {self.organisation}' if self.role else self.organisation

    def __str__(self):
        return self.summary_line


class ProfessionalReference(ProfileItem):
    """Private: never shown on the public profile."""

    seeker = models.ForeignKey(SeekerProfile, on_delete=models.CASCADE, related_name='references')
    name = models.CharField(max_length=120)
    position = models.CharField(max_length=120, blank=True)
    organisation = models.CharField(max_length=150, blank=True)
    relationship = models.CharField(max_length=120, blank=True)
    email = models.EmailField(blank=True)
    phone = models.CharField(max_length=30, blank=True)
    authorise_contact = models.BooleanField(default=False)

    @property
    def summary_line(self):
        return self.name + (f', {self.organisation}' if self.organisation else '')

    def __str__(self):
        return self.summary_line
