import logging

from odoo import _, api, models
from odoo.exceptions import UserError

_logger = logging.getLogger(__name__)


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

    def _xeno_auto_login_password(self):
        """login = xeno_employee_code (xeno_attendance's own auto-generated
        employee code -- same convention already used for the placeholder
        approver logins in xeno_leave). password = the last 4 digits of ID
        Card Number, falling back to Passport Number if no ID card number
        is on file. Returns (login, password) or (False, False) if either
        piece isn't available yet -- this is checked on both create and
        write so it fires whichever of "code" and "ID/passport number"
        happens to be filled in last, not just at creation time."""
        self.ensure_one()
        login = self.xeno_employee_code
        if not login:
            return False, False
        source = self.identification_id or self.passport_id or ""
        digits = "".join(ch for ch in source if ch.isdigit())
        if len(digits) < 4:
            return False, False
        return login, digits[-4:]

    def _xeno_auto_create_user(self):
        for employee in self:
            if employee.user_id:
                continue
            login, password = employee._xeno_auto_login_password()
            if not login:
                continue
            if self.env["res.users"].sudo().search_count([("login", "=", login)]):
                _logger.warning(
                    "xeno_theme_slate: skipped auto-creating a login for employee "
                    "%s (id %s) -- login %r already exists on another user.",
                    employee.name, employee.id, login)
                continue
            user = self.env["res.users"].sudo().with_context(no_reset_password=True).create({
                "name": employee.name,
                "login": login,
                "password": password,
                "group_ids": [(6, 0, [self.env.ref("base.group_user").id])],
            })
            employee.sudo().user_id = user.id
            employee.message_post(body=_("Self-service login auto-created (login: %s).", login))

    def action_xeno_reset_user_password(self):
        """HR-facing "Reset Password" button (hr_employee_reset_password_
        views.xml) -- resets the employee's login back to the SAME default
        this deployment already uses for a brand-new login (last 4 digits
        of ID Card/Passport, see _xeno_auto_login_password() above), rather
        than an arbitrary HR-typed password: predictable, and there's
        nothing new for HR to communicate out-of-band since the employee
        already knows to try their own ID/passport digits. Settings > Users
        itself is Administrator-only in this deployment (hr.group_hr_user
        doesn't include base.group_system), so this is the one narrow,
        explicitly-gated write HR needs -- not a broader admin grant."""
        self.ensure_one()
        if not self.env.user.has_group("hr.group_hr_user"):
            raise UserError(_("Only HR can reset an employee's login password."))
        if not self.user_id:
            raise UserError(_("%s doesn't have a login yet.", self.name))
        login, password = self._xeno_auto_login_password()
        if not password:
            raise UserError(_(
                "Can't compute a default password for %s -- no ID Card or "
                "Passport number on file to derive the last 4 digits from.",
                self.name))
        # Writing `password` directly never sends any email regardless of
        # context (confirmed against core: _set_password's inverse is a
        # plain hash-and-store, no notification path at all -- unlike
        # create(), no_reset_password only guards auth_signup's own
        # create() override, so it would be a no-op here).
        self.user_id.sudo().write({"password": password})
        self.message_post(body=_("Login password reset by %(user)s.", user=self.env.user.name))
        return {
            "type": "ir.actions.client",
            "tag": "display_notification",
            "params": {
                "type": "success",
                "title": _("Password Reset"),
                "message": _("%(name)s's password has been reset to: %(password)s",
                              name=self.name, password=password),
                "sticky": True,
            },
        }

    @api.model_create_multi
    def create(self, vals_list):
        records = super().create(vals_list)
        records._xeno_auto_create_user()
        return records

    def write(self, vals):
        result = super().write(vals)
        if {"xeno_employee_code", "identification_id", "passport_id"} & set(vals):
            self._xeno_auto_create_user()
        return result
