"""HR Job extension: commission tab fields + V9-faithful affiliate commission
lifecycle.

V9 flow (job_board/controllers/job_offers.py:1223-1242 + 1731-1740):
  1. Recruiter pays → commission created as **pending**   ← x_is_paid flip
  2. Job publishes  → commission flipped to **completed**  ← is_published flip
  3. Job deleted    → commission flipped to **canceled**

``x_is_paid`` is the V18 hook for step 1. It can be ticked manually by admin
today and will eventually be wired to the payment gateway when the checkout
flow is built in contract_management/website_sale.

Backward compat: jobs published without x_is_paid (admin-created) still get
a direct completed commission so existing behavior is preserved.
"""

import logging

from odoo import _, api, fields, models

_logger = logging.getLogger(__name__)


class HrJob(models.Model):
    _inherit = "hr.job"

    base_amount = fields.Monetary(
        string="Base Commission Amount",
        required=True,
        default=0.0,
        currency_field="currency_id",
        tracking=True,
        help="Base commission amount for this job. Distributed among "
             "affiliated partners according to their commission percentage.",
    )
    tracker_factor = fields.Float(
        string="Tracker Factor", default=1.0, tracking=True,
        help="Multiplier applied to the base amount before splitting.",
    )
    x_is_paid = fields.Boolean(
        string="Payment Confirmed",
        default=False,
        tracking=True,
        help="Tick when the recruiter's job package payment is confirmed. "
             "Creates a pending affiliate commission (V9 step 1). "
             "The commission flips to Completed automatically on job publish.",
    )
    partner_commission_ids = fields.One2many(
        comodel_name="job.partner.commission",
        inverse_name="job_id",
        string="Partner Commissions",
    )
    amount_total = fields.Monetary(
        string="Total", store=True, compute="_compute_amount_total",
        currency_field="currency_id",
        help="Total commission amount across all partners for this job.",
    )
    currency_id = fields.Many2one(
        comodel_name="res.currency",
        default=lambda self: self.env.company.currency_id,
    )

    _sql_constraints = [
        ("check_track_factor",
         "CHECK(tracker_factor > 0)",
         "Tracker Factor must be > 0 (default 1)."),
    ]

    @api.depends("partner_commission_ids", "partner_commission_ids.commission_amount")
    def _compute_amount_total(self):
        for rec in self:
            rec.amount_total = sum(
                rec.partner_commission_ids.filtered(
                    lambda c: c.transaction_type == "commission"
                ).mapped("commission_amount")
            )

    # ------------------------------------------------------------------
    # Affiliate commission lifecycle — mirrors V9 two-step flow
    # ------------------------------------------------------------------
    def write(self, values):
        paid_change = "x_is_paid" in values
        publish_change = "is_published" in values

        old_paid = {j.id: j.x_is_paid for j in self} if paid_change else {}
        old_published = {j.id: j.is_published for j in self} if publish_change else {}

        res = super().write(values)

        for job in self:
            # Step 1 (V9 checkout equivalent): payment confirmed → pending
            if paid_change:
                now_paid = job.x_is_paid
                was_paid = old_paid.get(job.id, False)
                if now_paid and not was_paid:
                    job._kj_create_affiliate_commission(state="pending")

            # Step 2 (V9 publish): publish → complete any pending commissions
            if publish_change:
                now_pub = job.is_published
                was_pub = old_published.get(job.id, False)
                if now_pub and not was_pub:
                    pending = job.partner_commission_ids.filtered(
                        lambda c: c.transaction_type == "commission"
                        and c.state == "pending"
                    )
                    if pending:
                        pending.action_complete()
                    else:
                        # Backward compat: no prior pending commission
                        # (admin-published without payment step) → create
                        # directly as completed.
                        job._kj_create_affiliate_commission(state="completed")
                elif was_pub and not now_pub:
                    # Unpublish: cancel any still-pending commissions.
                    job.partner_commission_ids.filtered(
                        lambda c: c.transaction_type == "commission"
                        and c.state == "pending"
                    ).action_cancel()
        return res

    def _kj_create_affiliate_commission(self, state="pending"):
        """Create an affiliate commission for this job.

        Resolves the affiliate via the job creator's
        ``affiliate_referrer_config_id``. Idempotent: skips if a commission
        already exists for this (widget_config, job) pair.

        ``state`` — pass ``'pending'`` when called from the payment-confirmed
        hook (x_is_paid), ``'completed'`` for backward-compat direct publish.
        """
        self.ensure_one()
        if not self.base_amount:
            return
        recruiter = self.create_uid.partner_id if self.create_uid else False
        if not recruiter:
            return
        config = recruiter.affiliate_referrer_config_id
        if not config or not config.partner_id:
            return
        Commission = self.env["job.partner.commission"].sudo()
        existing = Commission.search([
            ("job_id", "=", self.id),
            ("widget_config_id", "=", config.id),
            ("transaction_type", "=", "commission"),
        ], limit=1)
        if existing:
            return
        affiliate = config.partner_id
        pct = affiliate.affiliate_commission_pct or 100
        svc_type = "job_offer_premium" if getattr(self, "x_type_of_advertisement", "") == "premium" else "job_offer_standard"
        Commission.create({
            "job_id": self.id,
            "partner_id": affiliate.id,
            "widget_config_id": config.id,
            "commission_percentage": float(pct),
            "transaction_type": "commission",
            "state": state,
            "referrer_source": config.widget_mode or "kj",
            "service_type": svc_type,
            "service_price": self.base_amount,
            "service_title": self.name,
        })
