# -*- coding: utf-8 -*-

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

_logger = logging.getLogger(__name__)


class FusionAssessment(models.Model):
    _name = 'fusion.assessment'
    _description = 'ADP Assessment'
    _inherit = ['mail.thread', 'mail.activity.mixin', 'fusion.email.builder.mixin']
    _order = 'assessment_date desc, id desc'
    _rec_name = 'display_name'

    # Status
    state = fields.Selection([
        ('draft', 'In Progress'),
        ('pending_signature', 'Pending Signatures'),
        ('completed', 'Completed'),
        ('cancelled', 'Cancelled'),
    ], string='Status', default='draft', tracking=True, index=True)
    
    display_name = fields.Char(
        string='Display Name',
        compute='_compute_display_name',
        store=True,
    )
    
    # Reference
    reference = fields.Char(
        string='Reference',
        readonly=True,
        copy=False,
        default=lambda self: _('New'),
    )
    
    # ===== EXPRESS FORM: EQUIPMENT TYPE =====
    equipment_type = fields.Selection([
        ('rollator', 'Rollator'),
        ('wheelchair', 'Wheelchair'),
        ('powerchair', 'Powerchair'),
    ], string='Equipment Type', tracking=True, index=True)
    
    # Rollator Types
    rollator_type = fields.Selection([
        ('type_1', 'Type 1'),
        ('type_2', 'Type 2'),
        ('type_3', 'Type 3'),
    ], string='Rollator Type')
    
    # Wheelchair Types (Adult Manual)
    wheelchair_type = fields.Selection([
        ('type_1', 'Type 1 - Adult Manual Standard Wheelchair'),
        ('type_2', 'Type 2 - Adult Manual Lightweight Wheelchair'),
        ('type_3', 'Type 3 - Adult Manual Ultra Lightweight Wheelchair'),
        ('type_4', 'Type 4 - Adult Manual Tilt Wheelchair'),
        ('type_5', 'Type 5 - Adult Manual Dynamic Tilt Wheelchair'),
    ], string='Wheelchair Type')
    
    # Powerchair Types
    powerchair_type = fields.Selection([
        ('type_1', 'Adult Power Base Type 1'),
        ('type_2', 'Adult Power Base Type 2'),
        ('type_3', 'Adult Power Base Type 3'),
    ], string='Powerchair Type')
    
    # ===== EXPRESS FORM: ROLLATOR MEASUREMENTS =====
    rollator_handle_height = fields.Float(string='Handle Height (inches)', digits=(10, 2))
    rollator_seat_height = fields.Float(string='Seat Height (inches)', digits=(10, 2))
    
    # ===== EXPRESS FORM: ROLLATOR ADDONS =====
    rollator_addons = fields.Text(
        string='Rollator Addons',
        help='Comma-separated list of selected rollator addons',
    )
    
    # ===== EXPRESS FORM: WHEELCHAIR/POWERCHAIR MEASUREMENTS =====
    legrest_length = fields.Float(string='Legrest Length (inches)', digits=(10, 2))
    cane_height = fields.Float(string='Cane Height (inches)', digits=(10, 2), help='Ground to Canes')
    
    # ===== EXPRESS FORM: WHEELCHAIR OPTIONS =====
    frame_options = fields.Text(
        string='Frame Options',
        help='Comma-separated list: Recliner Option, Dynamic Tilt Frame, Titanium Frame',
    )
    
    wheel_options = fields.Text(
        string='Wheel Options/Addons',
        help='Comma-separated list of wheel options',
    )
    
    legrest_options = fields.Text(
        string='Legrest Accessories',
        help='Comma-separated list of legrest accessories',
    )
    
    additional_adp_options = fields.Text(
        string='Additional ADP Funded Options',
        help='Comma-separated list of additional ADP options',
    )
    
    seatbelt_type = fields.Selection([
        ('standard', 'Standard Belt - No Padding'),
        ('padded', 'Padded Belt - Positioning Belts (Modular)'),
        ('4point', '4 Point Seat Belt - Positioning Belts (Modular)'),
        ('chest_harness', 'Chest Harness - Positioning Belts (Modular)'),
        ('additional_pads', 'Additional Pads - Positioning Belts (Custom)'),
    ], string='Seat Belt Type')
    
    # ===== EXPRESS FORM: POWERCHAIR OPTIONS =====
    powerchair_options = fields.Text(
        string='Powerchair Additional Options',
        help='Comma-separated list of powerchair additional ADP options',
    )
    
    specialty_controls = fields.Text(
        string='Specialty Components',
        help='Comma-separated list of specialty controls (rationale required)',
    )
    
    # ===== EXPRESS FORM: ADDITIONAL INFO =====
    additional_customization = fields.Text(
        string='Additional Information/Customization',
        help='Free-form notes for customization requirements',
    )
    
    cushion_info = fields.Char(
        string='Cushion',
        help='Cushion details for wheelchair/powerchair',
    )
    
    backrest_info = fields.Char(
        string='Backrest',
        help='Backrest details for wheelchair/powerchair',
    )
    
    # ===== EXPRESS FORM: KEY DATES (map to SO x_fc_ fields) =====
    assessment_start_date = fields.Date(
        string='Assessment Start Date',
        tracking=True,
    )
    assessment_end_date = fields.Date(
        string='Assessment End Date',
        tracking=True,
    )
    claim_authorization_date = fields.Date(
        string='Claim Authorization Date',
        tracking=True,
    )
    
    # ===== EXPRESS FORM: CLIENT TYPE =====
    client_type = fields.Selection([
        ('reg', 'REG - Regular ADP'),
        ('ods', 'ODS - ODSP'),
        ('acs', 'ACS - ACSD'),
        ('owp', 'OWP - Ontario Works'),
    ], string='Client Type', default='reg',
       help='REG = ADP only, ODS/ACS/OWP = ADP + ODSP')
    
    # ===== EXPRESS FORM: REASON FOR APPLICATION =====
    reason_for_application = fields.Selection([
        ('first_access', 'First Time Access - NO previous ADP'),
        ('additions', 'Additions'),
        ('mod_non_adp', 'Modification/Upgrade - Original NOT through ADP'),
        ('mod_adp', 'Modification/Upgrade - Original through ADP'),
        ('replace_status', 'Replacement - Change in Status'),
        ('replace_size', 'Replacement - Change in Body Size'),
        ('replace_worn', 'Replacement - Worn out (past useful life)'),
        ('replace_lost', 'Replacement - Lost'),
        ('replace_stolen', 'Replacement - Stolen'),
        ('replace_damaged', 'Replacement - Damaged beyond repair'),
        ('replace_no_longer_meets', 'Replacement - No longer meets needs'),
        ('growth', 'Growth/Change in condition'),
    ], string='Reason for Application')
    
    previous_funding_date = fields.Date(
        string='Previous Funding Date',
        help='Date of previous ADP funding (for replacements)',
    )
    
    # ===== EXPRESS FORM: CLIENT BIOGRAPHIC (enhanced) =====
    client_middle_name = fields.Char(string='Middle Name')
    client_health_card_version = fields.Char(string='Health Card Version', help='Version code on health card')
    
    # ===== CLIENT INFORMATION =====
    client_name = fields.Char(
        string='Client Name',
        required=True,
        tracking=True,
    )
    client_first_name = fields.Char(string='First Name')
    client_last_name = fields.Char(string='Last Name')
    
    client_address = fields.Text(string='Address')
    client_street = fields.Char(string='Street')
    client_unit = fields.Char(string='Unit/Apt/Suite')
    client_city = fields.Char(string='City')
    client_state = fields.Char(string='Province/State', default='Ontario')
    client_postal_code = fields.Char(string='Postal Code')
    client_country_id = fields.Many2one('res.country', string='Country', default=lambda self: self.env.ref('base.ca', raise_if_not_found=False))
    
    client_phone = fields.Char(string='Phone')
    client_mobile = fields.Char(string='Mobile')
    client_email = fields.Char(string='Email')
    
    client_dob = fields.Date(string='Date of Birth')
    client_health_card = fields.Char(string='Health Card Number')
    
    # Link to existing partner or create new
    partner_id = fields.Many2one(
        'res.partner',
        string='Client Partner',
        help='Link to existing customer record',
    )
    create_new_partner = fields.Boolean(
        string='Create New Client',
        default=True,
        help='If checked, a new customer record will be created on completion',
    )
    
    # Client References (for searchability)
    client_reference_1 = fields.Char(string='Client Reference 1')
    client_reference_2 = fields.Char(string='Client Reference 2')
    
    # ===== ASSESSMENT PARTICIPANTS =====
    sales_rep_id = fields.Many2one(
        'res.users',
        string='Sales Rep',
        default=lambda self: self.env.user,
        tracking=True,
    )
    
    authorizer_id = fields.Many2one(
        'res.partner',
        string='Authorizer/OT',
        tracking=True,
        help='The Occupational Therapist or Authorizer conducting the assessment',
    )
    
    # ===== ASSESSMENT DATE/LOCATION =====
    assessment_date = fields.Datetime(
        string='Assessment Date',
        default=fields.Datetime.now,
        required=True,
        tracking=True,
    )
    
    assessment_location = fields.Selection([
        ('home', 'Client Home'),
        ('clinic', 'Clinic/Office'),
        ('hospital', 'Hospital'),
        ('ltc', 'Long Term Care'),
        ('other', 'Other'),
    ], string='Location Type', default='home')
    
    assessment_location_notes = fields.Text(string='Location Notes')
    
    # ===== WHEELCHAIR SPECIFICATIONS =====
    # Measurements (in inches)
    seat_width = fields.Float(string='Seat Width (inches)', digits=(10, 2))
    seat_depth = fields.Float(string='Seat Depth (inches)', digits=(10, 2))
    seat_to_floor_height = fields.Float(string='Seat to Floor Height (inches)', digits=(10, 2))
    back_height = fields.Float(string='Back Height (inches)', digits=(10, 2))
    armrest_height = fields.Float(string='Armrest Height (inches)', digits=(10, 2))
    footrest_length = fields.Float(string='Footrest Length (inches)', digits=(10, 2))
    
    # Additional Measurements
    overall_width = fields.Float(string='Overall Width (inches)', digits=(10, 2))
    overall_length = fields.Float(string='Overall Length (inches)', digits=(10, 2))
    overall_height = fields.Float(string='Overall Height (inches)', digits=(10, 2))
    seat_angle = fields.Float(string='Seat Angle (degrees)', digits=(10, 1))
    back_angle = fields.Float(string='Back Angle (degrees)', digits=(10, 1))
    
    # Client Measurements
    client_weight = fields.Float(string='Client Weight (lbs)', digits=(10, 1))
    client_height = fields.Float(string='Client Height (inches)', digits=(10, 1))
    
    # ===== PRODUCT TYPES =====
    cushion_type = fields.Selection([
        ('foam', 'Foam'),
        ('gel', 'Gel'),
        ('air', 'Air'),
        ('hybrid', 'Hybrid'),
        ('custom', 'Custom Molded'),
        ('other', 'Other'),
    ], string='Cushion Type')
    cushion_notes = fields.Text(string='Cushion Notes')
    
    backrest_type = fields.Selection([
        ('standard', 'Standard'),
        ('adjustable', 'Adjustable Tension'),
        ('solid', 'Solid Back'),
        ('contoured', 'Contoured'),
        ('custom', 'Custom'),
        ('other', 'Other'),
    ], string='Backrest Type')
    backrest_notes = fields.Text(string='Backrest Notes')
    
    frame_type = fields.Selection([
        ('folding', 'Folding'),
        ('rigid', 'Rigid'),
        ('tilt', 'Tilt-in-Space'),
        ('reclining', 'Reclining'),
        ('standing', 'Standing'),
        ('power', 'Power'),
        ('other', 'Other'),
    ], string='Frame Type')
    frame_notes = fields.Text(string='Frame Notes')
    
    wheel_type = fields.Selection([
        ('pneumatic', 'Pneumatic'),
        ('solid', 'Solid'),
        ('flat_free', 'Flat-Free'),
        ('mag', 'Mag Wheels'),
        ('spoke', 'Spoke Wheels'),
        ('other', 'Other'),
    ], string='Wheel Type')
    wheel_notes = fields.Text(string='Wheel Notes')
    
    # ===== ACCESSIBILITY/MOBILITY NEEDS =====
    mobility_notes = fields.Text(
        string='Mobility Needs',
        help='Document the client mobility needs and challenges',
    )
    
    accessibility_notes = fields.Text(
        string='Accessibility Notes',
        help='Document accessibility requirements and home environment',
    )
    
    special_requirements = fields.Text(
        string='Special Requirements',
        help='Any special requirements or customizations needed',
    )
    
    diagnosis = fields.Text(
        string='Diagnosis/Condition',
        help='Relevant medical diagnosis or conditions',
    )
    
    # ===== PAGE 11: CONSENT & DECLARATION =====
    consent_signed_by = fields.Selection([
        ('applicant', 'Applicant'),
        ('agent', 'Agent'),
    ], string='Consent Signed By', default='applicant',
       help='Who signed the ADP consent declaration')

    consent_declaration_accepted = fields.Boolean(
        string='Consent Declaration Accepted',
        help='Whether the consent declaration checkbox was checked',
    )
    consent_date = fields.Date(
        string='Consent Date',
        help='Date the consent was signed',
    )

    # Agent info (only if consent_signed_by == 'agent')
    agent_relationship = fields.Selection([
        ('spouse', 'Spouse'),
        ('parent', 'Parent(s)'),
        ('child', 'Child'),
        ('power_of_attorney', 'Power of Attorney'),
        ('public_guardian', 'Public Guardian/Trustee'),
    ], string='Agent Relationship')
    agent_first_name = fields.Char(string='Agent First Name')
    agent_last_name = fields.Char(string='Agent Last Name')
    agent_middle_initial = fields.Char(string='Agent Middle Initial')
    agent_unit = fields.Char(string='Agent Unit')
    agent_street_number = fields.Char(string='Agent Street Number')
    agent_street_name = fields.Char(string='Agent Street Name')
    agent_city = fields.Char(string='Agent City')
    agent_province = fields.Char(string='Agent Province', default='Ontario')
    agent_postal_code = fields.Char(string='Agent Postal Code')
    agent_home_phone = fields.Char(string='Agent Home Phone')
    agent_business_phone = fields.Char(string='Agent Business Phone')
    agent_phone_ext = fields.Char(string='Agent Phone Ext')

    # Generated filled PDF from template engine
    signed_page_11_pdf = fields.Binary(string='Signed Page 11 PDF')
    signed_page_11_pdf_filename = fields.Char(string='Signed Page 11 Filename')

    # ===== SIGNATURES =====
    signature_page_11 = fields.Binary(
        string='Page 11 Signature (Authorizer)',
        help='Digital signature for ADP Application Page 11',
    )
    signature_page_11_name = fields.Char(string='Page 11 Signer Name')
    signature_page_11_date = fields.Datetime(string='Page 11 Signed Date')
    
    signature_page_12 = fields.Binary(
        string='Page 12 Signature (Client)',
        help='Digital signature for ADP Application Page 12',
    )
    signature_page_12_name = fields.Char(string='Page 12 Signer Name')
    signature_page_12_date = fields.Datetime(string='Page 12 Signed Date')
    
    signatures_complete = fields.Boolean(
        string='Signatures Complete',
        compute='_compute_signatures_complete',
        store=True,
    )
    
    # ===== RELATIONSHIPS =====
    document_ids = fields.One2many(
        'fusion.adp.document',
        'assessment_id',
        string='Documents',
    )
    
    comment_ids = fields.One2many(
        'fusion.authorizer.comment',
        'assessment_id',
        string='Comments',
    )
    
    sale_order_id = fields.Many2one(
        'sale.order',
        string='Created Sale Order',
        readonly=True,
        copy=False,
    )
    
    # ===== COMPUTED FIELDS =====
    document_count = fields.Integer(
        string='Document Count',
        compute='_compute_document_count',
    )

    @api.depends('client_name', 'reference', 'equipment_type')
    def _compute_display_name(self):
        equipment_labels = {'rollator': 'Rollator', 'wheelchair': 'Wheelchair', 'powerchair': 'Powerchair'}
        for assessment in self:
            if assessment.reference and assessment.reference != 'New':
                equip = equipment_labels.get(assessment.equipment_type, '')
                equip_suffix = f' ({equip})' if equip else ''
                assessment.display_name = f"{assessment.reference} - {assessment.client_name or 'Unknown'}{equip_suffix}"
            else:
                assessment.display_name = assessment.client_name or _('New Assessment')

    @api.depends('signature_page_11', 'signature_page_12')
    def _compute_signatures_complete(self):
        for assessment in self:
            assessment.signatures_complete = bool(assessment.signature_page_11 and assessment.signature_page_12)

    @api.depends('document_ids')
    def _compute_document_count(self):
        for assessment in self:
            assessment.document_count = len(assessment.document_ids)

    @api.model_create_multi
    def create(self, vals_list):
        """Override create to generate reference number"""
        for vals in vals_list:
            if vals.get('reference', 'New') == 'New':
                vals['reference'] = self.env['ir.sequence'].next_by_code('fusion.assessment') or 'New'
        return super().create(vals_list)

    def action_mark_pending_signature(self):
        """Move to pending signature state"""
        self.ensure_one()
        self.state = 'pending_signature'
        return True

    def action_complete(self):
        """Complete the assessment and create draft sale order"""
        self.ensure_one()
        
        if not self.signatures_complete:
            raise UserError(_('Please ensure both Page 11 and Page 12 signatures are captured before completing.'))
        
        # Create or link partner
        partner = self._ensure_partner()
        
        # Create draft sale order
        sale_order = self._create_draft_sale_order(partner)
        
        # Generate signed documents
        self._generate_signed_documents()
        
        # Update state
        self.write({
            'state': 'completed',
            'sale_order_id': sale_order.id,
            'partner_id': partner.id,
        })
        
        # Send notifications
        self._send_completion_notifications()
        
        return {
            'type': 'ir.actions.act_window',
            'name': _('Created Sale Order'),
            'res_model': 'sale.order',
            'res_id': sale_order.id,
            'view_mode': 'form',
            'views': [(False, 'form')],
            'target': 'current',
        }

    def action_complete_express(self):
        """Complete express assessment and create draft sale order (no signatures required)"""
        self.ensure_one()
        
        # Validate required fields
        if not self.equipment_type:
            raise UserError(_('Please select an equipment type.'))
        if not self.authorizer_id:
            raise UserError(_('Please select an authorizer.'))
        if not self.client_name:
            raise UserError(_('Please enter the client name.'))
        
        # Create or link partner
        partner = self._ensure_partner()
        
        # Create draft sale order
        sale_order = self._create_draft_sale_order(partner)
        
        # Update state
        self.write({
            'state': 'completed',
            'sale_order_id': sale_order.id,
            'partner_id': partner.id,
        })
        
        _logger.info(f"Completed express assessment {self.reference}, created SO {sale_order.name}")
        
        return sale_order

    def action_cancel(self):
        """Cancel the assessment"""
        self.ensure_one()
        self.state = 'cancelled'
        return True

    def action_reset_draft(self):
        """Reset to draft state"""
        self.ensure_one()
        self.state = 'draft'
        return True

    def _ensure_partner(self):
        """Ensure a partner exists for the client, create if needed"""
        self.ensure_one()
        
        if self.partner_id:
            return self.partner_id
        
        if not self.create_new_partner:
            raise UserError(_('Please select an existing client or check "Create New Client".'))
        
        # Build address
        address_parts = []
        if self.client_street:
            address_parts.append(self.client_street)
        if self.client_city:
            address_parts.append(self.client_city)
        if self.client_state:
            address_parts.append(self.client_state)
        if self.client_postal_code:
            address_parts.append(self.client_postal_code)
        
        partner_vals = {
            'name': self.client_name,
            'street': self.client_street or '',
            'street2': self.client_unit or False,
            'city': self.client_city or '',
            'zip': self.client_postal_code or '',
            'phone': self.client_phone or '',
            'email': self.client_email or '',
            'customer_rank': 1,
        }
        
        if self.client_country_id:
            partner_vals['country_id'] = self.client_country_id.id
        
        partner = self.env['res.partner'].sudo().create(partner_vals)
        _logger.info(f"Created new partner {partner.name} (ID: {partner.id}) from assessment {self.reference}")
        
        return partner

    def _create_draft_sale_order(self, partner):
        """Create a draft sale order from the assessment"""
        self.ensure_one()
        
        SaleOrder = self.env['sale.order'].sudo()
        CrmTag = self.env['crm.tag'].sudo()
        
        # Determine sale type based on client type
        # REG = ADP only, ODS/ACS/OWP = ADP + ODSP
        sale_type = 'adp'
        if self.client_type in ['ods', 'acs', 'owp']:
            sale_type = 'adp_odsp'
        
        # Determine the correct workflow status for the SO.
        # The write() auto-transition (assessment_completed -> waiting_for_application)
        # does NOT fire during create(), so we set the final target status directly.
        if self.assessment_start_date and self.assessment_end_date:
            # Both dates filled = assessment completed -> advance to waiting_for_application
            target_status = 'waiting_for_application'
        elif self.assessment_start_date:
            # Only start date = assessment is scheduled
            target_status = 'assessment_scheduled'
        else:
            target_status = 'quotation'
        
        # Prepare values
        so_vals = {
            'partner_id': partner.id,
            'user_id': self.sales_rep_id.id if self.sales_rep_id else self.env.user.id,
            'state': 'draft',
            'origin': f'Assessment: {self.reference}',
            'x_fc_sale_type': sale_type,
            # Issue 2 fix: Set assessment back-link for traceability
            'assessment_id': self.id,
            # Set the correct workflow status directly
            'x_fc_adp_application_status': target_status,
        }
        
        # Set authorizer if available
        if self.authorizer_id:
            so_vals['x_fc_authorizer_id'] = self.authorizer_id.id
        
        # Set client references if available
        if self.client_reference_1:
            so_vals['x_fc_client_ref_1'] = self.client_reference_1
        if self.client_reference_2:
            so_vals['x_fc_client_ref_2'] = self.client_reference_2
        
        # Map assessment dates to SO x_fc_ fields
        if self.assessment_start_date:
            so_vals['x_fc_assessment_start_date'] = self.assessment_start_date
        if self.assessment_end_date:
            so_vals['x_fc_assessment_end_date'] = self.assessment_end_date
        if self.claim_authorization_date:
            so_vals['x_fc_claim_authorization_date'] = self.claim_authorization_date
        
        # Map reason for application
        if self.reason_for_application:
            so_vals['x_fc_reason_for_application'] = self.reason_for_application
        if self.previous_funding_date:
            so_vals['x_fc_previous_funding_date'] = self.previous_funding_date
        
        # Map client type (assessment uses lowercase, sale.order uses uppercase)
        if self.client_type:
            client_type_map = {
                'reg': 'REG',
                'ods': 'ODS',
                'acs': 'ACS',
                'owp': 'OWP',
            }
            so_vals['x_fc_client_type'] = client_type_map.get(self.client_type, self.client_type.upper())
        
        # =====================================================================
        # Issue 3 & 4 fix: Map Page 11 consent & signature tracking to SO
        # =====================================================================
        if self.consent_signed_by:
            # Map consent_signed_by to x_fc_page11_signer_type
            if self.consent_signed_by == 'applicant':
                so_vals['x_fc_page11_signer_type'] = 'client'
                so_vals['x_fc_page11_signer_name'] = self.client_name or ''
            elif self.consent_signed_by == 'agent':
                # Map agent_relationship to signer_type
                agent_type_map = {
                    'spouse': 'spouse',
                    'parent': 'parent',
                    'child': 'legal_guardian',
                    'power_of_attorney': 'poa',
                    'public_guardian': 'public_trustee',
                }
                so_vals['x_fc_page11_signer_type'] = agent_type_map.get(
                    self.agent_relationship, 'legal_guardian'
                )
                agent_name = f"{self.agent_first_name or ''} {self.agent_last_name or ''}".strip()
                so_vals['x_fc_page11_signer_name'] = agent_name or self.client_name or ''
                if self.agent_relationship:
                    relationship_labels = dict(self._fields['agent_relationship'].selection)
                    so_vals['x_fc_page11_signer_relationship'] = relationship_labels.get(
                        self.agent_relationship, self.agent_relationship
                    )
        
        if self.consent_date:
            so_vals['x_fc_page11_signed_date'] = self.consent_date
        
        # Build tags list
        tag_ids = []
        
        # Always add ADP tag
        adp_tag = CrmTag.search([('name', 'ilike', 'ADP')], limit=1)
        if adp_tag:
            tag_ids.append(adp_tag.id)
        
        # Add equipment type tag based on selection
        equipment_tag_name = None
        if self.equipment_type == 'wheelchair' and self.wheelchair_type:
            type_map = {
                'type_1': 'TYPE 1 WHEELCHAIR',
                'type_2': 'TYPE 2 WHEELCHAIR',
                'type_3': 'TYPE 3 WHEELCHAIR',
                'type_4': 'TYPE 4 WHEELCHAIR',
                'type_5': 'TYPE 5 WHEELCHAIR',
            }
            equipment_tag_name = type_map.get(self.wheelchair_type)
        elif self.equipment_type == 'rollator' and self.rollator_type:
            type_map = {
                'type_1': 'TYPE 1 ROLLATOR',
                'type_2': 'TYPE 2 ROLLATOR',
                'type_3': 'TYPE 3 ROLLATOR',
            }
            equipment_tag_name = type_map.get(self.rollator_type)
        elif self.equipment_type == 'powerchair' and self.powerchair_type:
            type_map = {
                'type_1': 'TYPE 1 POWERCHAIR',
                'type_2': 'TYPE 2 POWERCHAIR',
                'type_3': 'TYPE 3 POWERCHAIR',
            }
            equipment_tag_name = type_map.get(self.powerchair_type)
        
        # Find or create the equipment tag
        if equipment_tag_name:
            equipment_tag = CrmTag.search([('name', 'ilike', equipment_tag_name)], limit=1)
            if not equipment_tag:
                # Create the tag if it doesn't exist
                equipment_tag = CrmTag.create({'name': equipment_tag_name})
                _logger.info(f"Created new CRM tag: {equipment_tag_name}")
            tag_ids.append(equipment_tag.id)
        
        # Add tags to sale order values
        if tag_ids:
            so_vals['tag_ids'] = [(6, 0, tag_ids)]
        
        sale_order = SaleOrder.create(so_vals)
        _logger.info(f"Created draft sale order {sale_order.name} from assessment {self.reference} "
                     f"with sale_type={sale_type}, status={target_status}")
        
        # =====================================================================
        # Issue 6 fix: Post workflow-consistent chatter messages
        # =====================================================================
        # Post a workflow status message matching what backend wizards would generate
        equipment_labels = {
            'rollator': 'Rollator', 'wheelchair': 'Wheelchair', 'powerchair': 'Powerchair',
        }
        equipment_label = equipment_labels.get(self.equipment_type, 'Equipment')
        sales_rep_name = self.sales_rep_id.name if self.sales_rep_id else self.env.user.name
        authorizer_name = self.authorizer_id.name if self.authorizer_id else 'N/A'
        
        workflow_msg = Markup(
            '<div class="alert alert-info" role="alert">'
            '<h5 class="alert-heading"><i class="fa fa-clipboard"/> Assessment Completed (Portal)</h5>'
            '<ul class="mb-0">'
            f'<li><strong>Assessment:</strong> {self.reference}</li>'
            f'<li><strong>Equipment:</strong> {equipment_label}</li>'
            f'<li><strong>Sales Rep:</strong> {sales_rep_name}</li>'
            f'<li><strong>Authorizer:</strong> {authorizer_name}</li>'
            f'<li><strong>Assessment Date:</strong> {self.assessment_start_date or "N/A"}'
            f' to {self.assessment_end_date or "N/A"}</li>'
            f'<li><strong>Status set to:</strong> {target_status.replace("_", " ").title()}</li>'
            '</ul>'
            '</div>'
        )
        sale_order.message_post(
            body=workflow_msg,
            message_type='notification',
            subtype_xmlid='mail.mt_note',
        )
        
        # Post assessment details to chatter as HTML table
        assessment_html = self._format_assessment_html_table()
        sale_order.message_post(
            body=Markup(assessment_html),
            message_type='comment',
            subtype_xmlid='mail.mt_note',
        )
        
        # =====================================================================
        # Issue 4 fix: Post consent & agent details to chatter
        # =====================================================================
        if self.consent_signed_by:
            consent_label = 'Applicant' if self.consent_signed_by == 'applicant' else 'Agent'
            consent_parts = [
                f'<li><strong>Signed by:</strong> {consent_label}</li>',
            ]
            if self.consent_date:
                consent_parts.append(f'<li><strong>Consent date:</strong> {self.consent_date}</li>')
            if self.consent_declaration_accepted:
                consent_parts.append('<li><strong>Declaration accepted:</strong> Yes</li>')
            
            # Add agent details if signed by agent
            if self.consent_signed_by == 'agent':
                agent_name = f"{self.agent_first_name or ''} {self.agent_last_name or ''}".strip()
                if agent_name:
                    consent_parts.append(f'<li><strong>Agent name:</strong> {agent_name}</li>')
                if self.agent_relationship:
                    rel_labels = dict(self._fields['agent_relationship'].selection)
                    consent_parts.append(
                        f'<li><strong>Relationship:</strong> '
                        f'{rel_labels.get(self.agent_relationship, self.agent_relationship)}</li>'
                    )
                agent_addr_parts = []
                if self.agent_unit:
                    agent_addr_parts.append(f'Unit {self.agent_unit}')
                if self.agent_street_number:
                    agent_addr_parts.append(self.agent_street_number)
                if self.agent_street_name:
                    agent_addr_parts.append(self.agent_street_name)
                if self.agent_city:
                    agent_addr_parts.append(self.agent_city)
                if self.agent_province:
                    agent_addr_parts.append(self.agent_province)
                if self.agent_postal_code:
                    agent_addr_parts.append(self.agent_postal_code)
                if agent_addr_parts:
                    consent_parts.append(
                        f'<li><strong>Agent address:</strong> {", ".join(agent_addr_parts)}</li>'
                    )
                phones = []
                if self.agent_home_phone:
                    phones.append(f'Home: {self.agent_home_phone}')
                if self.agent_business_phone:
                    ext = f' ext {self.agent_phone_ext}' if self.agent_phone_ext else ''
                    phones.append(f'Business: {self.agent_business_phone}{ext}')
                if phones:
                    consent_parts.append(
                        f'<li><strong>Agent phone:</strong> {", ".join(phones)}</li>'
                    )
            
            consent_msg = Markup(
                '<div class="alert alert-success" role="alert">'
                '<h5 class="alert-heading"><i class="fa fa-file-text"/> Page 11 Consent Information</h5>'
                '<ul class="mb-0">'
                + ''.join(consent_parts) +
                '</ul>'
                '</div>'
            )
            sale_order.message_post(
                body=consent_msg,
                message_type='notification',
                subtype_xmlid='mail.mt_note',
            )
        
        # Send email notification to sales person and authorizer
        self._send_assessment_completed_email(sale_order)
        
        # Schedule follow-up activity for sales rep
        self._schedule_followup_activity(sale_order)
        
        return sale_order
    
    def _schedule_followup_activity(self, sale_order):
        """Schedule a follow-up activity for the sales rep"""
        self.ensure_one()
        
        sales_rep = self.sales_rep_id or self.env.user
        if not sales_rep:
            return
        
        # Get the "To Do" activity type
        activity_type = self.env.ref('mail.mail_activity_data_todo', raise_if_not_found=False)
        if not activity_type:
            _logger.warning("Could not find 'To Do' activity type")
            return
        
        # Get equipment type label
        equipment_labels = {
            'wheelchair': 'Wheelchair',
            'rollator': 'Rollator',
            'powerchair': 'Powerchair',
        }
        equipment_label = equipment_labels.get(self.equipment_type, 'Equipment')
        
        # Schedule activity for tomorrow
        due_date = fields.Date.today() + timedelta(days=1)
        
        try:
            sale_order.activity_schedule(
                activity_type_id=activity_type.id,
                date_deadline=due_date,
                user_id=sales_rep.id,
                summary=f'Follow up on {equipment_label} Assessment',
                note=f'Assessment {self.reference} for {self.client_name} has been completed. Please follow up with the client and authorizer.',
            )
            _logger.info(f"Scheduled follow-up activity for {sales_rep.name} on SO {sale_order.name}")
        except Exception as e:
            _logger.error(f"Failed to schedule follow-up activity: {e}")
    
    def _send_assessment_completed_email(self, sale_order):
        """Send email notification to sales person, authorizer, and office about completed assessment.
        Includes the full assessment report so recipients can review without logging in."""
        self.ensure_one()

        if not self._email_is_enabled():
            return

        to_emails = []
        cc_emails = []
        if self.authorizer_id and self.authorizer_id.email:
            to_emails.append(self.authorizer_id.email)
        if self.sales_rep_id and self.sales_rep_id.email:
            cc_emails.append(self.sales_rep_id.email)
        company = self.env.company
        office_partners = company.sudo().x_fc_office_notification_ids
        cc_emails.extend([p.email for p in office_partners if p.email])
        if not to_emails and not cc_emails:
            return

        sales_rep_name = self.sales_rep_id.name if self.sales_rep_id else 'The Sales Team'
        assessment_date = self.assessment_end_date.strftime('%B %d, %Y') if self.assessment_end_date else 'Today'
        equipment_labels = {'rollator': 'Rollator', 'wheelchair': 'Wheelchair', 'powerchair': 'Powerchair'}
        equipment_label = equipment_labels.get(self.equipment_type, 'Equipment')

        # Build the detailed assessment report sections for the email
        report_sections = self._build_assessment_email_sections(sale_order, equipment_label, assessment_date)

        email_body = self._email_build(
            title='Assessment Completed',
            summary=f'The ADP assessment for <strong>{self.client_name}</strong> has been completed '
                    f'on {assessment_date}. A draft sales order has been created. '
                    f'The full assessment report is included below.',
            email_type='success',
            sections=report_sections,
            note='<strong>Next steps:</strong> Please submit the ADP application '
                 '(including pages 11-12 signed by the client) so we can proceed with the claim submission.',
            button_url=f'{sale_order.get_base_url()}/web#id={sale_order.id}&model=sale.order&view_type=form',
            button_text='View Sale Order',
            sender_name=sales_rep_name,
        )

        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'Assessment Completed - {self.client_name} ({equipment_label}) - {sale_order.name}',
                'body_html': email_body,
                'email_to': email_to, 'email_cc': email_cc,
                'model': 'sale.order', 'res_id': sale_order.id,
                'auto_delete': True,
            }).send()
            chatter_body = Markup(
                '<div class="alert alert-info" role="alert">'
                f'<strong>Assessment Completed email sent</strong>'
                f'<ul class="mb-0 mt-1"><li>To: {email_to}</li>'
                f'<li>CC: {email_cc or "None"}</li></ul></div>'
            )
            sale_order.message_post(body=chatter_body, message_type='notification', subtype_xmlid='mail.mt_note')
            _logger.info(f"Sent assessment completed email for {self.reference}")
        except Exception as e:
            _logger.error(f"Failed to send assessment completed email: {e}")

    def _build_assessment_email_sections(self, sale_order, equipment_label, assessment_date):
        """Build comprehensive email sections with all assessment details.
        Returns a list of (heading, rows) tuples for _email_build()."""
        self.ensure_one()

        sections = []

        # --- Section 1: Overview ---
        overview_rows = [
            ('Reference', self.reference),
            ('Sales Order', sale_order.name),
            ('Client', self.client_name),
            ('Equipment', equipment_label),
            ('Assessment Date', assessment_date),
            ('Authorizer/OT', self.authorizer_id.name if self.authorizer_id else None),
            ('Sales Rep', self.sales_rep_id.name if self.sales_rep_id else None),
        ]
        if self.client_type:
            ct_labels = {
                'reg': 'REG - Regular ADP',
                'ods': 'ODS - ODSP',
                'acs': 'ACS - ACSD',
                'owp': 'OWP - Ontario Works',
            }
            overview_rows.append(('Client Type', ct_labels.get(self.client_type, self.client_type)))
        if self.reason_for_application:
            reason_labels = dict(self._fields['reason_for_application'].selection)
            overview_rows.append(('Reason for Application', reason_labels.get(
                self.reason_for_application, self.reason_for_application)))
        if self.previous_funding_date:
            overview_rows.append(('Previous Funding Date', str(self.previous_funding_date)))
        sections.append(('Assessment Overview', overview_rows))

        # --- Section 2: Client Information ---
        client_rows = [
            ('Name', self.client_name),
        ]
        if self.client_first_name or self.client_last_name:
            full = f"{self.client_first_name or ''} {self.client_middle_name or ''} {self.client_last_name or ''}".strip()
            client_rows.append(('Full Name', full))
        if self.client_weight:
            client_rows.append(('Weight', f'{int(self.client_weight)} lbs'))
        if self.client_dob:
            client_rows.append(('Date of Birth', str(self.client_dob)))
        if self.client_health_card:
            version = f' ({self.client_health_card_version})' if self.client_health_card_version else ''
            client_rows.append(('Health Card', f'{self.client_health_card}{version}'))
        # Address
        addr_parts = [p for p in [
            self.client_street, self.client_unit, self.client_city,
            self.client_state, self.client_postal_code,
        ] if p]
        if addr_parts:
            client_rows.append(('Address', ', '.join(addr_parts)))
        if self.client_phone:
            client_rows.append(('Phone', self.client_phone))
        if self.client_mobile:
            client_rows.append(('Mobile', self.client_mobile))
        if self.client_email:
            client_rows.append(('Email', self.client_email))
        sections.append(('Client Information', client_rows))

        # --- Section 3: Equipment Type & Subtype ---
        equip_rows = [('Equipment Type', equipment_label)]

        if self.equipment_type == 'rollator':
            if self.rollator_type:
                type_labels = dict(self._fields['rollator_type'].selection)
                equip_rows.append(('Rollator Type', type_labels.get(self.rollator_type, self.rollator_type)))
        elif self.equipment_type == 'wheelchair':
            if self.wheelchair_type:
                type_labels = dict(self._fields['wheelchair_type'].selection)
                equip_rows.append(('Wheelchair Type', type_labels.get(self.wheelchair_type, self.wheelchair_type)))
        elif self.equipment_type == 'powerchair':
            if self.powerchair_type:
                type_labels = dict(self._fields['powerchair_type'].selection)
                equip_rows.append(('Powerchair Type', type_labels.get(self.powerchair_type, self.powerchair_type)))

        sections.append(('Equipment Selection', equip_rows))

        # --- Section 4: Measurements ---
        meas_rows = []
        if self.equipment_type == 'rollator':
            if self.rollator_handle_height:
                meas_rows.append(('Handle Height', f'{self.rollator_handle_height}"'))
            if self.rollator_seat_height:
                meas_rows.append(('Seat Height', f'{self.rollator_seat_height}"'))
        else:
            # Wheelchair / Powerchair measurements
            if self.seat_width:
                meas_rows.append(('Seat Width', f'{self.seat_width}"'))
            if self.seat_depth:
                meas_rows.append(('Seat Depth', f'{self.seat_depth}"'))
            if self.legrest_length:
                meas_rows.append(('Legrest Length', f'{self.legrest_length}"'))
            if self.seat_to_floor_height:
                sfh_label = f'{self.seat_to_floor_height}" (Including Cushion)' if self.equipment_type == 'wheelchair' else f'{self.seat_to_floor_height}"'
                meas_rows.append(('Seat to Floor Height', sfh_label))
            if self.cane_height:
                meas_rows.append(('Cane Height', f'{self.cane_height}" (Ground to Canes)'))
            if self.back_height:
                meas_rows.append(('Back Height', f'{self.back_height}"'))
            if self.armrest_height:
                meas_rows.append(('Armrest Height', f'{self.armrest_height}"'))
            if self.footrest_length:
                meas_rows.append(('Footrest Length', f'{self.footrest_length}"'))
        if meas_rows:
            sections.append(('Measurements', meas_rows))

        # --- Section 5: Options & Addons ---
        options_rows = []
        if self.equipment_type == 'rollator' and self.rollator_addons:
            for addon in self.rollator_addons.split(','):
                addon = addon.strip()
                if addon:
                    options_rows.append((addon, 'Yes'))
        elif self.equipment_type == 'wheelchair':
            if self.frame_options:
                for opt in self.frame_options.split(','):
                    opt = opt.strip()
                    if opt:
                        options_rows.append((f'Frame: {opt}', 'Yes'))
            if self.wheel_options:
                for opt in self.wheel_options.split(','):
                    opt = opt.strip()
                    if opt:
                        options_rows.append((f'Wheel: {opt}', 'Yes'))
            if self.legrest_options:
                for opt in self.legrest_options.split(','):
                    opt = opt.strip()
                    if opt:
                        options_rows.append((f'Legrest: {opt}', 'Yes'))
            if self.additional_adp_options:
                for opt in self.additional_adp_options.split(','):
                    opt = opt.strip()
                    if opt:
                        options_rows.append((f'ADP Option: {opt}', 'Yes'))
        elif self.equipment_type == 'powerchair':
            if self.powerchair_options:
                for opt in self.powerchair_options.split(','):
                    opt = opt.strip()
                    if opt:
                        options_rows.append((f'Powerchair: {opt}', 'Yes'))
            if self.specialty_controls:
                for opt in self.specialty_controls.split(','):
                    opt = opt.strip()
                    if opt:
                        options_rows.append((f'Specialty: {opt}', 'Yes'))

        # Seatbelt (wheelchair & powerchair)
        if self.seatbelt_type and self.equipment_type in ('wheelchair', 'powerchair'):
            belt_labels = dict(self._fields['seatbelt_type'].selection)
            options_rows.append(('Seat Belt', belt_labels.get(self.seatbelt_type, self.seatbelt_type)))

        # Cushion & Backrest
        if self.cushion_info:
            options_rows.append(('Cushion', self.cushion_info))
        if self.backrest_info:
            options_rows.append(('Backrest', self.backrest_info))

        if options_rows:
            sections.append(('Options & Accessories', options_rows))

        # --- Section 6: Additional Notes ---
        notes_rows = []
        if self.additional_customization:
            notes_rows.append(('Customization', self.additional_customization))
        if self.mobility_notes:
            notes_rows.append(('Mobility Needs', self.mobility_notes))
        if self.accessibility_notes:
            notes_rows.append(('Accessibility', self.accessibility_notes))
        if self.special_requirements:
            notes_rows.append(('Special Requirements', self.special_requirements))
        if self.diagnosis:
            notes_rows.append(('Diagnosis/Condition', self.diagnosis))
        if notes_rows:
            sections.append(('Additional Notes', notes_rows))

        # --- Section 7: Key Dates ---
        date_rows = []
        if self.assessment_start_date:
            date_rows.append(('Assessment Start', self.assessment_start_date.strftime('%B %d, %Y')))
        if self.assessment_end_date:
            date_rows.append(('Assessment End', self.assessment_end_date.strftime('%B %d, %Y')))
        if self.claim_authorization_date:
            date_rows.append(('Claim Authorization', self.claim_authorization_date.strftime('%B %d, %Y')))
        if date_rows:
            sections.append(('Key Dates', date_rows))

        # --- Section 8: Consent Information ---
        if self.consent_signed_by:
            consent_rows = []
            consent_label = 'Applicant' if self.consent_signed_by == 'applicant' else 'Agent'
            consent_rows.append(('Signed By', consent_label))
            if self.consent_date:
                consent_rows.append(('Consent Date', str(self.consent_date)))
            if self.consent_declaration_accepted:
                consent_rows.append(('Declaration Accepted', 'Yes'))
            if self.consent_signed_by == 'agent':
                agent_name = f"{self.agent_first_name or ''} {self.agent_last_name or ''}".strip()
                if agent_name:
                    consent_rows.append(('Agent Name', agent_name))
                if self.agent_relationship:
                    rel_labels = dict(self._fields['agent_relationship'].selection)
                    consent_rows.append(('Relationship', rel_labels.get(
                        self.agent_relationship, self.agent_relationship)))
            sections.append(('Consent & Declaration (Page 11)', consent_rows))

        return sections

    def _format_assessment_html_table(self):
        """Format assessment data as HTML table for chatter"""
        self.ensure_one()
        
        # Get equipment type display name
        equipment_labels = {
            'rollator': 'Rollator',
            'wheelchair': 'Wheelchair',
            'powerchair': 'Powerchair',
        }
        equipment_display = equipment_labels.get(self.equipment_type, 'Unknown')
        
        # Start building HTML
        html = f'''
        <h3 style="color: #875A7B; margin-bottom: 10px;">ADP Assessment - {equipment_display}</h3>
        <table style="border-collapse: collapse; width: 100%; font-size: 13px;">
            <tr style="background: #875A7B; color: white;">
                <th style="border: 1px solid #ddd; padding: 8px; text-align: left; width: 40%;">Field</th>
                <th style="border: 1px solid #ddd; padding: 8px; text-align: left;">Value</th>
            </tr>
        '''
        
        row_num = 0
        def add_row(label, value, is_header=False):
            nonlocal html, row_num
            if is_header:
                html += f'''
                <tr style="background: #e8f4e8;">
                    <td colspan="2" style="border: 1px solid #ddd; padding: 8px;"><strong>{label}</strong></td>
                </tr>
                '''
            else:
                bg = '#f9f9f9' if row_num % 2 == 0 else '#ffffff'
                html += f'''
                <tr style="background: {bg};">
                    <td style="border: 1px solid #ddd; padding: 8px;">{label}</td>
                    <td style="border: 1px solid #ddd; padding: 8px;">{value}</td>
                </tr>
                '''
                row_num += 1
        
        # Client Type
        if self.client_type:
            client_type_labels = {
                'reg': 'REG - Regular ADP',
                'ods': 'ODS - ODSP',
                'acs': 'ACS - ACSD',
                'owp': 'OWP - Ontario Works',
            }
            add_row('Client Type', client_type_labels.get(self.client_type, self.client_type))
        
        # Equipment Type
        add_row('Equipment Type', equipment_display)
        
        # Client Weight - shown prominently at the top
        if self.client_weight:
            add_row('Client Weight', f'{int(self.client_weight)} lbs')
        
        # Type-specific info
        if self.equipment_type == 'rollator':
            if self.rollator_type:
                type_labels = dict(self._fields['rollator_type'].selection)
                add_row('Rollator Type', type_labels.get(self.rollator_type, self.rollator_type))
            
            add_row('Measurements', '', is_header=True)
            if self.rollator_handle_height:
                add_row('Handle Height', f'{self.rollator_handle_height}"')
            if self.rollator_seat_height:
                add_row('Seat Height', f'{self.rollator_seat_height}"')
            
            if self.rollator_addons:
                add_row('Addons', '', is_header=True)
                for addon in self.rollator_addons.split(','):
                    addon = addon.strip()
                    if addon:
                        add_row(addon, 'Yes')
        
        elif self.equipment_type == 'wheelchair':
            if self.wheelchair_type:
                type_labels = dict(self._fields['wheelchair_type'].selection)
                add_row('Wheelchair Type', type_labels.get(self.wheelchair_type, self.wheelchair_type))
            
            add_row('Measurements', '', is_header=True)
            if self.seat_width:
                add_row('Seat Width', f'{self.seat_width}"')
            if self.seat_depth:
                add_row('Seat Depth', f'{self.seat_depth}"')
            if self.legrest_length:
                add_row('Legrest Length', f'{self.legrest_length}"')
            if self.seat_to_floor_height:
                add_row('Seat to Floor Height', f'{self.seat_to_floor_height}" (Including Cushion)')
            if self.cane_height:
                add_row('Cane Height', f'{self.cane_height}" (Ground to Canes)')
            if self.back_height:
                add_row('Back Height', f'{self.back_height}"')
            
            if self.frame_options:
                add_row('Frame Options - ADP Funded', '', is_header=True)
                for opt in self.frame_options.split(','):
                    opt = opt.strip()
                    if opt:
                        add_row(opt, 'Yes')
            
            if self.wheel_options:
                add_row('Wheel Options/Addons - ADP Funded', '', is_header=True)
                for opt in self.wheel_options.split(','):
                    opt = opt.strip()
                    if opt:
                        add_row(opt, 'Yes')
            
            if self.legrest_options:
                add_row('Legrest Accessories - ADP Funded', '', is_header=True)
                for opt in self.legrest_options.split(','):
                    opt = opt.strip()
                    if opt:
                        add_row(opt, 'Yes')
            
            if self.additional_adp_options:
                add_row('Additional ADP Funded Options', '', is_header=True)
                for opt in self.additional_adp_options.split(','):
                    opt = opt.strip()
                    if opt:
                        add_row(opt, 'Yes')
            
            if self.seatbelt_type:
                belt_labels = dict(self._fields['seatbelt_type'].selection)
                add_row('Seat Belt Type', belt_labels.get(self.seatbelt_type, self.seatbelt_type))
        
        elif self.equipment_type == 'powerchair':
            if self.powerchair_type:
                type_labels = dict(self._fields['powerchair_type'].selection)
                add_row('Powerchair Type', type_labels.get(self.powerchair_type, self.powerchair_type))
            
            add_row('Measurements', '', is_header=True)
            if self.seat_width:
                add_row('Seat Width', f'{self.seat_width}"')
            if self.seat_depth:
                add_row('Seat Depth', f'{self.seat_depth}"')
            if self.legrest_length:
                add_row('Legrest Length', f'{self.legrest_length}"')
            if self.seat_to_floor_height:
                add_row('Seat to Floor Height', f'{self.seat_to_floor_height}"')
            if self.cane_height:
                add_row('Cane Height', f'{self.cane_height}" (Ground to Canes)')
            if self.back_height:
                add_row('Back Height', f'{self.back_height}"')
            if self.armrest_height:
                add_row('Armrest Height', f'{self.armrest_height}"')
            if self.footrest_length:
                add_row('Footrest Length', f'{self.footrest_length}"')
            
            if self.seatbelt_type:
                belt_labels = dict(self._fields['seatbelt_type'].selection)
                add_row('Seat Belt Type', belt_labels.get(self.seatbelt_type, self.seatbelt_type))
            
            if self.powerchair_options:
                add_row('Powerchair - Additional ADP Funded Options', '', is_header=True)
                for opt in self.powerchair_options.split(','):
                    opt = opt.strip()
                    if opt:
                        add_row(opt, 'Yes')
            
            if self.specialty_controls:
                add_row('Specialty Components (Rationale Required)', '', is_header=True)
                for opt in self.specialty_controls.split(','):
                    opt = opt.strip()
                    if opt:
                        add_row(opt, 'Yes')
        
        # Cushion & Backrest (wheelchair/powerchair)
        if self.cushion_info:
            add_row('Cushion', self.cushion_info)
        if self.backrest_info:
            add_row('Backrest', self.backrest_info)
        
        # Additional customization notes
        if self.additional_customization:
            add_row('Additional Information/Customization', self.additional_customization)
        
        # Client info summary
        add_row('Client Information', '', is_header=True)
        add_row('Client Name', self.client_name or '')
        if self.client_weight:
            add_row('Client Weight', f'{int(self.client_weight)} lbs')
        if self.client_health_card:
            version = f' ({self.client_health_card_version})' if self.client_health_card_version else ''
            add_row('Health Card', f'{self.client_health_card}{version}')
        if self.client_phone:
            add_row('Phone', self.client_phone)
        if self.client_email:
            add_row('Email', self.client_email)
        
        # Dates
        add_row('Key Dates', '', is_header=True)
        if self.assessment_start_date:
            add_row('Assessment Start Date', str(self.assessment_start_date))
        if self.assessment_end_date:
            add_row('Assessment End Date', str(self.assessment_end_date))
        if self.claim_authorization_date:
            add_row('Claim Authorization Date', str(self.claim_authorization_date))
        
        if self.reason_for_application:
            reason_labels = dict(self._fields['reason_for_application'].selection)
            add_row('Reason for Application', reason_labels.get(self.reason_for_application, self.reason_for_application))
        
        html += '</table>'
        return html

    def _format_specifications_for_order(self):
        """Format wheelchair specifications for the sale order notes (legacy)"""
        self.ensure_one()
        
        lines = [
            f"=== Assessment Specifications ({self.reference}) ===",
            "",
            "MEASUREMENTS:",
        ]
        
        if self.seat_width:
            lines.append(f"  Seat Width: {self.seat_width}\"")
        if self.seat_depth:
            lines.append(f"  Seat Depth: {self.seat_depth}\"")
        if self.seat_to_floor_height:
            lines.append(f"  Seat to Floor: {self.seat_to_floor_height}\"")
        if self.back_height:
            lines.append(f"  Back Height: {self.back_height}\"")
        if self.armrest_height:
            lines.append(f"  Armrest Height: {self.armrest_height}\"")
        if self.footrest_length:
            lines.append(f"  Footrest Length: {self.footrest_length}\"")
        
        lines.append("")
        lines.append("PRODUCT SELECTIONS:")
        
        if self.cushion_type:
            lines.append(f"  Cushion: {dict(self._fields['cushion_type'].selection).get(self.cushion_type, self.cushion_type)}")
        if self.backrest_type:
            lines.append(f"  Backrest: {dict(self._fields['backrest_type'].selection).get(self.backrest_type, self.backrest_type)}")
        if self.frame_type:
            lines.append(f"  Frame: {dict(self._fields['frame_type'].selection).get(self.frame_type, self.frame_type)}")
        if self.wheel_type:
            lines.append(f"  Wheels: {dict(self._fields['wheel_type'].selection).get(self.wheel_type, self.wheel_type)}")
        
        if self.mobility_notes:
            lines.append("")
            lines.append("MOBILITY NEEDS:")
            lines.append(f"  {self.mobility_notes}")
        
        if self.accessibility_notes:
            lines.append("")
            lines.append("ACCESSIBILITY NOTES:")
            lines.append(f"  {self.accessibility_notes}")
        
        if self.special_requirements:
            lines.append("")
            lines.append("SPECIAL REQUIREMENTS:")
            lines.append(f"  {self.special_requirements}")
        
        return "\n".join(lines)

    def _generate_signed_documents(self):
        """Generate document records for signed pages"""
        self.ensure_one()
        
        ADPDocument = self.env['fusion.adp.document'].sudo()
        
        # Create Page 11 document if signature exists
        if self.signature_page_11:
            ADPDocument.create({
                'assessment_id': self.id,
                'sale_order_id': self.sale_order_id.id if self.sale_order_id else False,
                'document_type': 'page_11',
                'file': self.signature_page_11,
                'filename': f'page_11_signature_{self.reference}.png',
                'mimetype': 'image/png',
                'source': 'assessment',
            })
        
        # Create Page 12 document if signature exists
        if self.signature_page_12:
            ADPDocument.create({
                'assessment_id': self.id,
                'sale_order_id': self.sale_order_id.id if self.sale_order_id else False,
                'document_type': 'page_12',
                'file': self.signature_page_12,
                'filename': f'page_12_signature_{self.reference}.png',
                'mimetype': 'image/png',
                'source': 'assessment',
            })

    def _send_completion_notifications(self):
        """Send email notifications when assessment is completed"""
        self.ensure_one()
        
        # Send to authorizer
        if self.authorizer_id and self.authorizer_id.email:
            try:
                template = self.env.ref('fusion_authorizer_portal.mail_template_assessment_complete_authorizer', raise_if_not_found=False)
                if template:
                    template.send_mail(self.id, force_send=True)
                    _logger.info(f"Sent assessment completion email to authorizer {self.authorizer_id.email}")
            except Exception as e:
                _logger.error(f"Failed to send authorizer notification: {e}")
        
        # Send to client
        if self.client_email:
            try:
                template = self.env.ref('fusion_authorizer_portal.mail_template_assessment_complete_client', raise_if_not_found=False)
                if template:
                    template.send_mail(self.id, force_send=True)
                    _logger.info(f"Sent assessment completion email to client {self.client_email}")
            except Exception as e:
                _logger.error(f"Failed to send client notification: {e}")

    def action_view_documents(self):
        """View related documents"""
        self.ensure_one()
        return {
            'type': 'ir.actions.act_window',
            'name': _('Documents'),
            'res_model': 'fusion.adp.document',
            'view_mode': 'list,form',
            'views': [(False, 'list'), (False, 'form')],
            'domain': [('assessment_id', '=', self.id)],
            'context': {'default_assessment_id': self.id},
        }

    def action_view_sale_order(self):
        """View the created sale order"""
        self.ensure_one()
        if not self.sale_order_id:
            raise UserError(_('No sale order has been created yet.'))
        return {
            'type': 'ir.actions.act_window',
            'name': _('Sale Order'),
            'res_model': 'sale.order',
            'res_id': self.sale_order_id.id,
            'view_mode': 'form',
            'views': [(False, 'form')],
            'target': 'current',
        }

    # ===== PDF TEMPLATE ENGINE INTEGRATION =====

    def _get_pdf_context(self):
        """Return a flat dict of all assessment data for PDF template filling.

        This is the data source for the generic PDF template engine.
        Each key can be mapped to a field on any PDF template via field_key.
        """
        self.ensure_one()

        ctx = {
            # Client biographical
            'client_last_name': self.client_last_name or '',
            'client_first_name': self.client_first_name or '',
            'client_middle_name': self.client_middle_name or '',
            'client_name': self.client_name or '',
            'client_health_card': self.client_health_card or '',
            'client_health_card_version': self.client_health_card_version or '',
            'client_street': self.client_street or '',
            'client_unit': self.client_unit or '',
            'client_city': self.client_city or '',
            'client_state': self.client_state or '',
            'client_postal_code': self.client_postal_code or '',
            'client_phone': self.client_phone or '',
            'client_email': self.client_email or '',
            'client_weight': str(int(self.client_weight)) if self.client_weight else '',

            # Client type
            'client_type': self.client_type or '',
            'client_type_reg': self.client_type == 'reg',
            'client_type_ods': self.client_type == 'ods',
            'client_type_acs': self.client_type == 'acs',
            'client_type_owp': self.client_type == 'owp',

            # Consent & Declaration (Page 11)
            'consent_signed_by': self.consent_signed_by or '',
            'consent_applicant': self.consent_signed_by == 'applicant',
            'consent_agent': self.consent_signed_by == 'agent',
            'consent_declaration_accepted': self.consent_declaration_accepted,
            'consent_date': str(self.consent_date) if self.consent_date else '',

            # Agent info
            'agent_relationship': self.agent_relationship or '',
            'agent_rel_spouse': self.agent_relationship == 'spouse',
            'agent_rel_parent': self.agent_relationship == 'parent',
            'agent_rel_child': self.agent_relationship == 'child',
            'agent_rel_poa': self.agent_relationship == 'power_of_attorney',
            'agent_rel_guardian': self.agent_relationship == 'public_guardian',
            'agent_first_name': self.agent_first_name or '',
            'agent_last_name': self.agent_last_name or '',
            'agent_middle_initial': self.agent_middle_initial or '',
            'agent_unit': self.agent_unit or '',
            'agent_street_number': self.agent_street_number or '',
            'agent_street_name': self.agent_street_name or '',
            'agent_city': self.agent_city or '',
            'agent_province': self.agent_province or '',
            'agent_postal_code': self.agent_postal_code or '',
            'agent_home_phone': self.agent_home_phone or '',
            'agent_business_phone': self.agent_business_phone or '',
            'agent_phone_ext': self.agent_phone_ext or '',

            # Equipment
            'equipment_type': self.equipment_type or '',
            'seat_width': str(self.seat_width) if self.seat_width else '',
            'seat_depth': str(self.seat_depth) if self.seat_depth else '',
            'seat_to_floor_height': str(self.seat_to_floor_height) if self.seat_to_floor_height else '',
            'back_height': str(self.back_height) if self.back_height else '',
            'legrest_length': str(self.legrest_length) if self.legrest_length else '',
            'cane_height': str(self.cane_height) if self.cane_height else '',

            # Dates
            'assessment_start_date': str(self.assessment_start_date) if self.assessment_start_date else '',
            'assessment_end_date': str(self.assessment_end_date) if self.assessment_end_date else '',
            'claim_authorization_date': str(self.claim_authorization_date) if self.claim_authorization_date else '',

            # Reason
            'reason_for_application': self.reason_for_application or '',

            # Reference
            'reference': self.reference or '',
        }

        # Authorizer info
        if self.authorizer_id:
            ctx['authorizer_name'] = self.authorizer_id.name or ''
            ctx['authorizer_phone'] = self.authorizer_id.phone or ''
            ctx['authorizer_email'] = self.authorizer_id.email or ''

        return ctx

    def _get_pdf_signatures(self):
        """Return a dict of signature binaries for PDF template filling."""
        self.ensure_one()
        sigs = {}
        if self.signature_page_11:
            sigs['signature_page_11'] = base64.b64decode(self.signature_page_11)
        if self.signature_page_12:
            sigs['signature_page_12'] = base64.b64decode(self.signature_page_12)
        return sigs

    def generate_template_pdf(self, template_name='adp_page_11'):
        """Generate a filled PDF using the named template.

        Args:
            template_name: the name field of the fusion.pdf.template record

        Returns:
            bytes of the filled PDF, or None if template not found
        """
        self.ensure_one()

        template = self.env['fusion.pdf.template'].search([
            ('state', '=', 'active'),
            ('name', 'ilike', template_name),
        ], limit=1)

        if not template:
            _logger.warning("No active PDF template found matching '%s'", template_name)
            return None

        context_data = self._get_pdf_context()
        signatures = self._get_pdf_signatures()

        try:
            pdf_bytes = template.generate_filled_pdf(context_data, signatures)
            _logger.info("Generated filled PDF from template '%s' for assessment %s",
                        template.name, self.reference)
            return pdf_bytes
        except Exception as e:
            _logger.error("Failed to generate PDF for assessment %s: %s", self.reference, e)
            return None
