import logging

from odoo import _, http
from odoo.exceptions import UserError
from odoo.http import request
from odoo.tools import html_escape

_logger = logging.getLogger(__name__)

_PAGE = """<!DOCTYPE html><html><head><meta charset="utf-8">
<title>Overtime Request</title></head>
<body style="font-family:Arial,Helvetica,sans-serif;background:#f8f9fa;">
<div style="max-width:480px;margin:80px auto;text-align:center;padding:2rem;
            background:#fff;border:1px solid #d8e1e4;border-radius:8px;">
<h2 style="color:%(color)s;margin-top:0;">%(message)s</h2>
</div></body></html>"""

# Same "decision card" layout as xeno_leave's own _RESULT_PAGE, OT-specific
# fields (Requestor/Date/Time/Working Place) instead of leave dates/type.
_RESULT_PAGE = """<!DOCTYPE html><html><head><meta charset="utf-8">
<title>Overtime Request</title></head>
<body style="font-family:Arial,Helvetica,sans-serif;background:#3d5afe;margin:0;padding:48px 16px;">
<div style="max-width:420px;margin:0 auto;background:#f2f3f5;border-radius:14px;
            padding:32px 28px;text-align:center;box-shadow:0 6px 24px rgba(0,0,0,0.18);">
  <div style="font-weight:800;font-size:1.25rem;letter-spacing:0.03em;color:#1a2233;margin-bottom:18px;">
    OVERTIME REQUEST APPROVAL
  </div>
  <div style="border-top:1px solid #d8dce3;margin-bottom:18px;"></div>
  <div style="font-size:0.9rem;color:#4b5563;line-height:1.9;">
    Employee Name:<br/>
    <strong style="color:#1a2233;">%(employee)s</strong><br/>
    Date:<br/>
    <strong style="color:#1a2233;">%(date)s</strong><br/>
    Time:<br/>
    <strong style="color:#1a2233;">%(time)s</strong><br/>
    Working Place:<br/>
    <strong style="color:#1a2233;">%(working_place)s</strong>
  </div>
  <div style="font-weight:800;font-size:1.15rem;color:%(color)s;margin-top:22px;">
    Result: %(result)s Completed
  </div>
</div></body></html>"""


class XenoOvertimeEmailController(http.Controller):

    def _page(self, message, ok=True):
        color = "#1f7a4d" if ok else "#b21f22"
        return request.make_response(
            _PAGE % {"color": color, "message": message},
            headers=[("Content-Type", "text/html; charset=utf-8")],
        )

    def _result_page(self, rec, result_word, ok=True):
        R = rec.sudo()
        color = "#1f9d55" if ok else "#d32f2f"
        return request.make_response(
            _RESULT_PAGE % {
                "employee": html_escape(R.employee_id.name or ""),
                "date": html_escape(str(R.date or "")),
                "time": html_escape("%s to %s" % (
                    R._xeno_format_hour(R.time_from), R._xeno_format_hour(R.time_to))),
                "working_place": html_escape(R.working_place or "-"),
                "color": color,
                "result": result_word,
            },
            headers=[("Content-Type", "text/html; charset=utf-8")],
        )

    @http.route(
        "/odoo/overtime/email_action",
        type="http", auth="public", website=False, sitemap=False, csrf=False,
    )
    def email_action(self, request_id=None, stage=None, action=None,
                      user_id=None, exp=None, token=None, **kw):
        """Approve/Reject an OT request straight from the notification
        email. Same idiom as xeno_leave's own /odoo/leave/email_action:
        the signed token proves the link is genuine and unexpired for this
        exact request/stage/action/user; the real business permission
        still runs through the normal action_*_approve/reject checks."""
        env = request.env
        Request = env["hr.overtime.request"].sudo()

        try:
            request_id, user_id, exp = int(request_id), int(user_id), int(exp)
        except (TypeError, ValueError):
            return self._page(_("This link is malformed."), ok=False)

        if stage not in ("manager", "hod") or action not in ("approve", "reject"):
            return self._page(_("This link is malformed."), ok=False)

        if not Request._xeno_verify_email_token(request_id, stage, action, user_id, exp, token):
            return self._page(_("This link is invalid or has expired."), ok=False)

        rec = Request.browse(request_id)
        user = env["res.users"].sudo().browse(user_id)
        if not (rec.exists() and user.exists()):
            return self._page(_("This overtime request no longer exists."), ok=False)

        expected_state = "confirm" if stage == "manager" else "manager_approved"
        if rec.state != expected_state:
            return self._page(_(
                "This overtime request has already been processed (or isn't at "
                "this stage anymore)."))

        rec_as_user = rec.with_user(user)
        try:
            if stage == "manager":
                if action == "approve":
                    rec_as_user.action_manager_approve()
                    return self._result_page(rec, _("Approved"), ok=True)
                rec_as_user.action_manager_reject()
                return self._result_page(rec, _("Rejected"), ok=False)
            else:
                if action == "approve":
                    rec_as_user.action_hod_approve()
                    return self._result_page(rec, _("Approved"), ok=True)
                rec_as_user.action_hod_reject()
                return self._result_page(rec, _("Rejected"), ok=False)
        except UserError as e:
            return self._page(str(e), ok=False)
        except Exception:
            _logger.exception("xeno_overtime email_action failed for request %s stage %s", request_id, stage)
            return self._page(_(
                "Something went wrong processing this request. Please use the app instead."
            ), ok=False)
