import time

from odoo import _, api, models
from odoo.tools import html_escape
from odoo.tools.misc import hmac as odoo_hmac

TOKEN_SCOPE = "xeno_overtime_email_action"
TOKEN_VALID_SECONDS = 14 * 24 * 3600  # 14 days, same window as xeno_leave's own action links.

_HEADER = """
<div style="max-width:600px;margin:0 auto;font-family:Arial,Helvetica,sans-serif;color:#142933;border:1px solid #d8e1e4;">
  <div style="background:#142933;padding:14px 20px;">
    <div style="color:#fff;">
      <div style="font-weight:700;font-size:16px;">XenOptics HR System</div>
      <div style="font-size:12px;color:#b7c7cc;">Overtime Request</div>
    </div>
  </div>
  <div style="padding:20px;">
    <div style="display:flex;justify-content:space-between;align-items:baseline;margin-bottom:10px;">
      <h2 style="margin:0;font-size:20px;">%(title)s</h2>
      <a href="%(see_more)s" style="background:#ec1d23;color:#fff;padding:5px 12px;border-radius:14px;font-size:11px;text-decoration:none;">See More</a>
    </div>
    %(rows)s
    %(history)s
"""

_FOOTER = """
  </div>
  <div style="background:#142933;color:#b7c7cc;text-align:center;padding:8px;font-size:11px;">
    XenOptics HR &middot; Do not reply
  </div>
</div>
"""


def _esc(s):
    return html_escape(s if s is not None else "")


def _row(label, value):
    return '<div style="margin:6px 0;font-size:13px;"><strong>%s:</strong> %s</div>' % (label, value)


def _history_block(lines_html):
    if not lines_html:
        return ""
    return (
        '<div style="margin-top:16px;border-top:1px solid #d8e1e4;padding-top:12px;">'
        '<div style="font-weight:700;font-size:14px;margin-bottom:6px;">Approval History</div>'
        "%s"
        "</div>"
    ) % lines_html


class HrOvertimeRequest(models.Model):
    _inherit = "hr.overtime.request"

    @api.model
    def _xeno_email_token(self, request_id, stage, action, user_id, exp):
        message = (request_id, stage, action, user_id, exp)
        return odoo_hmac(self.env(su=True), TOKEN_SCOPE, message)

    @api.model
    def _xeno_verify_email_token(self, request_id, stage, action, user_id, exp, token):
        """Same idiom as xeno_leave's own email tokens: proves the link is
        genuine and unexpired, bound to this exact request/stage/action/
        user -- it does NOT replace the real action_*_approve/reject
        permission check, which still runs normally against whoever the
        link names."""
        if not token or time.time() > exp:
            return False
        expected = self._xeno_email_token(request_id, stage, action, user_id, exp)
        import hmac as _hmac_lib
        return _hmac_lib.compare_digest(expected, token)

    def _xeno_email_action_url(self, stage, action, user_id, base_url=None):
        self.ensure_one()
        exp = int(time.time()) + TOKEN_VALID_SECONDS
        token = self._xeno_email_token(self.id, stage, action, user_id, exp)
        base_url = base_url or self.env["ir.config_parameter"].sudo().get_param("web.base.url")
        return (
            "%s/odoo/overtime/email_action?request_id=%s&stage=%s&action=%s"
            "&user_id=%s&exp=%s&token=%s" % (base_url, self.id, stage, action, user_id, exp, token)
        )

    def _xeno_see_more_url(self, base_url=None):
        self.ensure_one()
        base_url = base_url or self.env["ir.config_parameter"].sudo().get_param("web.base.url")
        action_id = self.env.ref("xeno_overtime.action_hr_overtime_approvals").id
        return "%s/odoo/action-%s/%s" % (base_url, action_id, self.id)

    def _xeno_request_email_rows(self):
        self.ensure_one()
        R = self.sudo()
        emp = R.employee_id
        rows = [
            _row("Requestor", _esc(emp.name)),
            _row("Position", _esc(emp.job_title or "-")),
            _row("Department", _esc(emp.department_id.name or "-")),
            _row("Supervisor Name", _esc(R.supervisor_id.name)),
            _row("Head of Department", _esc(R.head_of_department_id.name)),
            _row("Date", _esc(str(R.date or ""))),
            _row("Time", "%s to %s" % (
                self._xeno_format_hour(R.time_from), self._xeno_format_hour(R.time_to))),
            _row("Working Place", _esc(R.working_place or "-")),
            _row("Description of duties", _esc(R.description or "-")),
        ]
        if R.rejection_reason:
            rows.append(_row("Remark", _esc(R.rejection_reason)))
        return "".join(rows)

    def _xeno_render_approver_email_html(self, stage):
        self.ensure_one()
        R = self.sudo()
        base_url = self.env["ir.config_parameter"].sudo().get_param("web.base.url")
        see_more_url = R._xeno_see_more_url(base_url)
        recipient = R.supervisor_id if stage == "manager" else R.head_of_department_id
        user = recipient.user_id
        approve_url = R._xeno_email_action_url(stage, "approve", user.id, base_url)
        reject_url = R._xeno_email_action_url(stage, "reject", user.id, base_url)

        title = (
            "Manager Approval for Overtime Request" if stage == "manager"
            else "Head of Department Approval for Overtime Request"
        )
        history = ""
        if stage == "hod":
            # Mirrors the Manager's own decision back to the HOD, same
            # purpose as xeno_leave's _render_approval_history -- the
            # next approver in the chain can see who signed off before
            # them and when, without having to open the record.
            history = _history_block(
                '<div style="margin:4px 0;font-size:13px;">'
                "Supervisor: %s<br/>Supervisor Approve Status: Approved<br/>"
                "Supervisor Approve Time: %s"
                "</div>" % (
                    _esc(R.supervisor_id.name),
                    _esc(str(R.manager_decided_at or "")),
                )
            )

        body = (_HEADER % {
            "title": _esc(title),
            "see_more": see_more_url,
            "rows": R._xeno_request_email_rows(),
            "history": history,
        }) + ("""
    <hr style="border:none;border-top:1px solid #d8e1e4;margin:16px 0;"/>
    <div style="text-align:center;font-size:13px;margin-bottom:14px;">
      You have an Overtime Request awaiting your approval.
    </div>
    <div style="text-align:center;">
      <a href="%(approve)s" style="display:inline-block;background:#dff2e6;color:#1f7a4d;font-weight:700;padding:8px 22px;border-radius:16px;text-decoration:none;margin:0 6px;">Approve</a>
      <a href="%(reject)s" style="display:inline-block;background:#fbdad9;color:#b21f22;font-weight:700;padding:8px 22px;border-radius:16px;text-decoration:none;margin:0 6px;">Reject</a>
    </div>
""" % {"approve": approve_url, "reject": reject_url}) + _FOOTER

        return body

    def _xeno_send_approver_email(self, stage):
        """stage: 'manager' (right after creation) or 'hod' (right after
        the Manager approves). Silently skipped if that approver has no
        linked user/email -- same as xeno_leave's own recipient handling."""
        for rec in self:
            recipient = rec.supervisor_id if stage == "manager" else rec.head_of_department_id
            user = recipient.user_id
            if not user or not user.email:
                continue
            html = rec._xeno_render_approver_email_html(stage)
            self.env["mail.mail"].sudo().create({
                "subject": _("Overtime Request Approval – %s", rec.employee_id.name),
                "body_html": html,
                "email_to": user.email,
                "auto_delete": True,
            }).send()

    def _xeno_notify_employee(self, message):
        """Overrides the plain-text version from hr_overtime_request.py --
        same chatter note, but the email is now the same branded HTML
        shell as the approver's action email (read-only, no
        Approve/Reject links), instead of a bare <p> paragraph."""
        self.ensure_one()
        self.message_post(body=message)
        email = self.employee_id.work_email or (self.employee_id.user_id.email if self.employee_id.user_id else False)
        if not email:
            return
        R = self.sudo()
        base_url = self.env["ir.config_parameter"].sudo().get_param("web.base.url")
        body = (_HEADER % {
            "title": _esc(str(message)),
            "see_more": R._xeno_see_more_url(base_url),
            "rows": R._xeno_request_email_rows(),
            "history": "",
        }) + _FOOTER
        self.env["mail.mail"].sudo().create({
            "subject": _("Overtime Request Update – %s", self.employee_id.name),
            "body_html": body,
            "email_to": email,
            "auto_delete": True,
        }).send()
