"""Approval workflow models.

Powers the admin "Approval Config" page (`/admin/approval-config`) and the
per-record approval requests exposed by `ApprovalWorkflowController`.

Prior to this module the controller hand-rolled raw SQL against tables that
were never created.  These ORM models now own the schema so Odoo can create
the tables on install/update and the controller can use a standard API.
"""
from odoo import api, fields, models


STATUS_SELECTION = [
    ('draft', 'Draft'),
    ('active', 'Active'),
    ('archived', 'Archived'),
]

REQUEST_STATE = [
    ('draft', 'Draft'),
    ('in_progress', 'In Progress'),
    ('approved', 'Approved'),
    ('rejected', 'Rejected'),
    ('bypassed', 'Bypassed'),
]

STAGE_STATUS = [
    ('pending', 'Pending'),
    ('approved', 'Approved'),
    ('rejected', 'Rejected'),
    ('skipped', 'Skipped'),
]


class EncoachApprovalWorkflow(models.Model):
    _name = 'encoach.approval.workflow'
    _description = 'Approval Workflow'
    _order = 'create_date desc'

    name = fields.Char(required=True)
    type = fields.Char(default='custom',
                       help='Categorical tag e.g. leave, purchase, content, custom.')
    status = fields.Selection(STATUS_SELECTION, default='draft', required=True,
                              help='Draft = not yet routable. Active = available to new requests.')
    allow_bypass = fields.Boolean(
        default=False,
        help='If true, a bypass reason allows the workflow to be skipped.')
    entity_id = fields.Many2one('encoach.entity', ondelete='set null')
    stage_ids = fields.One2many('encoach.approval.stage', 'workflow_id',
                                copy=True)
    request_ids = fields.One2many('encoach.approval.request', 'workflow_id')
    stage_count = fields.Integer(compute='_compute_counts')
    request_count = fields.Integer(compute='_compute_counts')

    @api.depends('stage_ids', 'request_ids')
    def _compute_counts(self):
        for rec in self:
            rec.stage_count = len(rec.stage_ids)
            rec.request_count = len(rec.request_ids)


class EncoachApprovalStage(models.Model):
    _name = 'encoach.approval.stage'
    _description = 'Approval Workflow Stage'
    _order = 'sequence, id'

    workflow_id = fields.Many2one('encoach.approval.workflow',
                                  required=True, ondelete='cascade', index=True)
    sequence = fields.Integer(default=10, required=True,
                              help='Stored order; the admin UI speaks `order`.')
    approver_id = fields.Many2one('res.users', required=True, ondelete='restrict')
    max_days = fields.Integer(default=3,
                              help='SLA before auto-escalation can fire.')
    auto_escalate = fields.Boolean(default=False)
    notification_email = fields.Char(
        help='Optional CC address; falls back to approver_id.email otherwise.')
    status = fields.Selection(STAGE_STATUS, default='pending')
    comment = fields.Text()
    acted_at = fields.Datetime()


class EncoachApprovalRequest(models.Model):
    _name = 'encoach.approval.request'
    _description = 'Approval Request'
    _order = 'create_date desc'

    workflow_id = fields.Many2one('encoach.approval.workflow',
                                  required=True, ondelete='cascade', index=True)
    res_model = fields.Char(help='Optional target model (e.g. op.student.leave).')
    res_id = fields.Integer(help='Optional target record id inside res_model.')
    state = fields.Selection(REQUEST_STATE, default='draft', required=True)
    requester_id = fields.Many2one('res.users', ondelete='set null')
    current_stage_id = fields.Many2one('encoach.approval.stage', ondelete='set null')
    bypass_reason = fields.Text()
    created_at = fields.Datetime(default=fields.Datetime.now)
