# -*- coding: utf-8 -*-
# Copyright 2024-2026 Nexa Systems Inc.
# License OPL-1 (Odoo Proprietary License v1.0)

from odoo import models, fields, api, _
from odoo.exceptions import UserError, ValidationError
from markupsafe import Markup
from datetime import timedelta
import logging

_logger = logging.getLogger(__name__)


class FusionLoanerCheckout(models.Model):
    """Track loaner equipment checkouts and returns."""
    _name = 'fusion.loaner.checkout'
    _description = 'Loaner Equipment Checkout'
    _order = 'checkout_date desc, id desc'
    _inherit = ['mail.thread', 'mail.activity.mixin', 'fusion.email.builder.mixin']

    # =========================================================================
    # REFERENCE FIELDS
    # =========================================================================
    
    name = fields.Char(
        string='Reference',
        required=True,
        copy=False,
        readonly=True,
        default=lambda self: _('New'),
    )
    sale_order_id = fields.Many2one(
        'sale.order',
        string='Sale Order',
        ondelete='set null',
        tracking=True,
    )
    partner_id = fields.Many2one(
        'res.partner',
        string='Client',
        required=True,
        tracking=True,
    )
    authorizer_id = fields.Many2one(
        'res.partner',
        string='Authorizer',
        help='Therapist/Authorizer associated with this loaner',
    )
    sales_rep_id = fields.Many2one(
        'res.users',
        string='Sales Rep',
        default=lambda self: self.env.user,
        tracking=True,
    )
    company_id = fields.Many2one(
        'res.company',
        string='Company',
        default=lambda self: self.env.company,
    )

    # =========================================================================
    # PRODUCT & SERIAL
    # =========================================================================
    
    product_id = fields.Many2one(
        'product.product',
        string='Product',
        required=True,
        domain="[('x_fc_can_be_loaned', '=', True)]",
        tracking=True,
    )
    lot_id = fields.Many2one(
        'stock.lot',
        string='Serial Number',
        domain="[('product_id', '=', product_id)]",
        tracking=True,
    )
    product_description = fields.Text(
        string='Product Description',
        related='product_id.description_sale',
    )

    # =========================================================================
    # DATES
    # =========================================================================
    
    checkout_date = fields.Date(
        string='Checkout Date',
        required=True,
        default=fields.Date.context_today,
        tracking=True,
    )
    loaner_period_days = fields.Integer(
        string='Loaner Period (Days)',
        default=7,
        help='Number of free loaner days before rental conversion',
    )
    expected_return_date = fields.Date(
        string='Expected Return Date',
        compute='_compute_expected_return_date',
        store=True,
    )
    actual_return_date = fields.Date(
        string='Actual Return Date',
        tracking=True,
    )
    days_out = fields.Integer(
        string='Days Out',
        compute='_compute_days_out',
    )
    days_overdue = fields.Integer(
        string='Days Overdue',
        compute='_compute_days_overdue',
    )

    # =========================================================================
    # STATUS
    # =========================================================================
    
    state = fields.Selection([
        ('draft', 'Draft'),
        ('checked_out', 'Checked Out'),
        ('overdue', 'Overdue'),
        ('rental_pending', 'Rental Conversion Pending'),
        ('returned', 'Returned'),
        ('converted_rental', 'Converted to Rental'),
        ('lost', 'Lost/Write-off'),
    ], string='Status', default='draft', tracking=True, required=True)

    # =========================================================================
    # LOCATION
    # =========================================================================
    
    delivery_address = fields.Text(
        string='Delivery Address',
        help='Where the loaner was delivered',
    )
    return_location_id = fields.Many2one(
        'stock.location',
        string='Return Location',
        domain="[('usage', '=', 'internal')]",
        help='Where the loaner was returned to (store, warehouse, etc.)',
        tracking=True,
    )
    checked_out_by_id = fields.Many2one(
        'res.users',
        string='Checked Out By',
        default=lambda self: self.env.user,
    )
    returned_to_id = fields.Many2one(
        'res.users',
        string='Returned To',
    )

    # =========================================================================
    # CHECKOUT CONDITION
    # =========================================================================
    
    checkout_condition = fields.Selection([
        ('excellent', 'Excellent'),
        ('good', 'Good'),
        ('fair', 'Fair'),
        ('needs_repair', 'Needs Repair'),
    ], string='Checkout Condition', default='excellent')
    checkout_notes = fields.Text(
        string='Checkout Notes',
    )
    checkout_photo_ids = fields.Many2many(
        'ir.attachment',
        'fusion_loaner_checkout_photo_rel',
        'checkout_id',
        'attachment_id',
        string='Checkout Photos',
    )

    # =========================================================================
    # RETURN CONDITION
    # =========================================================================
    
    return_condition = fields.Selection([
        ('excellent', 'Excellent'),
        ('good', 'Good'),
        ('fair', 'Fair'),
        ('needs_repair', 'Needs Repair'),
        ('damaged', 'Damaged'),
    ], string='Return Condition')
    return_notes = fields.Text(
        string='Return Notes',
    )
    return_photo_ids = fields.Many2many(
        'ir.attachment',
        'fusion_loaner_return_photo_rel',
        'checkout_id',
        'attachment_id',
        string='Return Photos',
    )

    # =========================================================================
    # REMINDER TRACKING
    # =========================================================================
    
    reminder_day5_sent = fields.Boolean(
        string='Day 5 Reminder Sent',
        default=False,
    )
    reminder_day8_sent = fields.Boolean(
        string='Day 8 Warning Sent',
        default=False,
    )
    reminder_day10_sent = fields.Boolean(
        string='Day 10 Final Notice Sent',
        default=False,
    )

    # =========================================================================
    # RENTAL CONVERSION
    # =========================================================================
    
    rental_order_id = fields.Many2one(
        'sale.order',
        string='Rental Order',
        help='Sale order created when loaner converted to rental',
    )
    rental_conversion_date = fields.Date(
        string='Rental Conversion Date',
    )

    # =========================================================================
    # STOCK MOVES
    # =========================================================================
    
    checkout_move_id = fields.Many2one(
        'stock.move',
        string='Checkout Stock Move',
    )
    return_move_id = fields.Many2one(
        'stock.move',
        string='Return Stock Move',
    )

    # =========================================================================
    # HISTORY
    # =========================================================================
    
    history_ids = fields.One2many(
        'fusion.loaner.history',
        'checkout_id',
        string='History',
    )
    history_count = fields.Integer(
        compute='_compute_history_count',
        string='History Count',
    )

    # =========================================================================
    # COMPUTED FIELDS
    # =========================================================================
    
    @api.depends('checkout_date', 'loaner_period_days')
    def _compute_expected_return_date(self):
        for record in self:
            if record.checkout_date and record.loaner_period_days:
                record.expected_return_date = record.checkout_date + timedelta(days=record.loaner_period_days)
            else:
                record.expected_return_date = False

    @api.depends('checkout_date', 'actual_return_date')
    def _compute_days_out(self):
        today = fields.Date.today()
        for record in self:
            if record.checkout_date:
                end_date = record.actual_return_date or today
                record.days_out = (end_date - record.checkout_date).days
            else:
                record.days_out = 0

    @api.depends('expected_return_date', 'actual_return_date', 'state')
    def _compute_days_overdue(self):
        today = fields.Date.today()
        for record in self:
            if record.state in ('returned', 'converted_rental', 'lost'):
                record.days_overdue = 0
            elif record.expected_return_date:
                end_date = record.actual_return_date or today
                overdue = (end_date - record.expected_return_date).days
                record.days_overdue = max(0, overdue)
            else:
                record.days_overdue = 0

    def _compute_history_count(self):
        for record in self:
            record.history_count = len(record.history_ids)

    # =========================================================================
    # ONCHANGE
    # =========================================================================
    
    @api.onchange('product_id')
    def _onchange_product_id(self):
        if self.product_id:
            self.loaner_period_days = self.product_id.x_fc_loaner_period_days or 7
            self.lot_id = False

    @api.onchange('sale_order_id')
    def _onchange_sale_order_id(self):
        if self.sale_order_id:
            self.partner_id = self.sale_order_id.partner_id
            self.authorizer_id = self.sale_order_id.x_fc_authorizer_id
            self.sales_rep_id = self.sale_order_id.user_id
            self.delivery_address = self.sale_order_id.partner_shipping_id.contact_address if self.sale_order_id.partner_shipping_id else ''

    # =========================================================================
    # CRUD
    # =========================================================================
    
    @api.model_create_multi
    def create(self, vals_list):
        for vals in vals_list:
            if vals.get('name', _('New')) == _('New'):
                vals['name'] = self.env['ir.sequence'].next_by_code('fusion.loaner.checkout') or _('New')
        records = super().create(vals_list)
        for record in records:
            record._log_history('create', 'Loaner checkout created')
        return records

    # =========================================================================
    # ACTIONS
    # =========================================================================
    
    def action_checkout(self):
        """Confirm the loaner checkout."""
        self.ensure_one()
        if self.state != 'draft':
            raise UserError(_("Can only checkout from draft state."))
        
        if not self.product_id:
            raise UserError(_("Please select a product."))
        
        self.write({'state': 'checked_out'})
        self._log_history('checkout', f'Loaner checked out to {self.partner_id.name}')
        # Stock move is non-blocking -- use savepoint so failure doesn't roll back checkout
        try:
            with self.env.cr.savepoint():
                self._create_checkout_stock_move()
        except Exception as e:
            _logger.warning(f"Stock move failed for checkout {self.name} (non-blocking): {e}")
        self._send_checkout_email()
        
        # Post to chatter
        self.message_post(
            body=Markup(
                '<div class="alert alert-success">'
                f'<strong>Loaner Checked Out</strong><br/>'
                f'Product: {self.product_id.name}<br/>'
                f'Serial: {self.lot_id.name if self.lot_id else "N/A"}<br/>'
                f'Expected Return: {self.expected_return_date}'
                '</div>'
            ),
            message_type='notification',
            subtype_xmlid='mail.mt_note',
        )
        
        return True

    def action_return(self):
        """Open return wizard."""
        self.ensure_one()
        return {
            'name': _('Return Loaner'),
            'type': 'ir.actions.act_window',
            'res_model': 'fusion.loaner.return.wizard',
            'view_mode': 'form',
            'target': 'new',
            'context': {
                'default_checkout_id': self.id,
            },
        }

    def action_process_return(self, return_condition, return_notes=None, return_photos=None, return_location_id=None):
        """Process the loaner return."""
        self.ensure_one()
        if self.state not in ('checked_out', 'overdue', 'rental_pending'):
            raise UserError(_("Cannot return a loaner that is not checked out."))
        
        vals = {
            'state': 'returned',
            'actual_return_date': fields.Date.today(),
            'return_condition': return_condition,
            'return_notes': return_notes,
            'returned_to_id': self.env.user.id,
        }
        if return_location_id:
            vals['return_location_id'] = return_location_id
        if return_photos:
            vals['return_photo_ids'] = [(6, 0, return_photos)]
        
        self.write(vals)
        self._log_history('return', f'Loaner returned in {return_condition} condition')
        try:
            with self.env.cr.savepoint():
                self._create_return_stock_move()
        except Exception as e:
            _logger.warning(f"Stock move failed for return {self.name} (non-blocking): {e}")
        self._send_return_email()
        
        # Post to chatter
        self.message_post(
            body=Markup(
                '<div class="alert alert-info">'
                f'<strong>Loaner Returned</strong><br/>'
                f'Condition: {return_condition}<br/>'
                f'Days Out: {self.days_out}'
                '</div>'
            ),
            message_type='notification',
            subtype_xmlid='mail.mt_note',
        )
        
        return True

    def action_mark_lost(self):
        """Mark loaner as lost."""
        self.ensure_one()
        self.write({'state': 'lost'})
        self._log_history('lost', 'Loaner marked as lost/write-off')
        
        self.message_post(
            body=Markup(
                '<div class="alert alert-danger">'
                '<strong>Loaner Marked as Lost</strong><br/>'
                f'Product: {self.product_id.name}<br/>'
                f'Serial: {self.lot_id.name if self.lot_id else "N/A"}'
                '</div>'
            ),
            message_type='notification',
            subtype_xmlid='mail.mt_note',
        )

    def action_convert_to_rental(self):
        """Flag for rental conversion."""
        self.ensure_one()
        self.write({
            'state': 'rental_pending',
            'rental_conversion_date': fields.Date.today(),
        })
        self._log_history('rental_pending', 'Loaner flagged for rental conversion')
        self._send_rental_conversion_email()

    def action_view_history(self):
        """View loaner history."""
        self.ensure_one()
        return {
            'name': _('Loaner History'),
            'type': 'ir.actions.act_window',
            'res_model': 'fusion.loaner.history',
            'view_mode': 'tree,form',
            'domain': [('checkout_id', '=', self.id)],
            'context': {'default_checkout_id': self.id},
        }

    def action_view_sale_order(self):
        self.ensure_one()
        if not self.sale_order_id:
            return
        return {
            'name': self.sale_order_id.name,
            'type': 'ir.actions.act_window',
            'res_model': 'sale.order',
            'view_mode': 'form',
            'res_id': self.sale_order_id.id,
        }

    def action_view_partner(self):
        self.ensure_one()
        if not self.partner_id:
            return
        return {
            'name': self.partner_id.name,
            'type': 'ir.actions.act_window',
            'res_model': 'res.partner',
            'view_mode': 'form',
            'res_id': self.partner_id.id,
        }

    # =========================================================================
    # STOCK MOVES
    # =========================================================================
    
    def _get_loaner_location(self):
        """Get the loaner stock location."""
        location = self.env.ref('fusion_claims.stock_location_loaner', raise_if_not_found=False)
        if not location:
            # Fallback to main stock
            location = self.env.ref('stock.stock_location_stock')
        return location

    def _get_customer_location(self):
        """Get customer location for stock moves."""
        return self.env.ref('stock.stock_location_customers')

    def _create_checkout_stock_move(self):
        """Create stock move for checkout. Non-blocking -- checkout proceeds even if move fails."""
        if not self.lot_id:
            return  # No serial tracking
        
        try:
            source_location = self._get_loaner_location()
            dest_location = self._get_customer_location()
            
            move_vals = {
                'name': f'Loaner Checkout: {self.name}',
                'product_id': self.product_id.id,
                'product_uom_qty': 1,
                'product_uom': self.product_id.uom_id.id,
                'location_id': source_location.id,
                'location_dest_id': dest_location.id,
                'origin': self.name,
                'company_id': self.company_id.id,
                'procure_method': 'make_to_stock',
            }
            move = self.env['stock.move'].sudo().create(move_vals)
            move._action_confirm()
            move._action_assign()
            
            # Set the lot on move line
            if move.move_line_ids:
                move.move_line_ids.write({'lot_id': self.lot_id.id})
            
            move._action_done()
            self.checkout_move_id = move.id
        except Exception as e:
            _logger.warning(f"Could not create checkout stock move (non-blocking): {e}")

    def _create_return_stock_move(self):
        """Create stock move for return. Uses return_location_id if set, otherwise Loaner Stock."""
        if not self.lot_id:
            return
        
        try:
            source_location = self._get_customer_location()
            dest_location = self.return_location_id or self._get_loaner_location()
            
            move_vals = {
                'name': f'Loaner Return: {self.name}',
                'product_id': self.product_id.id,
                'product_uom_qty': 1,
                'product_uom': self.product_id.uom_id.id,
                'location_id': source_location.id,
                'location_dest_id': dest_location.id,
                'origin': self.name,
                'company_id': self.company_id.id,
                'procure_method': 'make_to_stock',
            }
            move = self.env['stock.move'].sudo().create(move_vals)
            move._action_confirm()
            move._action_assign()
            
            if move.move_line_ids:
                move.move_line_ids.write({'lot_id': self.lot_id.id})
            
            move._action_done()
            self.return_move_id = move.id
        except Exception as e:
            _logger.warning(f"Could not create return stock move: {e}")

    # =========================================================================
    # HISTORY LOGGING
    # =========================================================================
    
    def _log_history(self, action, notes=None):
        """Log action to history."""
        self.ensure_one()
        self.env['fusion.loaner.history'].create({
            'checkout_id': self.id,
            'lot_id': self.lot_id.id if self.lot_id else False,
            'action': action,
            'notes': notes,
        })

    # =========================================================================
    # EMAIL METHODS
    # =========================================================================
    
    def _get_email_recipients(self):
        """Get all email recipients for loaner notifications."""
        recipients = {
            'client_email': self.partner_id.email if self.partner_id else None,
            'authorizer_email': self.authorizer_id.email if self.authorizer_id else None,
            'sales_rep_email': self.sales_rep_id.email if self.sales_rep_id else None,
            'office_emails': [],
        }
        
        # Get office emails from company
        company = self.company_id or self.env.company
        office_partners = company.sudo().x_fc_office_notification_ids
        recipients['office_emails'] = [p.email for p in office_partners if p.email]
        
        return recipients

    def _send_checkout_email(self):
        """Send checkout confirmation email to all parties."""
        self.ensure_one()
        recipients = self._get_email_recipients()
        to_emails = [e for e in [recipients['client_email'], recipients['authorizer_email']] if e]
        cc_emails = [e for e in [recipients['sales_rep_email']] if e] + recipients['office_emails']
        if not to_emails:
            return False

        client_name = self.partner_id.name or 'Client'
        product_name = self.product_id.name or 'Product'
        expected_return = self.expected_return_date.strftime('%B %d, %Y') if self.expected_return_date else 'N/A'

        body_html = self._email_build(
            title='Loaner Equipment Checkout',
            summary=f'Loaner equipment has been checked out for <strong>{client_name}</strong>.',
            email_type='info',
            sections=[('Loaner Details', [
                ('Reference', self.name),
                ('Product', product_name),
                ('Serial Number', self.lot_id.name if self.lot_id else None),
                ('Checkout Date', self.checkout_date.strftime('%B %d, %Y') if self.checkout_date else None),
                ('Expected Return', expected_return),
                ('Loaner Period', f'{self.loaner_period_days} days'),
            ])],
            note='<strong>Important:</strong> Please return the loaner equipment by the expected return date. '
                 'If not returned on time, rental charges may apply.',
            note_color='#d69e2e',
        )
        try:
            self.env['mail.mail'].sudo().create({
                'subject': f'Loaner Checkout - {product_name} - {self.name}',
                'body_html': body_html,
                'email_to': ', '.join(to_emails),
                'email_cc': ', '.join(cc_emails) if cc_emails else '',
                'model': 'fusion.loaner.checkout', 'res_id': self.id,
            }).send()
            return True
        except Exception as e:
            _logger.error(f"Failed to send checkout email for {self.name}: {e}")
            return False

    def _send_return_email(self):
        """Send return confirmation email."""
        self.ensure_one()
        recipients = self._get_email_recipients()
        to_emails = [e for e in [recipients['client_email']] if e]
        cc_emails = [e for e in [recipients['sales_rep_email']] if e]
        if not to_emails:
            return False

        client_name = self.partner_id.name or 'Client'
        product_name = self.product_id.name or 'Product'

        body_html = self._email_build(
            title='Loaner Equipment Returned',
            summary=f'Thank you for returning the loaner equipment, <strong>{client_name}</strong>.',
            email_type='success',
            sections=[('Return Details', [
                ('Reference', self.name),
                ('Product', product_name),
                ('Return Date', self.actual_return_date.strftime('%B %d, %Y') if self.actual_return_date else None),
                ('Condition', self.return_condition or None),
                ('Days Out', str(self.days_out)),
            ])],
        )
        try:
            self.env['mail.mail'].sudo().create({
                'subject': f'Loaner Returned - {product_name} - {self.name}',
                'body_html': body_html,
                'email_to': ', '.join(to_emails),
                'email_cc': ', '.join(cc_emails) if cc_emails else '',
                'model': 'fusion.loaner.checkout', 'res_id': self.id,
            }).send()
            return True
        except Exception as e:
            _logger.error(f"Failed to send return email for {self.name}: {e}")
            return False

    def _send_rental_conversion_email(self):
        """Send rental conversion notification."""
        self.ensure_one()
        recipients = self._get_email_recipients()
        to_emails = [e for e in [recipients['client_email'], recipients['authorizer_email']] if e]
        cc_emails = [e for e in [recipients['sales_rep_email']] if e] + recipients['office_emails']
        if not to_emails and not cc_emails:
            return False

        client_name = self.partner_id.name or 'Client'
        product_name = self.product_id.name or 'Product'
        weekly_rate = self.product_id.x_fc_rental_price_weekly or 0
        monthly_rate = self.product_id.x_fc_rental_price_monthly or 0

        body_html = self._email_build(
            title='Loaner Rental Conversion Notice',
            summary=f'The loaner equipment for <strong>{client_name}</strong> has exceeded the free loaner period.',
            email_type='urgent',
            sections=[('Equipment Details', [
                ('Reference', self.name),
                ('Product', product_name),
                ('Days Out', str(self.days_out)),
                ('Days Overdue', str(self.days_overdue)),
                ('Weekly Rental Rate', f'${weekly_rate:.2f}'),
                ('Monthly Rental Rate', f'${monthly_rate:.2f}'),
            ])],
            note='<strong>Action required:</strong> Please return the equipment or contact us to arrange '
                 'a rental agreement. Rental charges will apply until the equipment is returned.',
            note_color='#c53030',
        )
        email_to = ', '.join(to_emails) if to_emails else ', '.join(cc_emails[:1])
        email_cc = ', '.join(cc_emails) if to_emails else ', '.join(cc_emails[1:])
        try:
            self.env['mail.mail'].sudo().create({
                'subject': f'Loaner Rental Conversion - {product_name} - {self.name}',
                'body_html': body_html,
                'email_to': email_to, 'email_cc': email_cc,
                'model': 'fusion.loaner.checkout', 'res_id': self.id,
            }).send()
            return True
        except Exception as e:
            _logger.error(f"Failed to send rental conversion email for {self.name}: {e}")
            return False

    def _send_reminder_email(self, reminder_type):
        """Send reminder email based on type (day5, day8, day10)."""
        self.ensure_one()
        recipients = self._get_email_recipients()
        client_name = self.partner_id.name or 'Client'
        product_name = self.product_id.name or 'Product'
        expected_return = self.expected_return_date.strftime('%B %d, %Y') if self.expected_return_date else 'N/A'

        if reminder_type == 'day5':
            to_emails = [e for e in [recipients['sales_rep_email']] if e] + recipients['office_emails']
            cc_emails = []
            subject = f'Loaner Reminder: {product_name} - Day 5'
            email_type = 'attention'
            message = (f'The loaner equipment for {client_name} has been out for 5 days. '
                       f'Please follow up to arrange return.')
        elif reminder_type == 'day8':
            to_emails = [e for e in [recipients['client_email']] if e]
            cc_emails = [e for e in [recipients['sales_rep_email']] if e] + recipients['office_emails']
            subject = f'Loaner Return Reminder - {product_name}'
            email_type = 'attention'
            message = (f'Your loaner equipment has been out for 8 days. '
                       f'Please return it soon or it may be converted to a rental.')
        else:
            to_emails = [e for e in [recipients['client_email'], recipients['authorizer_email']] if e]
            cc_emails = [e for e in [recipients['sales_rep_email']] if e] + recipients['office_emails']
            subject = f'Loaner Return Required - {product_name}'
            email_type = 'urgent'
            message = (f'Your loaner equipment has been out for {self.days_out} days. '
                       f'If not returned, rental charges will apply.')

        if not to_emails:
            return False

        body_html = self._email_build(
            title='Loaner Equipment Reminder',
            summary=message,
            email_type=email_type,
            sections=[('Loaner Details', [
                ('Reference', self.name),
                ('Client', client_name),
                ('Product', product_name),
                ('Days Out', str(self.days_out)),
                ('Expected Return', expected_return),
            ])],
        )
        try:
            self.env['mail.mail'].sudo().create({
                'subject': subject,
                'body_html': body_html,
                'email_to': ', '.join(to_emails),
                'email_cc': ', '.join(cc_emails) if cc_emails else '',
                'model': 'fusion.loaner.checkout', 'res_id': self.id,
            }).send()
            return True
        except Exception as e:
            _logger.error(f"Failed to send {reminder_type} reminder for {self.name}: {e}")
            return False

    # =========================================================================
    # CRON METHODS
    # =========================================================================
    
    @api.model
    def _cron_check_overdue_loaners(self):
        """Daily cron to check for overdue loaners and send reminders."""
        today = fields.Date.today()
        
        # Find all active loaners
        active_loaners = self.search([
            ('state', 'in', ['checked_out', 'overdue', 'rental_pending']),
        ])
        
        for loaner in active_loaners:
            days_out = loaner.days_out
            
            # Update overdue status
            if loaner.state == 'checked_out' and loaner.expected_return_date and today > loaner.expected_return_date:
                loaner.write({'state': 'overdue'})
                loaner._log_history('overdue', f'Loaner is now overdue by {loaner.days_overdue} days')
            
            # Day 5 reminder
            if days_out >= 5 and not loaner.reminder_day5_sent:
                loaner._send_reminder_email('day5')
                loaner.reminder_day5_sent = True
                loaner._log_history('reminder_sent', 'Day 5 reminder sent')
            
            # Day 8 warning
            if days_out >= 8 and not loaner.reminder_day8_sent:
                loaner._send_reminder_email('day8')
                loaner.reminder_day8_sent = True
                loaner._log_history('reminder_sent', 'Day 8 rental warning sent')
            
            # Day 10 final notice
            if days_out >= 10 and not loaner.reminder_day10_sent:
                loaner._send_reminder_email('day10')
                loaner.reminder_day10_sent = True
                loaner._log_history('reminder_sent', 'Day 10 final notice sent')
                
                # Flag for rental conversion
                if loaner.state != 'rental_pending':
                    loaner.action_convert_to_rental()
