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


class LaundryPaymentMethod(models.Model):
    """Configurable payment method linked to an accounting journal.

    One record per payment option (e.g. Cash, Visa, Bank Transfer, Credit).
    Each method is typed as cash / bank / credit so that session cash-control
    and accounting routing work exactly like Odoo POS payment methods.

    cash   → counted in the session cash drawer
    bank   → posted to a bank/card journal, not counted in cash
    credit → deferred / no-posting (customer owes)
    """
    _name = 'laundry.payment.method'
    _description = 'Laundry Payment Method'
    _order = 'sequence, id'

    # ── Identity ──────────────────────────────────────────────────────
    name = fields.Char(
        string='Method Name',
        required=True,
        translate=True,
    )
    sequence = fields.Integer(default=10)
    active = fields.Boolean(default=True)
    company_id = fields.Many2one(
        'res.company',
        default=lambda self: self.env.company,
    )

    # ── Type ──────────────────────────────────────────────────────────
    payment_type = fields.Selection([
        ('cash',   'Cash / نقد'),
        ('bank',   'Bank / Card / بنك'),
        ('credit', 'Credit / Deferred / آجل'),
    ], string='Type', required=True, default='cash',
       help=(
           'cash   → counts in session cash drawer\n'
           'bank   → posted to bank/card journal\n'
           'credit → deferred, no immediate accounting entry'
       ),
    )

    # ── Journal ───────────────────────────────────────────────────────
    journal_id = fields.Many2one(
        'account.journal', string='Accounting Journal',
        domain="[('type', 'in', ['cash', 'bank']), ('company_id', '=', company_id)]",
        help='Leave blank only for Credit/Deferred methods.',
    )

    # ── UI ────────────────────────────────────────────────────────────
    is_default = fields.Boolean(
        string='Default',
        help='Pre-selected when staff opens the Register Payment wizard.',
    )

    # ── Constraints ───────────────────────────────────────────────────
    @api.constrains('is_default', 'company_id')
    def _check_single_default(self):
        for rec in self.filtered('is_default'):
            duplicate = self.search([
                ('is_default',   '=', True),
                ('company_id',   '=', rec.company_id.id),
                ('id',           '!=', rec.id),
            ], limit=1)
            if duplicate:
                raise UserError(
                    f'Only one default payment method is allowed per company.\n'
                    f'"{duplicate.name}" is already the default.\n'
                    'Unset it first before marking this one as default.'
                )

    @api.constrains('payment_type', 'journal_id')
    def _check_journal_required(self):
        for rec in self:
            if rec.payment_type in ('cash', 'bank') and not rec.journal_id:
                raise UserError(
                    f'Payment method "{rec.name}" is of type "{rec.payment_type}" '
                    'and requires an accounting journal. '
                    'Please select a journal or change the type to Credit/Deferred.'
                )

    # ── Helpers ───────────────────────────────────────────────────────
    @api.model
    def get_default_method(self):
        """Return the default payment method for the current company."""
        company = self.env.company
        return (
            self.search([
                ('is_default', '=', True),
                ('company_id', '=', company.id),
                ('active',     '=', True),
            ], limit=1)
            or self.search([
                ('payment_type', '=', 'cash'),
                ('company_id',   '=', company.id),
                ('active',       '=', True),
            ], limit=1)
        )
