from odoo import api, fields, models
import logging
_logger = logging.getLogger(__name__)

class DirectivePolicy(models.Model):
    _name = "directive.policy"
    _description = "Directive Policy"
    _order = "sequence, id"

    name = fields.Char(required=True)
    active = fields.Boolean(default=True)
    sequence = fields.Integer(default=10)

    origin_model = fields.Char(
        string="Origin model",
        required=True,
        index=True,
        help="Техническое имя модели источника, например 'project.task'",
    )

    event = fields.Selection(
        [
            ("manual", "Manual"),
            ("on_create", "On Create"),
            ("on_write", "On Write"),
            ("on_stage", "On Stage Change"),
            ("on_cron", "On Cron"),
            ("on_callback", "При вызове метода (on_callback)"),
        ],
        required=True,
        index=True,
        default="manual",
    )

    mode = fields.Selection(
        [
            ("create_once", "Create once"),
            ("create_each_time", "Create each time"),
        ],
        required=True,
        default="create_once",
    )

    use_record_template_group = fields.Boolean(
        default=True,
        help="Если включено, группа берётся из поля записи-источника directive_template_group_id.",
    )

    template_group_id = fields.Many2one(
        "directive.template.group",
        string="Fixed template group",
        help="Если указано и use_record_template_group=False — будет использоваться эта группа.",
    )

    trigger_field = fields.Char(
        help="Имя поля источника, например 'stage_id'."
    )
    trigger_value_int = fields.Integer(
        help="Для Many2one/Integer: ожидаемое значение (например ID стадии)."
    )

    def _policy_should_fire(self, record, payload: dict | None = None) -> bool:
        self.ensure_one()

        # Для on_callback факт вызова метода - это уже триггер.
        if self.event == 'on_callback':
            return True

        if not self.trigger_field:
            return True

        value = getattr(record, self.trigger_field, False)

        if hasattr(value, "id"):
            match = bool(value and value.id == self.trigger_value_int)
            if not match:
                _logger.debug("[directive.policy] ID mismatch: expected %s, got %s", self.trigger_value_int, value.id)
            return match

        try:
            match = (value == self.trigger_value_int)
            if not match:
                _logger.debug("[directive.policy] Value mismatch: expected %s, got %s", self.trigger_value_int, value)
            return match
        except Exception as e:
            _logger.error("[directive.policy] Error comparing values: %s", e)
            return False

    def _resolve_template_group(self, record):
        self.ensure_one()
        if self.use_record_template_group:
            return record.directive_template_group_id
        return self.template_group_id

    def apply_to_records(self, records, payload: dict | None = None):
        self.ensure_one()
        if not records:
            return 0

        created_total = 0
        for rec in records:
            if rec._name != self.origin_model:
                continue

            if not self._policy_should_fire(rec, payload=payload):
                continue

            group = self._resolve_template_group(rec)
            if not group:
                continue

            if self.mode == "create_once":
                existing = rec.env["directive.directive"].search_count([
                    ("origin_id", "=", rec.directive_origin_id.id),
                    ("policy_id", "=", self.id),
                ])
                if existing:
                    continue

            rec._directive_create_from_group(group, policy=self)
            created_total += 1

        return created_total
