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

import base64
import json
import logging
import xml.etree.ElementTree as ET

from odoo import api, fields, models

_logger = logging.getLogger(__name__)


class FusionAdpApplicationData(models.Model):
    _name = 'fusion.adp.application.data'
    _description = 'ADP Application Data (Parsed XML)'
    _order = 'application_date desc, id desc'
    _rec_name = 'display_name'

    # ------------------------------------------------------------------
    # LINKAGE
    # ------------------------------------------------------------------
    profile_id = fields.Many2one(
        'fusion.client.profile', string='Client Profile',
        ondelete='cascade', index=True,
    )
    sale_order_id = fields.Many2one(
        'sale.order', string='Sale Order',
        ondelete='set null', index=True,
    )
    display_name = fields.Char(
        string='Name', compute='_compute_display_name', store=True,
    )

    # ------------------------------------------------------------------
    # COMPLETE XML DATA (for round-trip export fidelity)
    # ------------------------------------------------------------------
    xml_data_json = fields.Text(
        string='Complete XML Data (JSON)',
        help='Complete 1:1 JSON representation of all ~300 XML fields for export',
    )
    raw_xml = fields.Text(string='Raw XML Data')

    # ------------------------------------------------------------------
    # APPLICATION METADATA
    # ------------------------------------------------------------------
    device_category = fields.Selection([
        ('AA', 'Ambulation Aids (Section 2a)'),
        ('MD', 'Mobility Devices (Section 2b/2c)'),
        ('PS', 'Positioning/Seating (Section 2d)'),
        ('MX', 'Mixed/Multiple Sections'),
    ], string='Device Category')
    version_number = fields.Char(string='Form Version')
    application_date = fields.Date(string='Application Date')

    # ------------------------------------------------------------------
    # SECTION 1 - APPLICANT BIOGRAPHICAL INFORMATION
    # ------------------------------------------------------------------
    applicant_last_name = fields.Char(string='Last Name')
    applicant_first_name = fields.Char(string='First Name')
    applicant_middle_initial = fields.Char(string='Middle Initial')
    health_card_number = fields.Char(string='Health Card Number', index=True)
    health_card_version = fields.Char(string='Health Card Version')
    date_of_birth = fields.Date(string='Date of Birth')
    ltch_name = fields.Char(string='Long-Term Care Home')

    # Address (individual fields, not combined)
    unit_number = fields.Char(string='Unit Number')
    street_number = fields.Char(string='Street Number')
    street_name = fields.Char(string='Street Name')
    rural_route = fields.Char(string='Lot/Concession/Rural Route')
    city = fields.Char(string='City', index=True)
    province = fields.Char(string='Province')
    postal_code = fields.Char(string='Postal Code')

    # Contact
    home_phone = fields.Char(string='Home Phone')
    business_phone = fields.Char(string='Business Phone')
    phone_extension = fields.Char(string='Phone Extension')

    # ------------------------------------------------------------------
    # SECTION 1 - CONFIRMATION OF BENEFITS
    # ------------------------------------------------------------------
    receives_social_assistance = fields.Boolean(string='Receives Social Assistance')
    benefit_type = fields.Char(string='Benefit Program')
    benefit_owp = fields.Boolean(string='Ontario Works Program (OWP)')
    benefit_odsp = fields.Boolean(string='Ontario Disability Support Program (ODSP)')
    benefit_acsd = fields.Boolean(string='Assistance to Children with Severe Disabilities (ACSD)')
    wsib_eligible = fields.Boolean(string='WSIB Eligible')
    vac_eligible = fields.Boolean(string='Veterans Affairs Canada (VAC) Eligible')

    # ------------------------------------------------------------------
    # SECTION 2 - DEVICES AND ELIGIBILITY
    # ------------------------------------------------------------------
    medical_condition = fields.Text(string='Medical Condition / Diagnosis')
    mobility_status = fields.Text(string='Functional Mobility Status')

    # Previously funded equipment
    prev_funded_none = fields.Boolean(string='None Previously Funded')
    prev_funded_forearm = fields.Boolean(string='Forearm Crutches (Previously)')
    prev_funded_wheeled = fields.Boolean(string='Wheeled Walker (Previously)')
    prev_funded_manual = fields.Boolean(string='Manual Wheelchair (Previously)')
    prev_funded_power = fields.Boolean(string='Power Wheelchair (Previously)')
    prev_funded_addon = fields.Boolean(string='Power Add-On Device (Previously)')
    prev_funded_scooter = fields.Boolean(string='Power Scooter (Previously)')
    prev_funded_seating = fields.Boolean(string='Positioning Devices (Previously)')
    prev_funded_tilt = fields.Boolean(string='Power Tilt System (Previously)')
    prev_funded_recline = fields.Boolean(string='Power Recline System (Previously)')
    prev_funded_legrests = fields.Boolean(string='Power Elevating Leg Rests (Previously)')
    prev_funded_frame = fields.Boolean(string='Paediatric Standing Frame (Previously)')
    prev_funded_stroller = fields.Boolean(string='Paediatric Specialty Stroller (Previously)')

    # Devices currently required
    device_forearm_crutches = fields.Boolean(string='Forearm Crutches')
    device_wheeled_walker = fields.Boolean(string='Wheeled Walker')
    device_manual_wheelchair = fields.Boolean(string='Manual Wheelchair')
    device_ambulation_manual = fields.Boolean(string='Ambulation Aid + Manual Wheelchair')
    device_dependent_wheelchair = fields.Boolean(string='Manual Wheelchair (Dependent)')
    device_dynamic_tilt = fields.Boolean(string='Manual Dynamic Tilt Wheelchair')
    device_manual_dynamic = fields.Boolean(string='Manual Dynamic Tilt (Dependent)')
    device_manual_power_addon = fields.Boolean(string='Manual Wheelchair with Power Add-On')
    device_power_base = fields.Boolean(string='Power Base Only')
    device_power_scooter = fields.Boolean(string='Power Scooter Only')
    device_ambulation_power = fields.Boolean(string='Ambulation Aid + Power Base/Scooter')
    device_positioning = fields.Boolean(string='Positioning Devices (Seating)')
    device_high_tech = fields.Boolean(string='High Technology Power Base')
    device_standing_frame = fields.Boolean(string='Paediatric Standing Frame')
    device_adp_funded_mods = fields.Boolean(string='Modifications to ADP Funded Device(s)')
    device_non_adp_funded_mods = fields.Boolean(string='Modifications to Non ADP Funded Device(s)')

    # ------------------------------------------------------------------
    # SECTION 2A - AMBULATION AIDS (Walkers)
    # ------------------------------------------------------------------
    s2a_base_device = fields.Char(string='Walker Type')
    s2a_paediatric_frame = fields.Char(string='Paediatric Frame')
    s2a_forearm_crutches = fields.Char(string='Forearm Crutches Type')
    s2a_none = fields.Char(string='None Selected')
    s2a_reason = fields.Char(string='Reason for Application')
    s2a_replacement_status = fields.Char(string='Replacement - Mobility Status Change')
    s2a_replacement_size = fields.Char(string='Replacement - Body Size Change')
    s2a_replacement_adp = fields.Char(string='Replacement - Equipment Worn Out')
    s2a_replacement_special = fields.Char(string='Replacement - Special Circumstances')
    s2a_confirm1 = fields.Char(string='Confirmation 1')
    s2a_confirm2 = fields.Char(string='Confirmation 2')
    s2a_confirm3 = fields.Char(string='Confirmation 3')
    s2a_confirm4 = fields.Char(string='Confirmation 4')
    s2a_confirm5 = fields.Char(string='Confirmation 5')
    s2a_confirm6 = fields.Char(string='Confirmation 6')
    # Prescription
    s2a_seat_height = fields.Char(string='Seat Height')
    s2a_seat_height_unit = fields.Char(string='Seat Height Unit')
    s2a_handle_height = fields.Char(string='Push Handle Height')
    s2a_handle_height_unit = fields.Char(string='Handle Height Unit')
    s2a_hand_grips = fields.Char(string='Hand Grips')
    s2a_forearm_attachments = fields.Char(string='Forearm Attachments')
    s2a_width_handles = fields.Char(string='Width Between Push Handles')
    s2a_width_handles_unit = fields.Char(string='Width Handles Unit')
    s2a_client_weight = fields.Char(string='Client Weight')
    s2a_client_weight_unit = fields.Char(string='Client Weight Unit')
    s2a_brakes = fields.Char(string='Brakes')
    s2a_brake_type = fields.Char(string='Brake Type')
    s2a_num_wheels = fields.Char(string='Number of Wheels')
    s2a_wheel_size = fields.Char(string='Wheel Size')
    s2a_back_support = fields.Char(string='Back Support')
    # ADP options
    s2a_adp_walker = fields.Char(string='ADP Adolescent Walker')
    s2a_adp_frame = fields.Char(string='ADP Adolescent Frame')
    s2a_adp_standing = fields.Char(string='ADP Adolescent Standing')
    # Custom modifications
    s2a_custom = fields.Char(string='Custom Modifications Required')
    s2a_cost_labour = fields.Char(string='Cost of Labour')

    # ------------------------------------------------------------------
    # SECTION 2B - MANUAL WHEELCHAIRS
    # ------------------------------------------------------------------
    s2b_base_device = fields.Char(string='Manual Wheelchair Type')
    s2b_power_addon = fields.Char(string='Power Add-On Device')
    s2b_reason = fields.Char(string='Reason for Application')
    s2b_replacement_status = fields.Char(string='Replacement - Mobility Status')
    s2b_replacement_size = fields.Char(string='Replacement - Body Size')
    s2b_replacement_adp = fields.Char(string='Replacement - Equipment Worn')
    s2b_replacement_special = fields.Char(string='Replacement - Special')
    s2b_confirm1 = fields.Char(string='Confirmation 1')
    s2b_confirm2 = fields.Char(string='Confirmation 2')
    s2b_confirm3 = fields.Char(string='Confirmation 3')
    s2b_confirm4 = fields.Char(string='Confirmation 4')
    s2b_confirm5 = fields.Char(string='Confirmation 5')
    s2b_confirm6 = fields.Char(string='Confirmation 6')
    s2b_confirm7 = fields.Char(string='Confirmation 7')
    s2b_confirm8 = fields.Char(string='Confirmation 8')
    s2b_confirm9 = fields.Char(string='Confirmation 9')
    s2b_confirm10 = fields.Char(string='Confirmation 10')
    s2b_confirm11 = fields.Char(string='Confirmation 11')
    s2b_confirm12 = fields.Char(string='Confirmation 12')
    s2b_confirm13 = fields.Char(string='Confirmation 13')
    # Prescription
    s2b_seat_width = fields.Char(string='Seat Width')
    s2b_seat_width_unit = fields.Char(string='Seat Width Unit')
    s2b_seat_depth = fields.Char(string='Seat Depth')
    s2b_seat_depth_unit = fields.Char(string='Seat Depth Unit')
    s2b_floor_height = fields.Char(string='Finished Seat to Floor Height')
    s2b_floor_height_unit = fields.Char(string='Floor Height Unit')
    s2b_cane_height = fields.Char(string='Back Cane Height')
    s2b_cane_height_unit = fields.Char(string='Cane Height Unit')
    s2b_back_height = fields.Char(string='Finished Back Height')
    s2b_back_height_unit = fields.Char(string='Back Height Unit')
    s2b_rest_length = fields.Char(string='Finished Leg Rest Length')
    s2b_rest_length_unit = fields.Char(string='Rest Length Unit')
    s2b_client_weight = fields.Char(string='Client Weight')
    s2b_client_weight_unit = fields.Char(string='Client Weight Unit')
    # Add-on options
    s2b_adjustable_tension = fields.Boolean(string='Adjustable Tension Back Upholstery')
    s2b_heavy_duty = fields.Boolean(string='Heavy Duty Cross Braces & Upholstery')
    s2b_recliner = fields.Boolean(string='Recliner Option')
    s2b_footplates = fields.Boolean(string='Angle Adjustable Footplates')
    s2b_legrests = fields.Boolean(string='Elevating Legrests')
    s2b_spoke = fields.Boolean(string='Spoke Protectors')
    s2b_projected = fields.Boolean(string='Projected Handrims')
    s2b_standard_manual = fields.Boolean(string='Standard Manual with Dynamic Tilt')
    s2b_grade_aids = fields.Boolean(string='Grade Aids')
    s2b_caster_pin = fields.Boolean(string='Caster Pin Locks')
    s2b_amputee_axle = fields.Boolean(string='Amputee Axle Plates')
    s2b_quick_release = fields.Boolean(string='Quick Release Axles')
    s2b_stroller = fields.Boolean(string='Stroller Handles/Paediatric')
    s2b_oxygen = fields.Boolean(string='Oxygen Tank Holder')
    s2b_ventilator = fields.Boolean(string='Ventilator Tray')
    s2b_titanium = fields.Boolean(string='Titanium Frame')
    s2b_clothing_guards = fields.Boolean(string='Clothing Guards')
    s2b_one_arm = fields.Boolean(string='One Arm/Lever Drive')
    s2b_uni_lateral = fields.Boolean(string='Uni-Lateral Wheel Lock')
    s2b_plastic = fields.Boolean(string='Plastic Coated Handrims')
    s2b_rationale = fields.Text(string='Clinical Rationale')
    s2b_custom = fields.Char(string='Custom Modifications Required')
    s2b_cost_labour = fields.Char(string='Cost of Labour')

    # ------------------------------------------------------------------
    # SECTION 2C - POWER BASES AND POWER SCOOTERS
    # ------------------------------------------------------------------
    s2c_base_device = fields.Char(string='Power Base/Scooter Type')
    s2c_reason = fields.Char(string='Reason for Application')
    s2c_replacement_status = fields.Char(string='Replacement - Mobility Status')
    s2c_replacement_size = fields.Char(string='Replacement - Body Size')
    s2c_replacement_adp = fields.Char(string='Replacement - Equipment Worn')
    s2c_replacement_special = fields.Char(string='Replacement - Special')
    s2c_confirm1 = fields.Char(string='Power Base Confirmation 1')
    s2c_confirm2 = fields.Char(string='Power Base Confirmation 2')
    s2c_confirm3 = fields.Char(string='Scooter Confirmation 1')
    s2c_confirm4 = fields.Char(string='Scooter Confirmation 2')
    s2c_confirm5 = fields.Char(string='Scooter Confirmation 3')
    # Prescription
    s2c_seat_width = fields.Char(string='Seat Width')
    s2c_seat_width_unit = fields.Char(string='Seat Width Unit')
    s2c_back_height = fields.Char(string='Finished Back Height')
    s2c_back_height_unit = fields.Char(string='Back Height Unit')
    s2c_floor_height = fields.Char(string='Finished Seat to Floor Height')
    s2c_floor_height_unit = fields.Char(string='Floor Height Unit')
    s2c_rest_length = fields.Char(string='Leg Rest Length')
    s2c_rest_length_unit = fields.Char(string='Rest Length Unit')
    s2c_seat_depth = fields.Char(string='Seat Depth')
    s2c_seat_depth_unit = fields.Char(string='Seat Depth Unit')
    s2c_client_weight = fields.Char(string='Client Weight')
    s2c_client_weight_unit = fields.Char(string='Client Weight Unit')
    # Add-on options
    s2c_adjustable_tension = fields.Boolean(string='Adjustable Tension Back Upholstery')
    s2c_midline = fields.Boolean(string='Midline Control')
    s2c_manual_recline = fields.Boolean(string='Manual Recline Option')
    s2c_footplates = fields.Boolean(string='Angle Adjustable Footplates')
    s2c_legrests = fields.Boolean(string='Manual Elevating Legrests')
    s2c_swingaway = fields.Boolean(string='Swingaway Mounting Bracket')
    s2c_one_piece = fields.Boolean(string='One Piece 90/90 Front Riggings')
    s2c_seat_package_1 = fields.Boolean(string='Seat Package 1 for Power Bases')
    s2c_seat_package_2 = fields.Boolean(string='Seat Package 2 for Power Bases')
    s2c_oxygen = fields.Boolean(string='Oxygen Tank Holder')
    s2c_ventilator = fields.Boolean(string='Ventilator Tray')
    # Specialty controls
    s2c_sp_controls_1 = fields.Boolean(string='Specialty Controls 1 - Non Standard Joystick')
    s2c_sp_controls_2 = fields.Boolean(string='Specialty Controls 2 - Chin/Rim Control')
    s2c_sp_controls_3 = fields.Boolean(string='Specialty Controls 3 - Simple Touch')
    s2c_sp_controls_4 = fields.Boolean(string='Specialty Controls 4 - Proximity Control')
    s2c_sp_controls_5 = fields.Boolean(string='Specialty Controls 5 - Breath Control')
    s2c_sp_controls_6 = fields.Boolean(string='Specialty Controls 6 - Scanners')
    s2c_auto_correction = fields.Boolean(string='Auto Correction System')
    s2c_rationale = fields.Text(string='Clinical Rationale')
    # Power positioning
    s2c_power_tilt = fields.Boolean(string='Power Tilt Only')
    s2c_power_recline = fields.Boolean(string='Power Recline Only')
    s2c_tilt_and_recline = fields.Boolean(string='Power Tilt and Recline')
    s2c_power_elevating = fields.Boolean(string='Power Elevating Footrests')
    s2c_control_box = fields.Boolean(string='Multi-Function Control Box')
    s2c_custom = fields.Char(string='Custom Modifications Required')
    s2c_cost_labour = fields.Char(string='Cost of Labour')

    # ------------------------------------------------------------------
    # SECTION 2D - POSITIONING DEVICES (SEATING) FOR MOBILITY
    # ------------------------------------------------------------------
    # Seat Cushion
    s2d_seat_modular = fields.Boolean(string='Seat Cushion - Modular')
    s2d_seat_custom = fields.Boolean(string='Seat Cushion - Custom Fabricated')
    s2d_seat_cover_modular = fields.Boolean(string='Seat Cover - Modular')
    s2d_seat_cover_custom = fields.Boolean(string='Seat Cover - Custom Fabricated')
    s2d_seat_option_modular = fields.Boolean(string='Seat Options - Modular')
    s2d_seat_option_custom = fields.Boolean(string='Seat Options - Custom Fabricated')
    s2d_seat_hardware_modular = fields.Boolean(string='Seat Hardware - Modular')
    s2d_seat_hardware_custom = fields.Boolean(string='Seat Hardware - Custom Fabricated')
    s2d_adductor_modular = fields.Boolean(string='Pommel/Adductors - Modular')
    s2d_adductor_custom = fields.Boolean(string='Pommel/Adductors - Custom Fabricated')
    s2d_pommel_custom = fields.Boolean(string='Pommel Hardware - Custom Fabricated')
    # Back Support
    s2d_back_modular = fields.Boolean(string='Back Support - Modular')
    s2d_back_custom = fields.Boolean(string='Back Support - Custom Fabricated')
    s2d_back_option_modular = fields.Boolean(string='Back Options - Modular')
    s2d_back_option_custom = fields.Boolean(string='Back Options - Custom Fabricated')
    s2d_back_cover_custom = fields.Boolean(string='Back Cover - Custom Fabricated')
    s2d_back_hardware_modular = fields.Boolean(string='Back Hardware - Modular')
    s2d_back_hardware_custom = fields.Boolean(string='Back Hardware - Custom Fabricated')
    # Complete Assembly
    s2d_complete_modular = fields.Boolean(string='Complete Assembly - Modular')
    s2d_complete_custom = fields.Boolean(string='Complete Assembly - Custom Fabricated')
    # Headrest/Neckrest
    s2d_headrest_modular = fields.Boolean(string='Headrest/Neckrest - Modular')
    s2d_headrest_custom = fields.Boolean(string='Headrest/Neckrest - Custom Fabricated')
    s2d_head_option_custom = fields.Boolean(string='Headrest Options - Custom Fabricated')
    s2d_head_hardware_modular = fields.Boolean(string='Headrest Hardware - Modular')
    s2d_head_hardware_custom = fields.Boolean(string='Headrest Hardware - Custom Fabricated')
    # Positioning Belts
    s2d_belt_modular = fields.Boolean(string='Positioning Belt - Modular')
    s2d_belt_custom = fields.Boolean(string='Positioning Belt - Custom Fabricated')
    s2d_belt_option_custom = fields.Boolean(string='Belt Options - Custom Fabricated')
    # Arm Supports
    s2d_arm_modular = fields.Boolean(string='Arm Support - Modular')
    s2d_arm_custom = fields.Boolean(string='Arm Support - Custom Fabricated')
    s2d_arm_option_modular = fields.Boolean(string='Arm Options - Modular')
    s2d_arm_option_custom = fields.Boolean(string='Arm Options - Custom Fabricated')
    s2d_arm_hardware_modular = fields.Boolean(string='Arm Hardware - Modular')
    s2d_arm_hardware_custom = fields.Boolean(string='Arm Hardware - Custom Fabricated')
    # Tray
    s2d_tray_modular = fields.Boolean(string='Tray - Modular')
    s2d_tray_custom = fields.Boolean(string='Tray - Custom Fabricated')
    s2d_tray_option_modular = fields.Boolean(string='Tray Options - Modular')
    s2d_tray_option_custom = fields.Boolean(string='Tray Options - Custom Fabricated')
    # Lateral Supports
    s2d_lateral_modular = fields.Boolean(string='Lateral Support - Modular')
    s2d_lateral_custom = fields.Boolean(string='Lateral Support - Custom Fabricated')
    s2d_lateral_option_custom = fields.Boolean(string='Lateral Options - Custom Fabricated')
    s2d_lateral_hardware_custom = fields.Boolean(string='Lateral Hardware - Custom Fabricated')
    # Foot/Leg Supports
    s2d_foot_modular = fields.Boolean(string='Foot/Leg Support - Modular')
    s2d_foot_custom = fields.Boolean(string='Foot/Leg Support - Custom Fabricated')
    s2d_foot_option_modular = fields.Boolean(string='Foot Options - Modular')
    s2d_foot_option_custom = fields.Boolean(string='Foot Options - Custom Fabricated')
    s2d_foot_hardware_modular = fields.Boolean(string='Foot Hardware - Modular')
    s2d_foot_hardware_custom = fields.Boolean(string='Foot Hardware - Custom Fabricated')
    # Seating reason and confirmations
    s2d_reason = fields.Char(string='Reason for Application')
    s2d_replacement_status = fields.Char(string='Replacement - Mobility Status')
    s2d_replacement_size = fields.Char(string='Replacement - Body Size')
    s2d_replacement_adp = fields.Char(string='Replacement - Equipment Worn')
    s2d_replacement_special = fields.Char(string='Replacement - Special')
    s2d_confirm1 = fields.Char(string='Seating Confirmation 1')
    s2d_confirm2 = fields.Char(string='Seating Confirmation 2')
    s2d_custom = fields.Char(string='Custom Modifications Required')
    s2d_cost_labour = fields.Char(string='Cost of Labour')

    # ------------------------------------------------------------------
    # SECTION 3 - APPLICANT CONSENT AND SIGNATURE
    # ------------------------------------------------------------------
    consent_date = fields.Date(string='Consent Date')
    consent_signed_by = fields.Selection([
        ('applicant', 'Applicant'),
        ('agent', 'Agent'),
    ], string='Signed By')
    # Agent/Contact info (if signed by agent)
    agent_relationship = fields.Char(string='Agent Relationship')
    agent_last_name = fields.Char(string='Agent Last Name')
    agent_first_name = fields.Char(string='Agent First Name')
    agent_middle_initial = fields.Char(string='Agent Middle Initial')
    agent_unit = fields.Char(string='Agent Unit')
    agent_street_no = fields.Char(string='Agent Street Number')
    agent_street_name = fields.Char(string='Agent Street Name')
    agent_rural_route = fields.Char(string='Agent Rural Route')
    agent_city = fields.Char(string='Agent City')
    agent_province = fields.Char(string='Agent Province')
    agent_postal_code = fields.Char(string='Agent Postal Code')
    agent_home_phone = fields.Char(string='Agent Home Phone')
    agent_bus_phone = fields.Char(string='Agent Business Phone')
    agent_phone_ext = fields.Char(string='Agent Phone Ext')

    # ------------------------------------------------------------------
    # SECTION 4 - AUTHORIZER
    # ------------------------------------------------------------------
    authorizer_last_name = fields.Char(string='Authorizer Last Name')
    authorizer_first_name = fields.Char(string='Authorizer First Name')
    authorizer_phone = fields.Char(string='Authorizer Phone')
    authorizer_phone_ext = fields.Char(string='Authorizer Phone Ext')
    authorizer_adp_number = fields.Char(string='Authorizer ADP Registration Number')
    assessment_date = fields.Date(string='Assessment Date')

    # ------------------------------------------------------------------
    # SECTION 4 - VENDOR 1
    # ------------------------------------------------------------------
    vendor_business_name = fields.Char(string='Vendor Business Name')
    vendor_adp_number = fields.Char(string='Vendor ADP Registration Number')
    vendor_representative = fields.Char(string='Vendor Representative (Last, First)')
    vendor_position = fields.Char(string='Vendor Position Title')
    vendor_location = fields.Char(string='Vendor Location')
    vendor_phone = fields.Char(string='Vendor Phone')
    vendor_phone_ext = fields.Char(string='Vendor Phone Ext')
    vendor_sign_date = fields.Date(string='Vendor Sign Date')

    # ------------------------------------------------------------------
    # SECTION 4 - VENDOR 2
    # ------------------------------------------------------------------
    vendor2_business_name = fields.Char(string='Vendor 2 Business Name')
    vendor2_adp_number = fields.Char(string='Vendor 2 ADP Registration')
    vendor2_representative = fields.Char(string='Vendor 2 Representative')
    vendor2_position = fields.Char(string='Vendor 2 Position')
    vendor2_location = fields.Char(string='Vendor 2 Location')
    vendor2_phone = fields.Char(string='Vendor 2 Phone')
    vendor2_phone_ext = fields.Char(string='Vendor 2 Phone Ext')
    vendor2_sign_date = fields.Date(string='Vendor 2 Sign Date')

    # ------------------------------------------------------------------
    # SECTION 4 - EQUIPMENT SPEC & PROOF OF DELIVERY
    # ------------------------------------------------------------------
    equip_vendor_invoice_no = fields.Char(string='Vendor Invoice Number')
    equip_vendor_adp_reg = fields.Char(string='Vendor ADP Reg (Page 12)')
    equip_cell1 = fields.Char(string='ADP Device Code')
    equip_cell2 = fields.Char(string='Description of Item')
    equip_cell3 = fields.Char(string='Base Device')
    equip_cell4 = fields.Char(string='ADP Portion')
    equip_cell5 = fields.Char(string='Client Portion')
    pod_received_by = fields.Char(string='Proof of Delivery - Received By')
    pod_date = fields.Date(string='Proof of Delivery Date')

    # ------------------------------------------------------------------
    # SECTION 4 - NOTE TO ADP (sections submitted checklist)
    # ------------------------------------------------------------------
    note_section1 = fields.Boolean(string='Section 1 Submitted')
    note_section2a = fields.Boolean(string='Section 2a Submitted')
    note_section2b = fields.Boolean(string='Section 2b Submitted')
    note_section2c = fields.Boolean(string='Section 2c Submitted')
    note_section2d = fields.Boolean(string='Section 2d Submitted')
    note_section3and4 = fields.Boolean(string='Section 3 & 4 Submitted')
    note_vendor_replacement = fields.Char(string='Vendor Quote - Replacement')
    note_vendor_custom = fields.Char(string='Vendor Quote - Custom Modifications')
    note_funding_chart = fields.Char(string='Justification for Funding Chart')
    note_letter = fields.Char(string='Letter of Rationale')

    # Computed summary
    sections_submitted = fields.Char(
        string='Sections Submitted',
        compute='_compute_sections_submitted', store=True,
    )

    # Legacy compat fields
    base_device = fields.Char(
        string='Base Device Selected',
        compute='_compute_base_device', store=True,
    )
    reason_for_application = fields.Char(
        string='Reason for Application',
        compute='_compute_reason', store=True,
    )

    # ------------------------------------------------------------------
    # COMPUTED
    # ------------------------------------------------------------------
    @api.depends('applicant_last_name', 'applicant_first_name', 'application_date')
    def _compute_display_name(self):
        for rec in self:
            name_parts = [rec.applicant_last_name or '', rec.applicant_first_name or '']
            name = ', '.join(p for p in name_parts if p) or 'Unknown'
            date_str = rec.application_date.strftime('%Y-%m-%d') if rec.application_date else 'No Date'
            rec.display_name = f'{name} ({date_str})'

    @api.depends('note_section1', 'note_section2a', 'note_section2b',
                 'note_section2c', 'note_section2d', 'note_section3and4')
    def _compute_sections_submitted(self):
        for rec in self:
            parts = []
            if rec.note_section1:
                parts.append('1')
            if rec.note_section2a:
                parts.append('2a')
            if rec.note_section2b:
                parts.append('2b')
            if rec.note_section2c:
                parts.append('2c')
            if rec.note_section2d:
                parts.append('2d')
            if rec.note_section3and4:
                parts.append('3+4')
            rec.sections_submitted = ', '.join(parts) if parts else ''

    @api.depends('s2a_base_device', 's2b_base_device', 's2c_base_device')
    def _compute_base_device(self):
        for rec in self:
            rec.base_device = rec.s2a_base_device or rec.s2b_base_device or rec.s2c_base_device or ''

    @api.depends('s2a_reason', 's2b_reason', 's2c_reason', 's2d_reason')
    def _compute_reason(self):
        for rec in self:
            rec.reason_for_application = rec.s2a_reason or rec.s2b_reason or rec.s2c_reason or rec.s2d_reason or ''

    # ------------------------------------------------------------------
    # XML EXPORT
    # ------------------------------------------------------------------
    def action_export_xml(self):
        """Reconstruct ADP XML from stored JSON data."""
        self.ensure_one()
        if not self.xml_data_json:
            # Fall back to raw_xml if available
            if self.raw_xml:
                xml_content = self.raw_xml.encode('utf-8')
                attachment = self.env['ir.attachment'].create({
                    'name': f'{self.applicant_last_name}_{self.applicant_first_name}_data.xml',
                    'type': 'binary',
                    'datas': base64.b64encode(xml_content),
                    'mimetype': 'application/xml',
                })
                return {
                    'type': 'ir.actions.act_url',
                    'url': f'/web/content/{attachment.id}?download=true',
                    'target': 'new',
                }
            return False

        try:
            data = json.loads(self.xml_data_json)
            xml_str = self._json_to_xml(data)
            attachment = self.env['ir.attachment'].create({
                'name': f'{self.applicant_last_name or "export"}_{self.applicant_first_name or "data"}_data.xml',
                'type': 'binary',
                'datas': base64.b64encode(xml_str.encode('utf-8')),
                'mimetype': 'application/xml',
            })
            return {
                'type': 'ir.actions.act_url',
                'url': f'/web/content/{attachment.id}?download=true',
                'target': 'new',
            }
        except Exception as e:
            _logger.exception('XML export error: %s', e)
            return False

    def _json_to_xml(self, data):
        """Reconstruct the ADP XML from flat JSON dictionary."""
        # Build the XML tree following the exact ADP structure
        root = ET.Element('form1')
        form = ET.SubElement(root, 'Form')

        # Simple top-level fields
        self._set_el(form, 'deviceCategory', data.get('deviceCategory', ''))
        self._set_el(form, 'VersionNumber', data.get('VersionNumber', ''))

        # Section 1
        s1 = ET.SubElement(form, 'section1')
        s1_fields = [
            'applicantLastname', 'applicantFirstname', 'applicantMiddleinitial',
            'healthNo', 'versionNo', 'DateOfBirth', 'nameLTCH',
            'unitNo', 'streetNo', 'streetName', 'rrRoute',
            'city', 'province', 'postalCode',
            'homePhone', 'busPhone', 'phoneExtension',
        ]
        for f in s1_fields:
            self._set_el(s1, f, data.get(f'section1.{f}', ''))

        # Confirmation of benefit
        cob = ET.SubElement(s1, 'confirmationOfBenefit')
        for f in ['q1Yn', 'q1Ifyes', 'q2Yn', 'q3Yn']:
            self._set_el(cob, f, data.get(f'section1.confirmationOfBenefit.{f}', ''))

        # Section 2
        s2 = ET.SubElement(form, 'section2')

        # Devices and Eligibility
        de = ET.SubElement(s2, 'devicesandEligibility')
        de_fields = [
            'condition', 'status', 'none', 'forearm', 'wheeled', 'manual',
            'power', 'addOn', 'scooter', 'seating', 'tiltSystem', 'reclineSystem',
            'legRests', 'frame', 'stroller', 'deviceForearm', 'deviceWheeled',
            'deviceManual', 'deviceAmbulation', 'deviceDependent', 'deviceDynamic',
            'manualDyanmic', 'manualWheelchair', 'powerBase', 'powerScooter',
            'ambulation', 'positioning', 'highTech', 'standingFrame',
            'adpFunded', 'nonADPFunded',
        ]
        for f in de_fields:
            self._set_el(de, f, data.get(f'section2.devicesandEligibility.{f}', ''))

        # Sections 2a, 2b, 2c, 2d
        for section_key in ['section2a', 'section2b', 'section2c', 'section2d']:
            section_data = {k.split(f'section2.{section_key}.')[1]: v
                           for k, v in data.items()
                           if k.startswith(f'section2.{section_key}.')}
            sec = ET.SubElement(s2, section_key)
            # Preserve field order from the data keys
            ordered_keys = [k.split(f'section2.{section_key}.')[1]
                           for k in sorted(data.keys())
                           if k.startswith(f'section2.{section_key}.')]
            for f in ordered_keys:
                self._set_el(sec, f, section_data.get(f, ''))

        # Section 3
        s3 = ET.SubElement(form, 'section3')
        sig = ET.SubElement(s3, 'sig')
        for f in ['signature', 'person', 'Date']:
            self._set_el(sig, f, data.get(f'section3.sig.{f}', ''))
        contact = ET.SubElement(s3, 'contact')
        contact_fields = [
            'relationship', 'applicantLastname', 'applicantFirstname',
            'applicantMiddleinitial', 'unitNo', 'streetNo', 'streetName',
            'rrRoute', 'city', 'province', 'postalCode',
            'homePhone', 'busPhone', 'phoneExtension',
        ]
        for f in contact_fields:
            self._set_el(contact, f, data.get(f'section3.contact.{f}', ''))

        # Section 4
        s4 = ET.SubElement(form, 'section4')
        # Authorizer
        auth = ET.SubElement(s4, 'authorizer')
        for f in ['authorizerLastname', 'authorizerFirstname', 'busPhone',
                   'phoneExtension', 'adpNo', 'signature', 'Date']:
            self._set_el(auth, f, data.get(f'section4.authorizer.{f}', ''))
        # Vendor
        vendor = ET.SubElement(s4, 'vendor')
        for f in ['vendorBusName', 'adpVendorRegNo', 'vendorLastfirstname',
                   'positionTitle', 'vendorLocation', 'busPhone',
                   'phoneExtension', 'signature', 'Date']:
            self._set_el(vendor, f, data.get(f'section4.vendor.{f}', ''))
        # Vendor 2
        v2 = ET.SubElement(s4, 'vendor2')
        for f in ['vendorBusName', 'adpVendorRegNo', 'vendorLastfirstname',
                   'positionTitle', 'vendorLocation', 'busPhone',
                   'phoneExtension', 'signature', 'Date']:
            self._set_el(v2, f, data.get(f'section4.vendor2.{f}', ''))
        # Equipment Spec
        eq = ET.SubElement(s4, 'equipmentSpec')
        self._set_el(eq, 'vendorInvoiceNo', data.get('section4.equipmentSpec.vendorInvoiceNo', ''))
        self._set_el(eq, 'vendorADPRegNo', data.get('section4.equipmentSpec.vendorADPRegNo', ''))
        t2 = ET.SubElement(eq, 'Table2')
        r1 = ET.SubElement(t2, 'Row1')
        for c in ['Cell1', 'Cell2', 'Cell3', 'Cell4', 'Cell5']:
            self._set_el(r1, c, data.get(f'section4.equipmentSpec.Table2.Row1.{c}', ''))
        # Proof of delivery
        pod = ET.SubElement(s4, 'proofOfDelivery')
        for f in ['signature', 'receivedBy', 'Date']:
            self._set_el(pod, f, data.get(f'section4.proofOfDelivery.{f}', ''))
        # Note to ADP
        note = ET.SubElement(s4, 'noteToADP')
        for f in ['section1', 'section2a', 'section2b', 'section2c', 'section2d',
                   'section3and4', 'vendorReplacement', 'vendorCustom',
                   'fundingChart', 'letter']:
            self._set_el(note, f, data.get(f'section4.noteToADP.{f}', ''))

        # Convert to string
        tree = ET.ElementTree(root)
        ET.indent(tree, space='')
        import io
        buf = io.BytesIO()
        tree.write(buf, encoding='unicode', xml_declaration=True)
        return buf.getvalue()

    @staticmethod
    def _set_el(parent, tag, value):
        """Create a child element, self-closing if empty."""
        el = ET.SubElement(parent, tag)
        if value:
            el.text = str(value)
