from django.conf import settings
from django.db import models
from apps.core.models import TimeStampedModel
from apps.organization.models import Company, Branch, Department, Designation, Shift

class Employee(TimeStampedModel):
    class Status(models.TextChoices):
        ACTIVE="ACTIVE","Active"; PROBATION="PROBATION","Probation"; CONFIRMED="CONFIRMED","Confirmed"; SUSPENDED="SUSPENDED","Suspended"; RESIGNED="RESIGNED","Resigned"; TERMINATED="TERMINATED","Terminated"; RETIRED="RETIRED","Retired"; INACTIVE="INACTIVE","Inactive"
    class Gender(models.TextChoices):
        MALE="MALE","Male"; FEMALE="FEMALE","Female"; OTHER="OTHER","Other"
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name="employee_profile")
    company = models.ForeignKey(Company, on_delete=models.PROTECT, related_name="employees")
    employee_code = models.CharField(max_length=30)
    full_name = models.CharField(max_length=200)
    father_name = models.CharField(max_length=200, blank=True)
    mother_name = models.CharField(max_length=200, blank=True)
    date_of_birth = models.DateField(null=True, blank=True)
    gender = models.CharField(max_length=10, choices=Gender.choices, blank=True)
    marital_status = models.CharField(max_length=30, blank=True)
    blood_group = models.CharField(max_length=10, blank=True)
    nid_or_passport = models.CharField(max_length=60, blank=True)
    mobile = models.CharField(max_length=30, blank=True)
    email = models.EmailField(blank=True)
    present_address = models.TextField(blank=True)
    permanent_address = models.TextField(blank=True)
    emergency_contact = models.CharField(max_length=100, blank=True)
    branch = models.ForeignKey(Branch, on_delete=models.PROTECT, related_name="employees")
    department = models.ForeignKey(Department, on_delete=models.PROTECT, related_name="employees")
    designation = models.ForeignKey(Designation, on_delete=models.PROTECT, related_name="employees")
    shift = models.ForeignKey(Shift, on_delete=models.PROTECT, null=True, blank=True, related_name="employees")
    reporting_manager = models.ForeignKey("self", on_delete=models.PROTECT, null=True, blank=True, related_name="direct_reports")
    employee_type = models.CharField(max_length=60, default="Permanent")
    joining_date = models.DateField()
    confirmation_date = models.DateField(null=True, blank=True)
    # Canonical service-end date. It is controlled by the exit lifecycle, not normal profile editing.
    employment_end_date = models.DateField(null=True, blank=True, db_index=True)
    status = models.CharField(max_length=20, choices=Status.choices, default=Status.ACTIVE)
    weekly_holiday = models.CharField(max_length=20, default="Friday")
    ot_eligible = models.BooleanField(default=False)
    photo = models.ImageField(upload_to="employees/photos/", blank=True)
    class Meta:
        constraints = [models.UniqueConstraint(fields=["company", "employee_code"], name="uq_employee_company_code")]
        indexes = [models.Index(fields=["company", "employee_code"]), models.Index(fields=["status", "department"])]
    def __str__(self): return f"{self.employee_code} - {self.full_name}"

class EmployeeDocument(TimeStampedModel):
    employee = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name="documents")
    document_type = models.CharField(max_length=80)
    title = models.CharField(max_length=150)
    file = models.FileField(upload_to="employees/documents/")
    expires_on = models.DateField(null=True, blank=True)

class CustomFieldDefinition(TimeStampedModel):
    company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name="employee_custom_fields")
    key = models.SlugField(max_length=80)
    label = models.CharField(max_length=120)
    field_type = models.CharField(max_length=20, default="text")
    is_required = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    class Meta:
        constraints = [models.UniqueConstraint(fields=["company", "key"], name="uq_emp_custom_field_key")]

class CustomFieldValue(TimeStampedModel):
    employee = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name="custom_values")
    definition = models.ForeignKey(CustomFieldDefinition, on_delete=models.PROTECT, related_name="values")
    value = models.TextField(blank=True)
    class Meta:
        constraints = [models.UniqueConstraint(fields=["employee", "definition"], name="uq_emp_custom_field_value")]


class EmployeePaymentAccount(TimeStampedModel):
    class Method(models.TextChoices):
        BANK = "BANK", "Bank Transfer"
        CASH = "CASH", "Cash"
        MFS = "MFS", "Mobile Financial Service"

    employee = models.OneToOneField(Employee, on_delete=models.PROTECT, related_name="payment_account")
    payment_method = models.CharField(max_length=20, choices=Method.choices, default=Method.BANK)
    account_name = models.CharField(max_length=160, blank=True)
    bank_name = models.CharField(max_length=160, blank=True)
    bank_branch = models.CharField(max_length=160, blank=True)
    account_number = models.CharField(max_length=80, blank=True)
    routing_number = models.CharField(max_length=40, blank=True)
    wallet_provider = models.CharField(max_length=80, blank=True)
    wallet_number = models.CharField(max_length=40, blank=True)
    is_active = models.BooleanField(default=True)

    @property
    def masked_destination(self):
        value = self.account_number if self.payment_method == self.Method.BANK else self.wallet_number
        if not value:
            return "—"
        value = str(value)
        return ("*" * max(0, len(value) - 4)) + value[-4:]

    def __str__(self):
        return f"{self.employee.employee_code} - {self.get_payment_method_display()}"
