# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
from odoo.exceptions import UserError
from odoo.fields import Command
from markupsafe import Markup
import logging

_logger = logging.getLogger(__name__)


class ModPcaReceivedWizard(models.TransientModel):
    _name = 'fusion_claims.mod.pca.received.wizard'
    _description = 'MOD - Record PCA Receipt and Create Invoice(s)'

    sale_order_id = fields.Many2one('sale.order', required=True, readonly=True)
    currency_id = fields.Many2one('res.currency', related='sale_order_id.currency_id')
    order_total = fields.Monetary(
        related='sale_order_id.amount_untaxed', string='Order Subtotal', readonly=True)

    # PCA Document
    pca_document = fields.Binary(string='PCA Document', required=True)
    pca_filename = fields.Char(string='PCA Filename')

    # Case details (pre-filled from order, editable)
    hvmp_reference = fields.Char(string='HVMP Reference #')
    case_worker_id = fields.Many2one(
        'res.partner', string='Case Worker',
        help='March of Dimes case worker assigned to this case',
    )

    # Approval details
    approval_type = fields.Selection([
        ('full', 'Full Approval'),
        ('partial', 'Partial Approval'),
    ], string='Approval Type', required=True, default='full')

    approved_amount = fields.Monetary(
        string='MOD Approved Amount',
        currency_field='currency_id',
        help='Total amount approved by March of Dimes (before taxes)',
    )

    # Preview lines (computed when partial)
    preview_line_ids = fields.One2many(
        'fusion_claims.mod.funding.approved.wizard.line', 'wizard_id',
        string='Line Split Preview',
    )

    @api.model
    def default_get(self, fields_list):
        res = super().default_get(fields_list)
        if self.env.context.get('active_id'):
            order = self.env['sale.order'].browse(self.env.context['active_id'])
            res['sale_order_id'] = order.id
            if order.x_fc_case_reference:
                res['hvmp_reference'] = order.x_fc_case_reference
            if order.x_fc_case_worker:
                res['case_worker_id'] = order.x_fc_case_worker.id
            if order.x_fc_mod_pca_document:
                res['pca_document'] = order.x_fc_mod_pca_document
                res['pca_filename'] = order.x_fc_mod_pca_filename
            if order.x_fc_mod_approved_amount:
                res['approved_amount'] = order.x_fc_mod_approved_amount
                res['approval_type'] = order.x_fc_mod_approval_type or 'full'
            else:
                res['approved_amount'] = order.amount_untaxed
        return res

    @api.onchange('approval_type', 'approved_amount')
    def _onchange_compute_preview(self):
        """Compute the proportional split preview when partial approval."""
        order = self.sale_order_id
        if not order:
            return

        lines = []
        product_lines = order.order_line.filtered(
            lambda l: not l.display_type and l.product_uom_qty > 0 and l.product_id)

        if self.approval_type == 'partial' and self.approved_amount and self.approved_amount > 0:
            subtotal = order.amount_untaxed
            if subtotal <= 0:
                return
            for line in product_lines:
                ratio = line.price_subtotal / subtotal if subtotal else 0
                mod_amount = round(self.approved_amount * ratio, 2)
                client_amount = round(line.price_subtotal - mod_amount, 2)
                lines.append((0, 0, {
                    'product_name': line.product_id.display_name,
                    'quantity': line.product_uom_qty,
                    'line_total': line.price_subtotal,
                    'mod_amount': mod_amount,
                    'client_amount': client_amount,
                }))
        elif self.approval_type == 'full':
            for line in product_lines:
                lines.append((0, 0, {
                    'product_name': line.product_id.display_name,
                    'quantity': line.product_uom_qty,
                    'line_total': line.price_subtotal,
                    'mod_amount': line.price_subtotal,
                    'client_amount': 0,
                }))

        self.preview_line_ids = [(5, 0, 0)] + lines

    def action_confirm(self):
        """Record PCA, set approval amounts, and create invoice(s)."""
        self.ensure_one()
        order = self.sale_order_id

        if not self.pca_document:
            raise UserError(_("Please attach the PCA document."))

        if self.approval_type == 'partial':
            if not self.approved_amount or self.approved_amount <= 0:
                raise UserError(_("Please enter the approved amount for partial approval."))
            if self.approved_amount >= order.amount_untaxed:
                raise UserError(_(
                    "Approved amount is equal to or greater than the order subtotal. "
                    "Use 'Full Approval' instead."))

        client_name = order.partner_id.name or 'Client'

        # Update sale order
        vals = {
            'x_fc_mod_status': 'contract_received',
            'x_fc_mod_pca_received_date': fields.Date.today(),
            'x_fc_mod_pca_document': self.pca_document,
            'x_fc_mod_pca_filename': self.pca_filename or f'PCA - {client_name}.pdf',
            'x_fc_mod_approval_type': self.approval_type,
        }
        if self.approval_type == 'partial':
            vals['x_fc_mod_approved_amount'] = self.approved_amount
            vals['x_fc_mod_payment_commitment'] = self.approved_amount
        else:
            vals['x_fc_mod_approved_amount'] = order.amount_untaxed
            vals['x_fc_mod_payment_commitment'] = order.amount_total
        if self.case_worker_id:
            vals['x_fc_case_worker'] = self.case_worker_id.id
        if self.hvmp_reference:
            vals['x_fc_case_reference'] = self.hvmp_reference
        order.write(vals)

        # Create invoices
        mod_partner = order._get_mod_partner()
        client = order.partner_id

        if self.approval_type == 'full':
            mod_invoice = self._create_full_invoice(order, mod_partner)
            self._log_pca_and_invoices(order, mod_invoice)
            return self._open_invoice(mod_invoice)
        else:
            mod_invoice = self._create_split_mod_invoice(order, mod_partner)
            client_invoice = self._create_split_client_invoice(order, client)
            self._log_pca_and_invoices(order, mod_invoice, client_invoice)
            return self._open_invoice(mod_invoice)

    # ------------------------------------------------------------------
    # Invoice creation helpers
    # ------------------------------------------------------------------

    def _create_full_invoice(self, order, mod_partner):
        """Create a single MOD invoice for the full order amount."""
        line_vals = []
        for line in order.order_line:
            if line.display_type in ('line_section', 'line_note'):
                line_vals.append(Command.create({
                    'display_type': line.display_type,
                    'name': line.name,
                    'sequence': line.sequence,
                }))
            elif not line.display_type and line.product_uom_qty > 0:
                inv_line = line._prepare_invoice_line()
                inv_line['quantity'] = line.product_uom_qty
                inv_line['sequence'] = line.sequence
                line_vals.append(Command.create(inv_line))

        return order._create_mod_invoice(
            partner_id=mod_partner.id,
            invoice_lines=line_vals,
            portion_type='full',
            label=' (March of Dimes - Full)',
        )

    def _create_split_mod_invoice(self, order, mod_partner):
        """Create MOD invoice with proportionally reduced amounts."""
        subtotal = order.amount_untaxed
        approved = self.approved_amount
        line_vals = []

        for line in order.order_line:
            if line.display_type in ('line_section', 'line_note'):
                line_vals.append(Command.create({
                    'display_type': line.display_type,
                    'name': line.name,
                    'sequence': line.sequence,
                }))
            elif not line.display_type and line.product_uom_qty > 0:
                ratio = line.price_subtotal / subtotal if subtotal else 0
                mod_line_amount = round(approved * ratio, 2)
                mod_price_unit = round(
                    mod_line_amount / line.product_uom_qty, 2
                ) if line.product_uom_qty else 0

                inv_line = line._prepare_invoice_line()
                inv_line['quantity'] = line.product_uom_qty
                inv_line['price_unit'] = mod_price_unit
                inv_line['sequence'] = line.sequence
                line_vals.append(Command.create(inv_line))

        return order._create_mod_invoice(
            partner_id=mod_partner.id,
            invoice_lines=line_vals,
            portion_type='adp',
            label=' (March of Dimes Portion)',
        )

    def _create_split_client_invoice(self, order, client):
        """Create Client invoice with the difference amounts."""
        subtotal = order.amount_untaxed
        approved = self.approved_amount
        line_vals = []

        for line in order.order_line:
            if line.display_type in ('line_section', 'line_note'):
                line_vals.append(Command.create({
                    'display_type': line.display_type,
                    'name': line.name,
                    'sequence': line.sequence,
                }))
            elif not line.display_type and line.product_uom_qty > 0:
                ratio = line.price_subtotal / subtotal if subtotal else 0
                mod_line_amount = round(approved * ratio, 2)
                client_line_amount = round(line.price_subtotal - mod_line_amount, 2)
                client_price_unit = round(
                    client_line_amount / line.product_uom_qty, 2
                ) if line.product_uom_qty else 0

                inv_line = line._prepare_invoice_line()
                inv_line['quantity'] = line.product_uom_qty
                inv_line['price_unit'] = client_price_unit
                inv_line['sequence'] = line.sequence

                if client_line_amount <= 0:
                    inv_line['price_unit'] = 0
                    inv_line['name'] = f'{line.name}\n[Covered by March of Dimes]'

                line_vals.append(Command.create(inv_line))

        return order._create_mod_invoice(
            partner_id=client.id,
            invoice_lines=line_vals,
            portion_type='client',
            label=' (Client Portion)',
        )

    # ------------------------------------------------------------------
    # Logging and navigation
    # ------------------------------------------------------------------

    def _log_pca_and_invoices(self, order, mod_invoice, client_invoice=None):
        """Log PCA receipt and invoice creation to chatter."""
        parts = [f'<strong>PCA Received and Invoice(s) Created</strong>']
        parts.append(f'Date: {fields.Date.today().strftime("%B %d, %Y")}')
        if self.hvmp_reference:
            parts.append(f'HVMP Reference: {self.hvmp_reference}')
        if self.case_worker_id:
            parts.append(f'Case Worker: {self.case_worker_id.name}')

        type_label = 'Full Approval' if self.approval_type == 'full' else 'Partial Approval'
        parts.append(f'Approval Type: {type_label}')

        if self.approval_type == 'partial':
            parts.append(f'MOD Approved: ${self.approved_amount:,.2f}')
            parts.append(
                f'Client Portion: ${order.amount_untaxed - self.approved_amount:,.2f}')

        inv_links = [
            f'MOD Invoice: <a href="/web#id={mod_invoice.id}'
            f'&amp;model=account.move&amp;view_type=form">'
            f'{mod_invoice.name or "Draft"}</a>'
        ]
        if client_invoice:
            inv_links.append(
                f'Client Invoice: <a href="/web#id={client_invoice.id}'
                f'&amp;model=account.move&amp;view_type=form">'
                f'{client_invoice.name or "Draft"}</a>'
            )
        parts.extend(inv_links)

        order.message_post(
            body=Markup('<div class="alert alert-success">' + '<br/>'.join(parts) + '</div>'),
            message_type='notification', subtype_xmlid='mail.mt_note',
        )

    def _open_invoice(self, invoice):
        return {
            'type': 'ir.actions.act_window',
            'name': 'Invoice',
            'res_model': 'account.move',
            'view_mode': 'form',
            'res_id': invoice.id,
        }
