from odoo import models, fields, api


class LaundryDashboard(models.TransientModel):
    """Live KPI dashboard — queries sale.order with is_laundry_order = True."""
    _name = 'laundry.dashboard'
    _description = 'Laundry Dashboard'

    today_orders      = fields.Integer(string="Today's Orders")
    today_revenue     = fields.Monetary(string="Today's Revenue",   currency_field='currency_id')
    today_collected   = fields.Monetary(string='Collected Today',   currency_field='currency_id')
    today_outstanding = fields.Monetary(string='Outstanding Today', currency_field='currency_id')

    pending_count     = fields.Integer(string='Pending Orders')
    ready_count       = fields.Integer(string='Ready for Pickup')
    in_progress_count = fields.Integer(string='In Processing')
    draft_count       = fields.Integer(string='Quotes / Draft')

    session_is_open      = fields.Boolean(string='Session Open')
    session_name         = fields.Char(string='Session')
    session_opening_cash = fields.Monetary(string='Opening Float', currency_field='currency_id')
    session_sales        = fields.Monetary(string='Session Sales', currency_field='currency_id')
    session_cash         = fields.Monetary(string='Session Cash',  currency_field='currency_id')
    session_bank         = fields.Monetary(string='Session Bank',  currency_field='currency_id')
    session_id           = fields.Many2one('laundry.session', string='Session Link')

    month_orders  = fields.Integer(string='Orders This Month')
    month_revenue = fields.Monetary(string='Revenue This Month',   currency_field='currency_id')
    month_paid    = fields.Monetary(string='Collected This Month', currency_field='currency_id')

    currency_id = fields.Many2one(
        'res.currency',
        default=lambda self: self.env.company.currency_id,
    )

    @api.model
    def _build(self):
        today       = fields.Date.today()
        month_start = today.replace(day=1)
        company     = self.env.company
        Order       = self.env['sale.order']
        Payment     = self.env['account.payment']

        _base_domain = [
            ('is_laundry_order', '=', True),
            ('company_id',       '=', company.id),
        ]

        # ── Today ──────────────────────────────────────────────────────
        today_orders = Order.search(_base_domain + [
            ('date_order', '>=', fields.Datetime.to_datetime(today)),
            ('state',      'not in', ['cancel', 'draft']),
        ])
        today_invoices = today_orders.mapped('invoice_ids').filtered(
            lambda i: i.state == 'posted' and i.move_type == 'out_invoice'
        )
        today_revenue     = sum(today_orders.mapped('amount_total'))
        today_outstanding = sum(
            max(i.amount_residual, 0.0) for i in today_invoices
        )
        today_collected   = today_revenue - today_outstanding

        # ── Pipeline (all active laundry orders) ──────────────────────
        pipeline = Order.search(_base_domain + [
            ('state', '=', 'sale'),
        ])
        pending_count     = len(pipeline)
        ready_count       = len(pipeline.filtered(lambda o: o.laundry_state == 'ready'))
        in_progress_count = len(pipeline.filtered(lambda o: o.laundry_state == 'processing'))
        draft_count       = len(Order.search(_base_domain + [('state', '=', 'draft')]))

        # ── Session ────────────────────────────────────────────────────
        session = self.env['laundry.session'].search([
            ('state',      '=', 'opened'),
            ('company_id', '=', company.id),
        ], limit=1)

        # ── Month ──────────────────────────────────────────────────────
        month_orders = Order.search(_base_domain + [
            ('date_order', '>=', fields.Datetime.to_datetime(month_start)),
            ('state',      'not in', ['cancel', 'draft']),
        ])
        month_invoices = month_orders.mapped('invoice_ids').filtered(
            lambda i: i.state == 'posted' and i.move_type == 'out_invoice'
        )
        month_revenue = sum(month_orders.mapped('amount_total'))
        month_outstanding = sum(max(i.amount_residual, 0.0) for i in month_invoices)
        month_paid = month_revenue - month_outstanding

        return self.create({
            'today_orders'      : len(today_orders),
            'today_revenue'     : today_revenue,
            'today_collected'   : max(today_collected, 0.0),
            'today_outstanding' : today_outstanding,
            'pending_count'     : pending_count,
            'ready_count'       : ready_count,
            'in_progress_count' : in_progress_count,
            'draft_count'       : draft_count,
            'session_is_open'      : bool(session),
            'session_name'         : session.name if session else '',
            'session_opening_cash' : session.opening_cash if session else 0.0,
            'session_sales'        : session.total_sales if session else 0.0,
            'session_cash'         : session.total_cash if session else 0.0,
            'session_bank'         : session.total_bank if session else 0.0,
            'session_id'           : session.id if session else False,
            'month_orders'  : len(month_orders),
            'month_revenue' : month_revenue,
            'month_paid'    : max(month_paid, 0.0),
        })

    @api.model
    def action_open_dashboard(self):
        rec = self._build()
        return {
            'type':      'ir.actions.act_window',
            'name':      'Dashboard',
            'res_model': 'laundry.dashboard',
            'res_id':    rec.id,
            'view_mode': 'form',
            'target':    'main',
            'flags':     {'mode': 'readonly'},
        }

    def action_refresh(self):
        return self.action_open_dashboard()

    def action_new_order(self):
        return {
            'type':      'ir.actions.act_window',
            'name':      'New Laundry Order',
            'res_model': 'sale.order',
            'view_mode': 'form',
            'target':    'current',
            'context': {
                'default_is_laundry_order': True,
            },
        }

    def action_open_session(self):
        if self.session_id:
            return {
                'type':      'ir.actions.act_window',
                'name':      'Session',
                'res_model': 'laundry.session',
                'res_id':    self.session_id.id,
                'view_mode': 'form',
            }
        return {
            'type':      'ir.actions.act_window',
            'name':      'Sessions',
            'res_model': 'laundry.session',
            'view_mode': 'list,form',
        }

    def action_new_session(self):
        return {
            'type':      'ir.actions.act_window',
            'name':      'New Session',
            'res_model': 'laundry.session',
            'view_mode': 'form',
        }

    def action_view_ready_orders(self):
        return {
            'type':      'ir.actions.act_window',
            'name':      'Ready for Pickup',
            'res_model': 'sale.order',
            'view_mode': 'list,form',
            'domain':    [('is_laundry_order', '=', True), ('laundry_state', '=', 'ready')],
        }

    def action_view_pending_orders(self):
        return {
            'type':      'ir.actions.act_window',
            'name':      'Pending Orders',
            'res_model': 'sale.order',
            'view_mode': 'list,form',
            'domain':    [('is_laundry_order', '=', True), ('state', '=', 'sale'),
                          ('laundry_state', 'not in', ['delivered'])],
        }
