from django.db import migrations, models
import uuid


def _all_models():
    return [
        # ═════════════════════════════════════════════════════════
        # JobTitle
        # ═════════════════════════════════════════════════════════
        migrations.CreateModel(
            name="JobTitle",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("updated_at", models.DateTimeField(auto_now=True)),
                ("title", models.CharField(max_length=120)),
                ("level", models.PositiveSmallIntegerField(default=1)),
                ("tenant", models.ForeignKey(
                    on_delete=models.deletion.CASCADE, related_name="+",
                    to="tenants.tenant",
                )),
                ("organization_node", models.ForeignKey(
                    blank=True, null=True,
                    on_delete=models.deletion.SET_NULL, related_name="+",
                    to="organizations.organizationnode",
                )),
                ("department", models.ForeignKey(
                    blank=True, null=True,
                    on_delete=models.deletion.SET_NULL, related_name="job_titles",
                    to="organizations.organizationnode",
                )),
            ],
            options={
                "db_table": "hr_jobtitle",
                "ordering": ["title"],
            },
        ),
        migrations.AddConstraint(
            model_name="jobtitle",
            constraint=models.UniqueConstraint(
                fields=["tenant", "title"],
                name="hr_jobtitle_unique_tenant_title",
            ),
        ),
        # ═════════════════════════════════════════════════════════
        # Employee
        # ═════════════════════════════════════════════════════════
        migrations.CreateModel(
            name="Employee",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("updated_at", models.DateTimeField(auto_now=True)),
                ("public_id", models.CharField(default=uuid.uuid4, max_length=32, unique=True)),
                ("tenant", models.ForeignKey(
                    on_delete=models.deletion.CASCADE, related_name="+",
                    to="tenants.tenant",
                )),
                ("organization_node", models.ForeignKey(
                    on_delete=models.deletion.PROTECT, related_name="+",
                    to="organizations.organizationnode",
                )),
                ("is_deleted", models.BooleanField(default=False)),
                ("deleted_at", models.DateTimeField(blank=True, null=True)),
                ("deleted_by", models.ForeignKey(
                    blank=True, null=True,
                    on_delete=models.deletion.SET_NULL, related_name="+",
                    to="accounts.user",
                )),
                ("version", models.PositiveIntegerField(default=1)),
                ("user", models.OneToOneField(
                    blank=True, null=True,
                    on_delete=models.deletion.SET_NULL, related_name="employee_profile",
                    to="accounts.user",
                )),
                ("employee_no", models.CharField(blank=True, max_length=30)),
                ("first_name", models.CharField(max_length=80)),
                ("last_name", models.CharField(max_length=80)),
                ("display_name", models.CharField(blank=True, max_length=160)),
                ("national_id", models.CharField(blank=True, max_length=512)),
                ("birth_date", models.DateField(blank=True, null=True)),
                ("gender", models.CharField(blank=True, max_length=20)),
                ("mobile", models.CharField(blank=True, max_length=30)),
                ("personal_email", models.EmailField(blank=True, max_length=254)),
                ("work_email", models.EmailField(blank=True, max_length=254)),
                ("employment_type", models.CharField(default="full_time", max_length=20)),
                ("hire_date", models.DateField()),
                ("termination_date", models.DateField(blank=True, null=True)),
                ("status", models.CharField(default="active", max_length=20)),
                ("work_location", models.CharField(blank=True, max_length=200)),
                ("department", models.ForeignKey(
                    blank=True, null=True,
                    on_delete=models.deletion.SET_NULL, related_name="employees",
                    to="organizations.organizationnode",
                )),
                ("manager", models.ForeignKey(
                    blank=True, null=True,
                    on_delete=models.deletion.SET_NULL, related_name="direct_reports",
                    to="hr_core.employee",
                )),
                ("job_title", models.ForeignKey(
                    blank=True, null=True,
                    on_delete=models.deletion.SET_NULL, related_name="employees",
                    to="hr_core.jobtitle",
                )),
                ("extra_data", models.JSONField(blank=True, default=dict)),
            ],
            options={
                "db_table": "hr_employee",
                "ordering": ["last_name", "first_name"],
            },
        ),
        migrations.AddConstraint(
            model_name="employee",
            constraint=models.UniqueConstraint(
                fields=["tenant", "employee_no"],
                condition=models.Q(employee_no__gt=""),
                name="hr_employee_unique_tenant_employee_no",
            ),
        ),
        # ═════════════════════════════════════════════════════════
        # EmployeeDocument
        # ═════════════════════════════════════════════════════════
        migrations.CreateModel(
            name="EmployeeDocument",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("updated_at", models.DateTimeField(auto_now=True)),
                ("public_id", models.CharField(default=uuid.uuid4, max_length=32, unique=True)),
                ("tenant", models.ForeignKey(
                    blank=True, null=True,
                    on_delete=models.deletion.CASCADE, related_name="+",
                    to="tenants.tenant",
                )),
                ("organization_node", models.ForeignKey(
                    blank=True, null=True,
                    on_delete=models.deletion.SET_NULL, related_name="+",
                    to="organizations.organizationnode",
                )),
                ("employee", models.ForeignKey(
                    on_delete=models.deletion.CASCADE, related_name="documents",
                    to="hr_core.employee",
                )),
                ("doc_type", models.CharField(default="other", max_length=20)),
                ("dms_file_id", models.CharField(blank=True, max_length=36)),
                ("title", models.CharField(blank=True, max_length=200)),
                ("expiry_date", models.DateField(blank=True, null=True)),
                ("is_verified", models.BooleanField(default=False)),
            ],
            options={
                "db_table": "hr_employeedocument",
                "ordering": ["-created_at"],
            },
        ),
        # ═════════════════════════════════════════════════════════
        # EmployeeBankAccount
        # ═════════════════════════════════════════════════════════
        migrations.CreateModel(
            name="EmployeeBankAccount",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("updated_at", models.DateTimeField(auto_now=True)),
                ("public_id", models.CharField(default=uuid.uuid4, max_length=32, unique=True)),
                ("tenant", models.ForeignKey(
                    blank=True, null=True,
                    on_delete=models.deletion.CASCADE, related_name="+",
                    to="tenants.tenant",
                )),
                ("organization_node", models.ForeignKey(
                    blank=True, null=True,
                    on_delete=models.deletion.SET_NULL, related_name="+",
                    to="organizations.organizationnode",
                )),
                ("employee", models.ForeignKey(
                    on_delete=models.deletion.CASCADE, related_name="bank_accounts",
                    to="hr_core.employee",
                )),
                ("bank_name", models.CharField(max_length=120)),
                ("account_no", models.CharField(max_length=512)),
                ("iban", models.CharField(blank=True, max_length=512)),
                ("is_default", models.BooleanField(default=False)),
            ],
            options={
                "db_table": "hr_employeebankaccount",
                "ordering": ["-is_default", "bank_name"],
            },
        ),
        migrations.AddConstraint(
            model_name="employeebankaccount",
            constraint=models.UniqueConstraint(
                fields=["employee", "is_default"],
                condition=models.Q(is_default=True),
                name="hr_bank_account_one_default_per_employee",
            ),
        ),
        # ═════════════════════════════════════════════════════════
        # LeaveType
        # ═════════════════════════════════════════════════════════
        migrations.CreateModel(
            name="LeaveType",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("updated_at", models.DateTimeField(auto_now=True)),
                ("tenant", models.ForeignKey(
                    on_delete=models.deletion.CASCADE, related_name="leave_types",
                    to="tenants.tenant",
                )),
                ("name", models.CharField(max_length=120)),
                ("code", models.CharField(max_length=40)),
                ("color", models.CharField(blank=True, default="#4A90D9", max_length=20)),
                ("is_paid", models.BooleanField(default=True)),
                ("requires_approval", models.BooleanField(default=True)),
                ("max_days_per_year", models.DecimalField(blank=True, decimal_places=2, max_digits=6, null=True)),
                ("carry_forward_days", models.DecimalField(decimal_places=2, default=0, max_digits=6)),
                ("accrual_method", models.CharField(default="upfront", max_length=20)),
            ],
            options={
                "db_table": "hr_leavetype",
                "ordering": ["name"],
            },
        ),
        migrations.AddConstraint(
            model_name="leavetype",
            constraint=models.UniqueConstraint(
                fields=["tenant", "code"],
                name="hr_leavetype_unique_tenant_code",
            ),
        ),
        # ═════════════════════════════════════════════════════════
        # PublicHoliday
        # ═════════════════════════════════════════════════════════
        migrations.CreateModel(
            name="PublicHoliday",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("updated_at", models.DateTimeField(auto_now=True)),
                ("tenant", models.ForeignKey(
                    on_delete=models.deletion.CASCADE, related_name="public_holidays",
                    to="tenants.tenant",
                )),
                ("date", models.DateField()),
                ("name", models.CharField(max_length=200)),
                ("calendar_type", models.CharField(default="gregorian", max_length=20)),
                ("is_recurring", models.BooleanField(default=False)),
            ],
            options={
                "db_table": "hr_publicholiday",
                "ordering": ["date"],
            },
        ),
        migrations.AddConstraint(
            model_name="publicholiday",
            constraint=models.UniqueConstraint(
                fields=["tenant", "date", "calendar_type"],
                name="hr_publicholiday_unique_tenant_date_calendar",
            ),
        ),
        # ═════════════════════════════════════════════════════════
        # LeaveBalance
        # ═════════════════════════════════════════════════════════
        migrations.CreateModel(
            name="LeaveBalance",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("updated_at", models.DateTimeField(auto_now=True)),
                ("employee", models.ForeignKey(
                    on_delete=models.deletion.CASCADE, related_name="leave_balances",
                    to="hr_core.employee",
                )),
                ("leave_type", models.ForeignKey(
                    on_delete=models.deletion.CASCADE, related_name="balances",
                    to="hr_core.leavetype",
                )),
                ("year", models.PositiveSmallIntegerField()),
                ("allocated", models.DecimalField(decimal_places=2, default=0, max_digits=6)),
                ("used", models.DecimalField(decimal_places=2, default=0, max_digits=6)),
                ("pending", models.DecimalField(decimal_places=2, default=0, max_digits=6)),
            ],
            options={
                "db_table": "hr_leavebalance",
                "ordering": ["-year", "leave_type__name"],
            },
        ),
        migrations.AddConstraint(
            model_name="leavebalance",
            constraint=models.UniqueConstraint(
                fields=["employee", "leave_type", "year"],
                name="hr_leavebalance_unique_employee_type_year",
            ),
        ),
        # ═════════════════════════════════════════════════════════
        # LeaveRequest
        # ═════════════════════════════════════════════════════════
        migrations.CreateModel(
            name="LeaveRequest",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("updated_at", models.DateTimeField(auto_now=True)),
                ("public_id", models.CharField(default=uuid.uuid4, max_length=32, unique=True)),
                ("tenant", models.ForeignKey(
                    on_delete=models.deletion.CASCADE, related_name="leave_requests",
                    to="tenants.tenant",
                )),
                ("employee", models.ForeignKey(
                    on_delete=models.deletion.CASCADE, related_name="leave_requests",
                    to="hr_core.employee",
                )),
                ("leave_type", models.ForeignKey(
                    on_delete=models.deletion.PROTECT, related_name="requests",
                    to="hr_core.leavetype",
                )),
                ("from_date", models.DateField()),
                ("to_date", models.DateField()),
                ("days_requested", models.DecimalField(decimal_places=2, default=0, max_digits=6)),
                ("reason", models.TextField(blank=True)),
                ("status", models.CharField(default="draft", max_length=20)),
                ("submitted_at", models.DateTimeField(blank=True, null=True)),
                ("reviewed_by", models.ForeignKey(
                    blank=True, null=True,
                    on_delete=models.deletion.SET_NULL, related_name="reviewed_leave_requests",
                    to="accounts.user",
                )),
                ("reviewed_at", models.DateTimeField(blank=True, null=True)),
                ("review_note", models.TextField(blank=True)),
            ],
            options={
                "db_table": "hr_leaverequest",
                "ordering": ["-created_at"],
            },
        ),
        # ═════════════════════════════════════════════════════════
        # ShiftDefinition
        # ═════════════════════════════════════════════════════════
        migrations.CreateModel(
            name="ShiftDefinition",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("updated_at", models.DateTimeField(auto_now=True)),
                ("tenant", models.ForeignKey(
                    on_delete=models.deletion.CASCADE, related_name="shift_definitions",
                    to="tenants.tenant",
                )),
                ("name", models.CharField(max_length=120)),
                ("start_time", models.TimeField()),
                ("end_time", models.TimeField()),
                ("work_days", models.JSONField(default=list)),
                ("break_minutes", models.PositiveSmallIntegerField(default=0)),
            ],
            options={
                "db_table": "hr_shiftdefinition",
                "ordering": ["name"],
            },
        ),
        migrations.AddConstraint(
            model_name="shiftdefinition",
            constraint=models.UniqueConstraint(
                fields=["tenant", "name"],
                name="hr_shiftdef_unique_tenant_name",
            ),
        ),
        # ═════════════════════════════════════════════════════════
        # EmployeeShift
        # ═════════════════════════════════════════════════════════
        migrations.CreateModel(
            name="EmployeeShift",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("updated_at", models.DateTimeField(auto_now=True)),
                ("employee", models.ForeignKey(
                    on_delete=models.deletion.CASCADE, related_name="shift_assignments",
                    to="hr_core.employee",
                )),
                ("shift", models.ForeignKey(
                    on_delete=models.deletion.PROTECT, related_name="employee_assignments",
                    to="hr_core.shiftdefinition",
                )),
                ("effective_from", models.DateField()),
                ("effective_to", models.DateField(blank=True, null=True)),
            ],
            options={
                "db_table": "hr_employeeshift",
                "ordering": ["-effective_from"],
            },
        ),
        # ═════════════════════════════════════════════════════════
        # AttendanceRecord
        # ═════════════════════════════════════════════════════════
        migrations.CreateModel(
            name="AttendanceRecord",
            fields=[
                ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
                ("created_at", models.DateTimeField(auto_now_add=True)),
                ("updated_at", models.DateTimeField(auto_now=True)),
                ("public_id", models.CharField(default=uuid.uuid4, max_length=32, unique=True)),
                ("tenant", models.ForeignKey(
                    on_delete=models.deletion.CASCADE, related_name="attendance_records",
                    to="tenants.tenant",
                )),
                ("employee", models.ForeignKey(
                    on_delete=models.deletion.CASCADE, related_name="attendance_records",
                    to="hr_core.employee",
                )),
                ("date", models.DateField()),
                ("check_in", models.TimeField(blank=True, null=True)),
                ("check_out", models.TimeField(blank=True, null=True)),
                ("work_minutes", models.PositiveIntegerField(blank=True, null=True)),
                ("overtime_minutes", models.PositiveIntegerField(default=0)),
                ("source", models.CharField(default="manual", max_length=20)),
                ("note", models.TextField(blank=True, default="")),
                ("is_finalized", models.BooleanField(default=False)),
            ],
            options={
                "db_table": "hr_attendancerecord",
                "ordering": ["-date"],
            },
        ),
        migrations.AddConstraint(
            model_name="attendancerecord",
            constraint=models.UniqueConstraint(
                fields=["tenant", "employee", "date"],
                name="hr_attendance_unique_tenant_employee_date",
            ),
        ),
    ]


_MODELS = _all_models()


class Migration(migrations.Migration):
    initial = True

    dependencies = [
        ("tenants", "0001_initial"),
        ("organizations", "0002_workspace_template_user_context_pref"),
        ("accounts", "0001_initial"),
    ]

    operations = [
        migrations.SeparateDatabaseAndState(
            database_operations=_MODELS,
            state_operations=_MODELS,
        ),
    ]
