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


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

    # groups= required: custom stored hr.employee fields without a group
    # restriction break any employee read by a non-HR user (see
    # xeno_attendance's xeno_employee_code for the incident this pattern
    # fixed). Purely cosmetic ordering data, not sensitive on its own, but
    # still has to carry this restriction or the whole employee UX breaks
    # for regular staff.
    xeno_org_sequence = fields.Integer(
        string="Org Chart Position", default=10, groups="hr.group_hr_user",
        help="Left-to-right display order among this employee's siblings "
             "on the Organization Chart page. Cosmetic only -- never "
             "affects the actual manager relationship (parent_id).",
    )

    @api.model
    def xeno_reorder_org_siblings(self, parent_id, ordered_ids):
        """Persist a new left-to-right order for one manager's direct
        reports (or the top-level group, when parent_id is False).

        Reorder-only by design: every id in ordered_ids must already
        report to parent_id, or the whole call is rejected -- this can
        never be used to change who anyone's manager is, only their
        display position among their existing peers.

        @api.model is required, not just idiomatic: core's call_kw
        dispatch (odoo/service/model.py) treats args[0] as record ids to
        browse() and strips it before calling the method UNLESS the
        method is @api.model -- without it, the JS caller's first
        positional arg (parent_id) was silently consumed as "ids" and
        ordered_ids never arrived (TypeError: missing 1 required
        positional argument).
        """
        if not self.env.user.has_group("hr_holidays.group_hr_holidays_user"):
            raise AccessError(_("Only HR officers can reorder the organization chart."))

        Employee = self.env["hr.employee"].sudo().with_context(active_test=False)
        employees = Employee.browse(ordered_ids)
        if len(employees) != len(ordered_ids):
            raise UserError(_("One or more employees could not be found."))

        expected_parent = parent_id or False
        actual_parents = {employee.parent_id.id or False for employee in employees}
        if actual_parents != {expected_parent}:
            raise UserError(_(
                "This action can only reorder employees who already share the same manager."))

        for index, employee in enumerate(employees):
            employee.xeno_org_sequence = (index + 1) * 10
