from odoo import models, fields, api, _
from odoo.exceptions import UserError
import base64
from types import SimpleNamespace
from odoo.tools import formatLang


class PosOrder(models.Model):
    _inherit = "pos.order"

    def action_print_backend_ticket(self):
        self.ensure_one()
        if self.state not in ("paid", "done", "invoiced"):
            raise UserError(
                _(
                    "You can only print the receipt when the order is paid, closed, or invoiced."
                )
            )
        return self.env.ref(
            "pos_order_backend_receipt.action_report_pos_order_ticket"
        ).report_action(self)

    # ----------------- Helpers Backend Ticket -----------------
    def _get_backend_tax_breakdown(self):
        """Return list of dicts with tax_rate, base, amount for legal breakdown.

        Group by tax (percentage). Only sales taxes (positive or negative based on sign).
        """
        self.ensure_one()
        breakdown = []
        Tax = self.env["account.tax"]
        currency = self.pricelist_id.currency_id or self.company_id.currency_id
        # aggregate via line taxes after fiscal position
        tax_map = {}
        for line in self.lines:
            # price_subtotal (sin impuestos), price_subtotal_incl (con impuestos)
            base = line.price_subtotal
            tax_amount_line = line.price_subtotal_incl - line.price_subtotal
            # Derivar tipo (promedio) desde los impuestos aplicados
            for tax in line.tax_ids_after_fiscal_position:
                key = tax.id
                entry = tax_map.setdefault(
                    key,
                    {
                        "tax": tax,
                        "base": 0.0,
                        "amount": 0.0,
                    },
                )
                # prorratear base / importe cuando múltiples impuestos
                # simplificación: si hay varios impuestos no compuestos, se reparte proporcional a sus montos teóricos
                if line.tax_ids_after_fiscal_position:
                    # compute_all para repartir preciso
                    taxes_res = tax.compute_all(
                        line.price_unit * (1 - (line.discount or 0.0) / 100.0),
                        currency,
                        line.qty,
                        product=line.product_id,
                        partner=self.partner_id,
                    )
                    # encontrar este tax
                    for tline in taxes_res["taxes"]:
                        if tline["id"] == tax.id:
                            entry["amount"] += tline["amount"]
                            # base para ese impuesto específico
                            entry["base"] += tline["base"]
                else:
                    entry["base"] += base
                    entry["amount"] += tax_amount_line
        # formatear
        for v in tax_map.values():
            tax = v["tax"]
            rate = tax.amount if tax.amount_type == "percent" else 0.0
            breakdown.append(
                {
                    "rate": rate,
                    "base": currency.round(v["base"]),
                    "amount": currency.round(v["amount"]),
                }
            )
        # ordenar por tasa
        breakdown.sort(key=lambda x: x["rate"])
        return breakdown
