from odoo import _, api, fields, models
from odoo.exceptions import UserError

REJECT_KINDS = [
    ("outside", "Outside Request"),
    ("supervisor_reimb", "Reimbursement (Supervisor)"),
    ("management_reimb", "Reimbursement (Management)"),
]


class XenoOrrRejectWizard(models.TransientModel):
    """One shared "enter a reason and reject" popup for all three reject
    actions in this module (Outside Request, Supervisor Reimburse Reject,
    Management Reject) -- each real action_*_reject() already requires a
    reason, so this only exists to collect it before calling them."""

    _name = "xeno.orr.reject.wizard"
    _description = "Outside Request / Reimbursement Reject Reason"

    kind = fields.Selection(REJECT_KINDS, required=True)
    request_id = fields.Many2one("xeno.orr.request")
    reimbursement_id = fields.Many2one("xeno.orr.reimbursement")
    reason = fields.Text(required=True)

    def action_confirm(self):
        self.ensure_one()
        if self.kind == "outside":
            self.request_id.action_supervisor_reject(self.reason)
        elif self.kind == "supervisor_reimb":
            self.reimbursement_id.action_supervisor_reject(self.reason)
        elif self.kind == "management_reimb":
            self.reimbursement_id.action_management_reject(self.reason)
        return {"type": "ir.actions.act_window_close"}


class XenoOrrReimbursementWizardLine(models.TransientModel):
    _name = "xeno.orr.reimbursement.wizard.line"
    _description = "Outside Request Reimbursement Wizard Line"

    wizard_id = fields.Many2one("xeno.orr.reimbursement.wizard", ondelete="cascade")
    place = fields.Char(required=True)
    description = fields.Char(required=True)
    amount = fields.Float(required=True)
    proof_image = fields.Binary(string="Proof Image")


class XenoOrrReimbursementWizard(models.TransientModel):
    """Ask Reimbursement (Section 6) and Resend (Section 7) share this same
    form -- resend_of_id being set is what tells action_confirm() to call
    action_resend() (a new attempt) instead of action_ask_reimbursement()
    (the first attempt)."""

    _name = "xeno.orr.reimbursement.wizard"
    _description = "Ask / Resend Reimbursement"

    request_id = fields.Many2one("xeno.orr.request", required=True)
    resend_of_id = fields.Many2one("xeno.orr.reimbursement")
    vehicle_type = fields.Selection(related="request_id.vehicle_type")
    distance_km = fields.Float(related="request_id.distance_km")
    fuel_rate = fields.Float(compute="_compute_fuel_rate")
    fuel_amount_preview = fields.Float(compute="_compute_fuel_rate")
    reimbursement_type = fields.Selection(
        [("fuel", "Fuel"), ("other", "Other")], required=True,
        default=lambda self: "other" if self.env.context.get("default_request_id") else False)
    line_ids = fields.One2many("xeno.orr.reimbursement.wizard.line", "wizard_id")

    @api.depends("distance_km")
    def _compute_fuel_rate(self):
        rate = self.env["xeno.orr.config"].sudo().get_rate()
        for rec in self:
            rec.fuel_rate = rate
            rec.fuel_amount_preview = rate * (rec.distance_km or 0.0)

    def action_confirm(self):
        self.ensure_one()
        if self.reimbursement_type == "fuel" and self.vehicle_type == "company_car":
            raise UserError(_("Fuel reimbursement isn't available for a Company Car trip."))
        vals = {
            "reimbursement_type": self.reimbursement_type,
            "line_ids": [(0, 0, {
                "place": line.place,
                "description": line.description,
                "amount": line.amount,
                "proof_image": line.proof_image,
            }) for line in self.line_ids],
        }
        if self.resend_of_id:
            self.resend_of_id.action_resend(vals)
        else:
            self.request_id.action_ask_reimbursement(vals)
        return {"type": "ir.actions.act_window_close"}


class XenoOrrAskBackWizard(models.TransientModel):
    _name = "xeno.orr.ask.back.wizard"
    _description = "Ask Back"

    reimbursement_id = fields.Many2one("xeno.orr.reimbursement", required=True)
    amount = fields.Float(required=True)
    reason = fields.Text(required=True)

    def action_confirm(self):
        self.ensure_one()
        self.reimbursement_id.action_ask_back(self.amount, self.reason)
        return {"type": "ir.actions.act_window_close"}
