from dateutil.relativedelta import relativedelta

from odoo import _, api, fields, models


class HrEmployee(models.Model):
    _inherit = "hr.employee"

    # XENHR employee_foreigner_details columns with no core equivalent.
    # groups= required: custom stored hr.employee fields without a group
    # restriction break employee reads by non-HR users (hr.employee.public's
    # private-fields check rejects fields it doesn't know).
    xeno_passport_issue_place = fields.Char(
        string="Passport Issue Place", groups="hr.group_hr_user", tracking=True)
    xeno_passport_issue_date = fields.Date(
        string="Passport Issue Date", groups="hr.group_hr_user", tracking=True)
    xeno_visa_issue_date = fields.Date(
        string="Visa Issue Date", groups="hr.group_hr_user", tracking=True)

    # Once-per-expiry-date alert latches (core has the equivalent
    # work_permit_scheduled_activity for permits, nothing for visa/passport).
    xeno_visa_alerted = fields.Boolean(
        default=False, groups="hr.group_hr_user")
    xeno_passport_alerted = fields.Boolean(
        default=False, groups="hr.group_hr_user")

    def write(self, vals):
        # Same pattern core uses for work_permit_scheduled_activity: a new
        # expiry date re-arms its alert.
        if "visa_expire" in vals:
            vals["xeno_visa_alerted"] = False
        if "passport_expiration_date" in vals:
            vals["xeno_passport_alerted"] = False
        return super().write(vals)

    @api.model
    def notify_expiring_contract_work_permit(self):
        # Full override, no super(): core's work-permit branch only matches
        # expiry == today + notice_period EXACTLY, so any date first recorded
        # already inside the window (exactly what the XENHR
        # employee_foreigner_details import will do) never alerts. Replaced
        # with windowed checks latched by a per-date flag, and extended to
        # visa and passport expiry, which core doesn't watch at all.
        today = fields.Date.today()
        Employee = self.env["hr.employee"]

        for company in self.env["res.company"].search([]):
            # Contract branch: identical to core.
            expiring_contract = Employee.search([
                ("company_id", "=", company.id),
                ("contract_date_start", "!=", False),
                ("contract_date_start", "<", today),
                ("contract_date_end", "=", today + relativedelta(
                    days=company.contract_expiration_notice_period)),
            ])
            for employee in expiring_contract:
                employee.with_context(
                    mail_activity_quick_update=True).activity_schedule(
                    "mail.mail_activity_data_todo", employee.contract_date_end,
                    _("The contract of %s is about to expire.", employee.name),
                    user_id=employee.hr_responsible_id.id or self.env.uid)

            deadline = today + relativedelta(
                days=company.work_permit_expiration_notice_period)
            document_checks = [
                ("work_permit_expiration_date", "work_permit_scheduled_activity",
                 _("The work permit of %s is about to expire.")),
                ("visa_expire", "xeno_visa_alerted",
                 _("The visa of %s is about to expire.")),
                ("passport_expiration_date", "xeno_passport_alerted",
                 _("The passport of %s is about to expire.")),
            ]
            for date_field, flag_field, summary in document_checks:
                expiring = Employee.search([
                    ("company_id", "=", company.id),
                    (date_field, "!=", False),
                    (date_field, "<=", deadline),
                    (flag_field, "=", False),
                ])
                for employee in expiring:
                    employee.with_context(
                        mail_activity_quick_update=True).activity_schedule(
                        "mail.mail_activity_data_todo", employee[date_field],
                        summary % employee.name,
                        user_id=employee.hr_responsible_id.id or self.env.uid)
                expiring.write({flag_field: True})
        return True
