/** @odoo-module **/
// Fusion Claims - Google Address Autocomplete for Contacts
// Copyright 2024-2025 Nexa Systems Inc.
// License OPL-1

import { FormController } from "@web/views/form/form_controller";
import { useService } from "@web/core/utils/hooks";
import { onMounted, onWillUnmount } from "@odoo/owl";
import { patch } from "@web/core/utils/patch";

// Store for autocomplete instances and services
let googleMapsLoaded = false;
let googleMapsLoading = false;
let googleMapsApiKey = null;
let globalOrm = null;
const autocompleteInstances = new Map();

/**
 * Load Google Maps API dynamically
 */
async function loadGoogleMapsApi(apiKey) {
    if (googleMapsLoaded) {
        return Promise.resolve();
    }
    
    if (googleMapsLoading) {
        return new Promise((resolve) => {
            const checkLoaded = setInterval(() => {
                if (googleMapsLoaded) {
                    clearInterval(checkLoaded);
                    resolve();
                }
            }, 100);
        });
    }
    
    googleMapsLoading = true;
    
    return new Promise((resolve, reject) => {
        window.initGoogleMapsAutocomplete = () => {
            googleMapsLoaded = true;
            googleMapsLoading = false;
            resolve();
        };
        
        const script = document.createElement('script');
        script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places&callback=initGoogleMapsAutocomplete`;
        script.async = true;
        script.defer = true;
        script.onerror = () => {
            googleMapsLoading = false;
            reject(new Error('Failed to load Google Maps API'));
        };
        document.head.appendChild(script);
    });
}

/**
 * Get API key from Odoo config
 */
async function getGoogleMapsApiKey(orm) {
    if (googleMapsApiKey) {
        return googleMapsApiKey;
    }
    
    try {
        const result = await orm.call(
            'ir.config_parameter',
            'get_param',
            ['fusion_claims.google_maps_api_key']
        );
        googleMapsApiKey = result || null;
        return googleMapsApiKey;
    } catch (error) {
        console.warn('Could not fetch Google Maps API key:', error);
        return null;
    }
}

/**
 * Initialize autocomplete on a street input field
 */
function initAutocompleteOnField(input, formModel) {
    if (!input || !window.google || !window.google.maps || !window.google.maps.places) {
        return null;
    }
    
    if (autocompleteInstances.has(input)) {
        return autocompleteInstances.get(input);
    }
    
    const autocomplete = new google.maps.places.Autocomplete(input, {
        componentRestrictions: { country: 'ca' },
        types: ['address'],
        fields: ['address_components', 'formatted_address', 'geometry']
    });

    autocomplete.addListener('place_changed', async () => {
        const place = autocomplete.getPlace();
        if (!place.address_components) {
            return;
        }
        
        // Parse address components
        let streetNumber = '';
        let streetName = '';
        let unitNumber = '';  // For apartment/unit/suite
        let city = '';
        let province = '';
        let postalCode = '';
        let countryCode = '';
        
        for (const component of place.address_components) {
            const types = component.types;
            
            if (types.includes('street_number')) {
                streetNumber = component.long_name;
            } else if (types.includes('route')) {
                streetName = component.long_name;
            } else if (types.includes('subpremise')) {
                // Unit, apartment, suite number
                unitNumber = component.long_name;
            } else if (types.includes('floor')) {
                // Floor number
                if (!unitNumber) unitNumber = 'Floor ' + component.long_name;
            } else if (types.includes('locality')) {
                city = component.long_name;
            } else if (types.includes('sublocality_level_1') && !city) {
                city = component.long_name;
            } else if (types.includes('administrative_area_level_1')) {
                province = component.short_name;
            } else if (types.includes('postal_code')) {
                postalCode = component.long_name;
            } else if (types.includes('country')) {
                countryCode = component.short_name;
            }
        }
        
        const street = streetNumber ? `${streetNumber} ${streetName}` : streetName;
        
        console.log('[GooglePlaces] Parsed address:', { street, unitNumber, city, province, postalCode, countryCode });
        
        if (!formModel || !formModel.root) {
            console.warn('[GooglePlaces] No form model available');
            return;
        }
        
        const record = formModel.root;
        
        // First, lookup country and state IDs
        let countryId = null;
        let stateId = null;
        
        if (globalOrm && countryCode) {
            try {
                // Find country
                const countries = await globalOrm.searchRead(
                    'res.country',
                    [['code', '=', countryCode]],
                    ['id'],
                    { limit: 1 }
                );
                
                if (countries.length) {
                    countryId = countries[0].id;
                    console.log('[GooglePlaces] Found country ID:', countryId);
                    
                    // Find state
                    if (province) {
                        const states = await globalOrm.searchRead(
                            'res.country.state',
                            [['code', '=', province], ['country_id', '=', countryId]],
                            ['id'],
                            { limit: 1 }
                        );
                        
                        if (states.length) {
                            stateId = states[0].id;
                            console.log('[GooglePlaces] Found state ID:', stateId);
                        }
                    }
                }
            } catch (error) {
                console.error('[GooglePlaces] Error looking up country/state:', error);
            }
        }
        
        // Build complete update payload
        const updatePayload = {};
        if (street) updatePayload.street = street;
        if (unitNumber) updatePayload.street2 = unitNumber;
        if (city) updatePayload.city = city;
        if (postalCode) updatePayload.zip = postalCode;
        if (countryId !== null) updatePayload.country_id = countryId;
        if (stateId !== null) updatePayload.state_id = stateId;
        
        console.log('[GooglePlaces] Full update payload:', updatePayload);
        console.log('[GooglePlaces] Record ID:', record.resId);
        console.log('[GooglePlaces] Country ID to set:', countryId);
        console.log('[GooglePlaces] State ID to set:', stateId);
        
        // If record is saved (has ID), use ORM write directly
        if (record.resId && globalOrm) {
            try {
                console.log('[GooglePlaces] Using ORM write for saved record');
                
                // First write country and text fields
                const firstWrite = { ...updatePayload };
                delete firstWrite.state_id;  // Remove state from first write
                
                await globalOrm.write('res.partner', [record.resId], firstWrite);
                console.log('[GooglePlaces] First write (country + text) successful');
                
                // Then write state separately after a small delay
                if (stateId !== null) {
                    await new Promise(resolve => setTimeout(resolve, 100));
                    await globalOrm.write('res.partner', [record.resId], { state_id: stateId });
                    console.log('[GooglePlaces] Second write (state) successful');
                }
                
                // Reload the record to show updated values
                await record.load();
                console.log('[GooglePlaces] Record reloaded');
            } catch (error) {
                console.error('[GooglePlaces] ORM write failed:', error);
            }
        } else {
            // For new records - use DOM manipulation approach
            console.log('[GooglePlaces] New record - using DOM approach');
            
            try {
                // Update text fields through record.update (these work)
                const textUpdate = {};
                if (street) textUpdate.street = street;
                if (unitNumber) textUpdate.street2 = unitNumber;
                if (city) textUpdate.city = city;
                if (postalCode) textUpdate.zip = postalCode;
                
                if (Object.keys(textUpdate).length > 0) {
                    await record.update(textUpdate);
                    console.log('[GooglePlaces] Text fields updated');
                }
                
                // For Many2one fields, we need to simulate user interaction
                const formEl = input.closest('.o_form_view') || input.closest('.o_content') || document.body;
                
                if (countryId !== null && globalOrm) {
                    // Get country and state names in parallel for speed
                    const [countryData, stateData] = await Promise.all([
                        globalOrm.read('res.country', [countryId], ['display_name']),
                        stateId ? globalOrm.read('res.country.state', [stateId], ['display_name']) : Promise.resolve([])
                    ]);
                    
                    const countryName = countryData[0]?.display_name || 'Canada';
                    const stateName = stateData[0]?.display_name || province;
                    
                    // Find and update country field via DOM
                    await simulateMany2OneSelection(formEl, 'country_id', countryId, countryName);
                    
                    // Wait for country onchange to complete (reduced time)
                    await new Promise(resolve => setTimeout(resolve, 300));
                    
                    // Now set state
                    if (stateId !== null) {
                        await simulateMany2OneSelection(formEl, 'state_id', stateId, stateName);
                    }
                }
                
            } catch (error) {
                console.error('[GooglePlaces] New record update failed:', error);
            }
        }
    });
    
    autocompleteInstances.set(input, autocomplete);
    return autocomplete;
}

/**
 * Simulate Many2One field selection by finding the widget and triggering its update
 */
async function simulateMany2OneSelection(formEl, fieldName, valueId, displayName) {
    console.log(`[GooglePlaces] Simulating selection for ${fieldName}: ${valueId} - ${displayName}`);
    
    // Find the field container
    const fieldSelectors = [
        `[name="${fieldName}"]`,
        `.o_field_widget[name="${fieldName}"]`,
        `div[name="${fieldName}"]`,
    ];
    
    let fieldContainer = null;
    for (const selector of fieldSelectors) {
        fieldContainer = formEl.querySelector(selector);
        if (fieldContainer) break;
    }
    
    if (!fieldContainer) {
        console.log(`[GooglePlaces] Field container not found for ${fieldName}`);
        return false;
    }
    
    console.log(`[GooglePlaces] Found field container for ${fieldName}`);
    
    // Try to find the OWL component instance
    // In Odoo 17+, OWL components store their instance in __owl__
    let owlComponent = null;
    let el = fieldContainer;
    while (el && !owlComponent) {
        if (el.__owl__) {
            owlComponent = el.__owl__;
            break;
        }
        el = el.parentElement;
    }
    
    if (owlComponent && owlComponent.component) {
        console.log(`[GooglePlaces] Found OWL component for ${fieldName}`);
        
        // Try to call the component's update method
        const component = owlComponent.component;
        
        if (component.props && component.props.record) {
            try {
                // Try updating through the props record
                await component.props.record.update({ [fieldName]: valueId });
                console.log(`[GooglePlaces] Updated via props.record for ${fieldName}`);
                return true;
            } catch (e) {
                console.log(`[GooglePlaces] props.record.update failed for ${fieldName}:`, e.message);
            }
        }
        
        if (typeof component.updateValue === 'function') {
            try {
                await component.updateValue(valueId);
                console.log(`[GooglePlaces] Updated via updateValue for ${fieldName}`);
                return true;
            } catch (e) {
                console.log(`[GooglePlaces] updateValue failed for ${fieldName}:`, e.message);
            }
        }
    }
    
    // Fallback: Try to find and manipulate the input directly
    const inputEl = fieldContainer.querySelector('input:not([type="hidden"])');
    if (inputEl) {
        // Focus the input first
        inputEl.focus();
        
        // Clear and set value
        inputEl.value = '';
        inputEl.value = displayName;
        
        // Trigger input event to open dropdown
        inputEl.dispatchEvent(new InputEvent('input', { 
            bubbles: true, 
            cancelable: true,
            data: displayName,
            inputType: 'insertText'
        }));
        
        console.log(`[GooglePlaces] Triggered input event for ${fieldName}, waiting for dropdown...`);
        
        // Wait for dropdown to appear and search results to load (reduced)
        await new Promise(resolve => setTimeout(resolve, 250));
        
        // Look for dropdown items with various selectors used by Odoo
        const dropdownSelectors = [
            '.o-autocomplete--dropdown-menu .o-autocomplete--dropdown-item',
            '.o_m2o_dropdown_option',
            '.dropdown-menu .dropdown-item',
            '.o-autocomplete .dropdown-item',
            'ul.ui-autocomplete li',
            '.o_field_many2one_selection li',
        ];
        
        let found = false;
        for (const selector of dropdownSelectors) {
            const dropdownItems = document.querySelectorAll(selector);
            console.log(`[GooglePlaces] Checking selector "${selector}": found ${dropdownItems.length} items`);
            
            for (const item of dropdownItems) {
                const itemText = item.textContent.trim();
                if (itemText.includes(displayName) || displayName.includes(itemText)) {
                    // Click the item
                    item.click();
                    console.log(`[GooglePlaces] Clicked dropdown item for ${fieldName}: "${itemText}"`);
                    found = true;
                    break;
                }
            }
            if (found) break;
        }
        
        if (!found) {
            console.log(`[GooglePlaces] No matching dropdown item found for ${fieldName}`);
            
            // Try pressing Enter to select the first option
            inputEl.dispatchEvent(new KeyboardEvent('keydown', { 
                key: 'Enter', 
                code: 'Enter', 
                keyCode: 13,
                bubbles: true 
            }));
            console.log(`[GooglePlaces] Sent Enter key for ${fieldName}`);
            
            // Also try Tab to confirm selection
            await new Promise(resolve => setTimeout(resolve, 50));
            inputEl.dispatchEvent(new KeyboardEvent('keydown', { 
                key: 'Tab', 
                code: 'Tab', 
                keyCode: 9,
                bubbles: true 
            }));
        }
        
        // Blur to finalize
        await new Promise(resolve => setTimeout(resolve, 50));
        inputEl.blur();
        
        return found;
    }
    
    return false;
}

/**
 * Initialize company name autocomplete (searches for businesses)
 */
function initCompanyAutocomplete(input, formModel) {
    if (!input || !window.google || !window.google.maps || !window.google.maps.places) {
        return null;
    }
    
    const instanceKey = 'company_' + input.id;
    if (autocompleteInstances.has(instanceKey)) {
        return autocompleteInstances.get(instanceKey);
    }
    
    const autocomplete = new google.maps.places.Autocomplete(input, {
        componentRestrictions: { country: 'ca' },
        types: ['establishment'],  // Search for businesses
        fields: ['place_id', 'name', 'address_components', 'formatted_address', 'formatted_phone_number', 'international_phone_number', 'website', 'geometry']
    });
    
    autocomplete.addListener('place_changed', async () => {
        let place = autocomplete.getPlace();
        if (!place.name && !place.place_id) {
            return;
        }
        
        console.log('[GooglePlaces] Company selected:', place.name);
        console.log('[GooglePlaces] Initial place data:', place);
        
        // If phone/website not in initial response, fetch place details
        if (place.place_id && (!place.formatted_phone_number && !place.website)) {
            try {
                const service = new google.maps.places.PlacesService(document.createElement('div'));
                const detailsPromise = new Promise((resolve, reject) => {
                    service.getDetails(
                        { 
                            placeId: place.place_id, 
                            fields: ['formatted_phone_number', 'international_phone_number', 'website', 'name', 'address_components'] 
                        },
                        (result, status) => {
                            if (status === google.maps.places.PlacesServiceStatus.OK) {
                                resolve(result);
                            } else {
                                reject(new Error('Place details failed: ' + status));
                            }
                        }
                    );
                });
                
                const details = await detailsPromise;
                console.log('[GooglePlaces] Fetched place details:', details);
                
                // Merge details into place
                if (details.formatted_phone_number) place.formatted_phone_number = details.formatted_phone_number;
                if (details.international_phone_number) place.international_phone_number = details.international_phone_number;
                if (details.website) place.website = details.website;
            } catch (e) {
                console.log('[GooglePlaces] Could not fetch place details:', e.message);
            }
        }
        
        console.log('[GooglePlaces] Final place data:', place);
        
        // Parse address components
        let streetNumber = '';
        let streetName = '';
        let unitNumber = '';  // For apartment/unit/suite
        let city = '';
        let province = '';
        let postalCode = '';
        let countryCode = '';
        
        if (place.address_components) {
            for (const component of place.address_components) {
                const types = component.types;
                
                if (types.includes('street_number')) {
                    streetNumber = component.long_name;
                } else if (types.includes('route')) {
                    streetName = component.long_name;
                } else if (types.includes('subpremise')) {
                    // Unit, apartment, suite number
                    unitNumber = component.long_name;
                } else if (types.includes('floor')) {
                    // Floor number - add to unit if no unit already
                    if (!unitNumber) unitNumber = 'Floor ' + component.long_name;
                } else if (types.includes('locality')) {
                    city = component.long_name;
                } else if (types.includes('sublocality_level_1') && !city) {
                    city = component.long_name;
                } else if (types.includes('administrative_area_level_1')) {
                    province = component.short_name;
                } else if (types.includes('postal_code')) {
                    postalCode = component.long_name;
                } else if (types.includes('country')) {
                    countryCode = component.short_name;
                }
            }
        }
        
        const street = streetNumber ? `${streetNumber} ${streetName}` : streetName;
        console.log('[GooglePlaces] Parsed: street=', street, 'unit=', unitNumber, 'city=', city);
        
        if (!formModel || !formModel.root) {
            return;
        }
        
        const record = formModel.root;
        
        // Lookup country and state IDs
        let countryId = null;
        let stateId = null;
        
        if (globalOrm && countryCode) {
            try {
                const [countryData, stateData] = await Promise.all([
                    globalOrm.searchRead('res.country', [['code', '=', countryCode]], ['id'], { limit: 1 }),
                    province ? globalOrm.searchRead('res.country.state', [['code', '=', province], ['country_id.code', '=', countryCode]], ['id'], { limit: 1 }) : Promise.resolve([])
                ]);
                
                if (countryData.length) countryId = countryData[0].id;
                if (stateData.length) stateId = stateData[0].id;
            } catch (error) {
                console.error('[GooglePlaces] Error looking up country/state:', error);
            }
        }
        
        // Get phone number (prefer formatted, fallback to international)
        const phoneNumber = place.formatted_phone_number || place.international_phone_number || '';
        
        // Build update payload
        const updatePayload = {
            name: place.name,
        };
        if (street) updatePayload.street = street;
        if (unitNumber) updatePayload.street2 = unitNumber;
        if (city) updatePayload.city = city;
        if (postalCode) updatePayload.zip = postalCode;
        if (phoneNumber) updatePayload.phone = phoneNumber;
        if (place.website) updatePayload.website = place.website;
        if (countryId) updatePayload.country_id = countryId;
        if (stateId) updatePayload.state_id = stateId;
        
        console.log('[GooglePlaces] Phone:', phoneNumber, 'Website:', place.website, 'Unit:', unitNumber);
        
        console.log('[GooglePlaces] Company update payload:', updatePayload);
        
        // For saved records, use ORM write
        if (record.resId && globalOrm) {
            try {
                const writePayload = { ...updatePayload };
                delete writePayload.state_id;  // Write state separately
                
                await globalOrm.write('res.partner', [record.resId], writePayload);
                
                if (stateId) {
                    await new Promise(resolve => setTimeout(resolve, 100));
                    await globalOrm.write('res.partner', [record.resId], { state_id: stateId });
                }
                
                await record.load();
                console.log('[GooglePlaces] Company record updated');
            } catch (error) {
                console.error('[GooglePlaces] Company ORM write failed:', error);
            }
        } else {
            // For new records, update through the form
            try {
                // Text fields
                const textFields = {};
                if (place.name) textFields.name = place.name;
                if (street) textFields.street = street;
                if (unitNumber) textFields.street2 = unitNumber;
                if (city) textFields.city = city;
                if (postalCode) textFields.zip = postalCode;
                if (phoneNumber) textFields.phone = phoneNumber;
                if (place.website) textFields.website = place.website;
                
                console.log('[GooglePlaces] New record text fields:', textFields);
                
                await record.update(textFields);
                
                // Country and state via DOM simulation
                const formEl = input.closest('.o_form_view') || input.closest('.o_content') || document.body;
                
                if (countryId && globalOrm) {
                    const [countryInfo, stateInfo] = await Promise.all([
                        globalOrm.read('res.country', [countryId], ['display_name']),
                        stateId ? globalOrm.read('res.country.state', [stateId], ['display_name']) : Promise.resolve([])
                    ]);
                    
                    await simulateMany2OneSelection(formEl, 'country_id', countryId, countryInfo[0]?.display_name || 'Canada');
                    
                    if (stateId) {
                        await new Promise(resolve => setTimeout(resolve, 300));
                        await simulateMany2OneSelection(formEl, 'state_id', stateId, stateInfo[0]?.display_name || province);
                    }
                }
                
                console.log('[GooglePlaces] Company new record updated');
            } catch (error) {
                console.error('[GooglePlaces] Company update failed:', error);
            }
        }
    });
    
    autocompleteInstances.set(instanceKey, autocomplete);
    return autocomplete;
}

/**
 * Setup autocomplete for partner form
 */
async function setupPartnerAutocomplete(el, model, orm) {
    globalOrm = orm;
    
    const apiKey = await getGoogleMapsApiKey(orm);
    if (!apiKey) {
        console.log('[GooglePlaces] API key not configured');
        return;
    }
    
    try {
        await loadGoogleMapsApi(apiKey);
    } catch (error) {
        console.warn('[GooglePlaces] Failed to load API:', error);
        return;
    }
    
    // Find street input field for address autocomplete
    const streetInputSelectors = [
        'input[name="street"]',
        '.o_field_widget[name="street"] input',
        '[name="street"] input',
        'div[name="street"] input',
        '.o_address_street input'
    ];
    
    let streetInput = null;
    for (const selector of streetInputSelectors) {
        streetInput = el.querySelector(selector);
        if (streetInput) break;
    }
    
    if (streetInput && !autocompleteInstances.has(streetInput)) {
        initAutocompleteOnField(streetInput, model);
        
        // Add visual indicator
        streetInput.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 24 24\' fill=\'%234CAF50\'%3E%3Cpath d=\'M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\'/%3E%3C/svg%3E")';
        streetInput.style.backgroundRepeat = 'no-repeat';
        streetInput.style.backgroundPosition = 'right 8px center';
        streetInput.style.backgroundSize = '20px';
        streetInput.style.paddingRight = '35px';
        
        console.log('[GooglePlaces] Address autocomplete initialized on street field');
    }
    
    // Find company name input field for company autocomplete
    const nameInputSelectors = [
        'input[name="name"]',
        '.o_field_widget[name="name"] input',
        '[name="name"] input',
        'input.o_input[placeholder*="Lumber"]',  // Odoo's placeholder for company name
        '.o_field_char[name="name"] input',
    ];
    
    let nameInput = null;
    for (const selector of nameInputSelectors) {
        nameInput = el.querySelector(selector);
        if (nameInput) {
            console.log('[GooglePlaces] Found name input with selector:', selector);
            break;
        }
    }
    
    // Check if company type is selected - try multiple ways
    let isCompany = false;
    
    // Method 1: Check radio buttons
    const companyRadio = el.querySelector('input[name="company_type"][value="company"]');
    if (companyRadio && companyRadio.checked) {
        isCompany = true;
        console.log('[GooglePlaces] Company detected via radio button');
    }
    
    // Method 2: Check for company-specific elements (building icon visible)
    if (!isCompany) {
        const companyIcon = el.querySelector('.fa-building, .o_field_partner_type .fa-building-o');
        if (companyIcon) {
            isCompany = true;
            console.log('[GooglePlaces] Company detected via building icon');
        }
    }
    
    // Method 3: Check data attribute or class
    if (!isCompany) {
        const companyTypeField = el.querySelector('[name="company_type"]');
        if (companyTypeField) {
            const selectedOption = companyTypeField.querySelector('.active, .selected, [aria-checked="true"]');
            if (selectedOption && selectedOption.textContent.toLowerCase().includes('company')) {
                isCompany = true;
                console.log('[GooglePlaces] Company detected via active option');
            }
        }
    }
    
    // Method 4: Check the model data
    if (!isCompany && model && model.root && model.root.data) {
        const companyType = model.root.data.company_type;
        if (companyType === 'company') {
            isCompany = true;
            console.log('[GooglePlaces] Company detected via model data');
        }
    }
    
    console.log('[GooglePlaces] isCompany:', isCompany, 'nameInput:', !!nameInput);
    
    if (nameInput) {
        const instanceKey = 'company_' + (nameInput.id || 'default');
        
        if (isCompany && !autocompleteInstances.has(instanceKey)) {
            initCompanyAutocomplete(nameInput, model);
            
            // Add visual indicator (building icon)
            nameInput.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 24 24\' fill=\'%232196F3\'%3E%3Cpath d=\'M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z\'/%3E%3C/svg%3E")';
            nameInput.style.backgroundRepeat = 'no-repeat';
            nameInput.style.backgroundPosition = 'right 8px center';
            nameInput.style.backgroundSize = '20px';
            nameInput.style.paddingRight = '35px';
            
            console.log('[GooglePlaces] Company autocomplete initialized on name field');
        } else if (!isCompany && autocompleteInstances.has(instanceKey)) {
            // Remove company autocomplete when switched to Person
            autocompleteInstances.delete(instanceKey);
            nameInput.style.backgroundImage = '';
            nameInput.style.paddingRight = '';
            console.log('[GooglePlaces] Company autocomplete removed (switched to Person)');
        }
    }
    
    // Listen for company_type changes - try multiple selectors
    const companyTypeSelectors = [
        'input[name="company_type"]',
        '[name="company_type"] input',
        '.o_field_radio[name="company_type"] input',
        '.o_field_widget[name="company_type"] input',
    ];
    
    for (const selector of companyTypeSelectors) {
        const inputs = el.querySelectorAll(selector);
        inputs.forEach(input => {
            if (!input.dataset.googlePlacesListener) {
                input.dataset.googlePlacesListener = 'true';
                input.addEventListener('change', () => {
                    console.log('[GooglePlaces] company_type changed, re-initializing...');
                    setTimeout(() => {
                        setupPartnerAutocomplete(el, model, orm);
                    }, 200);
                });
                console.log('[GooglePlaces] Added listener to company_type input');
            }
        });
    }
    
    // Also listen for clicks on the company type labels/buttons
    const companyTypeContainer = el.querySelector('[name="company_type"]');
    if (companyTypeContainer && !companyTypeContainer.dataset.googlePlacesListener) {
        companyTypeContainer.dataset.googlePlacesListener = 'true';
        companyTypeContainer.addEventListener('click', () => {
            console.log('[GooglePlaces] company_type container clicked, re-initializing...');
            setTimeout(() => {
                setupPartnerAutocomplete(el, model, orm);
            }, 300);
        });
    }
}

/**
 * Cleanup autocomplete instances
 */
function cleanupAutocomplete(el) {
    if (!el) return;
    
    const inputs = el.querySelectorAll('input');
    inputs.forEach(input => {
        if (autocompleteInstances.has(input)) {
            autocompleteInstances.delete(input);
        }
    });
}

/**
 * Setup autocomplete for technician task form (address_street field)
 */
async function setupTaskAutocomplete(el, model, orm) {
    globalOrm = orm;

    const apiKey = await getGoogleMapsApiKey(orm);
    if (!apiKey) {
        console.log('[GooglePlaces Task] API key not configured');
        return;
    }

    try {
        await loadGoogleMapsApi(apiKey);
    } catch (error) {
        console.warn('[GooglePlaces Task] Failed to load API:', error);
        return;
    }

    // Find address_street input
    const streetSelectors = [
        'div[name="address_street"] input',
        '.o_field_widget[name="address_street"] input',
        '[name="address_street"] input',
    ];

    let streetInput = null;
    for (const selector of streetSelectors) {
        streetInput = el.querySelector(selector);
        if (streetInput) break;
    }

    if (!streetInput || autocompleteInstances.has(streetInput)) {
        return;
    }

    _attachTaskAutocomplete(streetInput, el, model);
}

/**
 * Attach Google Places autocomplete to a task address_street input.
 * Separated so it can be re-called after OWL re-renders the input.
 */
function _attachTaskAutocomplete(streetInput, el, model) {
    if (!streetInput || !window.google?.maps?.places) return;
    if (autocompleteInstances.has(streetInput)) return;

    console.log('[GooglePlaces Task] Attaching autocomplete on address_street');

    const autocomplete = new google.maps.places.Autocomplete(streetInput, {
        componentRestrictions: { country: 'ca' },
        types: ['address'],
        fields: ['address_components', 'formatted_address', 'geometry'],
    });

    autocomplete.addListener('place_changed', async () => {
        const place = autocomplete.getPlace();
        if (!place.address_components) return;

        let streetNumber = '', streetName = '', unitNumber = '';
        let city = '', province = '', postalCode = '', countryCode = '';
        let lat = 0, lng = 0;

        for (const c of place.address_components) {
            const t = c.types;
            if (t.includes('street_number')) streetNumber = c.long_name;
            else if (t.includes('route')) streetName = c.long_name;
            else if (t.includes('subpremise')) unitNumber = c.long_name;
            else if (t.includes('floor') && !unitNumber) unitNumber = 'Floor ' + c.long_name;
            else if (t.includes('locality')) city = c.long_name;
            else if (t.includes('sublocality_level_1') && !city) city = c.long_name;
            else if (t.includes('administrative_area_level_1')) province = c.short_name;
            else if (t.includes('postal_code')) postalCode = c.long_name;
            else if (t.includes('country')) countryCode = c.short_name;
        }

        if (place.geometry && place.geometry.location) {
            lat = place.geometry.location.lat();
            lng = place.geometry.location.lng();
        }

        const streetOnly = streetNumber ? `${streetNumber} ${streetName}` : streetName;
        // Use the full formatted address from Google for the Street field
        // so the user sees the complete address in one shot.
        const fullAddress = place.formatted_address || streetOnly;
        console.log('[GooglePlaces Task] Parsed:', { fullAddress, streetOnly, unitNumber, city, province, postalCode, lat, lng });

        if (!model || !model.root) return;
        const record = model.root;

        // Look up state ID
        let stateId = false;
        if (province && globalOrm) {
            try {
                const states = await globalOrm.searchRead(
                    'res.country.state',
                    [['code', '=', province], ['country_id.code', '=', countryCode || 'CA']],
                    ['id'],
                    { limit: 1 }
                );
                if (states.length) stateId = states[0].id;
            } catch (e) {
                console.warn('[GooglePlaces Task] State lookup failed:', e);
            }
        }

        // Update through the form model
        // address_street gets the FULL formatted address so the user can see it.
        // Hidden fields still get parsed components for data/geocoding/travel.
        try {
            const update = {};
            update.address_street = fullAddress;
            if (unitNumber) update.address_street2 = unitNumber;
            if (city) update.address_city = city;
            if (postalCode) update.address_zip = postalCode;
            if (lat) update.address_lat = lat;
            if (lng) update.address_lng = lng;
            if (stateId) update.address_state_id = stateId;

            await record.update(update);
            console.log('[GooglePlaces Task] Address fields updated via model');
        } catch (err) {
            console.error('[GooglePlaces Task] Update failed:', err);
        }

        // After record.update(), OWL may re-render and replace the input element.
        // Re-attach autocomplete on the (potentially new) input after a short delay.
        setTimeout(() => {
            _reattachTaskAutocomplete(el, model);
        }, 400);
    });

    autocompleteInstances.set(streetInput, autocomplete);

    // Visual indicator
    streetInput.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 24 24\' fill=\'%234CAF50\'%3E%3Cpath d=\'M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\'/%3E%3C/svg%3E")';
    streetInput.style.backgroundRepeat = 'no-repeat';
    streetInput.style.backgroundPosition = 'right 8px center';
    streetInput.style.backgroundSize = '20px';
    streetInput.style.paddingRight = '35px';

    console.log('[GooglePlaces Task] Autocomplete ready on address_street');
}

/**
 * Re-attach autocomplete after OWL re-renders the task form input.
 * Finds the current address_street input and attaches if not already done.
 */
function _reattachTaskAutocomplete(el, model) {
    const streetSelectors = [
        'div[name="address_street"] input',
        '.o_field_widget[name="address_street"] input',
        '[name="address_street"] input',
    ];

    let streetInput = null;
    for (const selector of streetSelectors) {
        streetInput = el.querySelector(selector);
        if (streetInput) break;
    }

    if (streetInput && !autocompleteInstances.has(streetInput)) {
        console.log('[GooglePlaces Task] Re-attaching autocomplete after re-render');
        _attachTaskAutocomplete(streetInput, el, model);
    }
}

/**
 * Attach Google Places autocomplete to a simple Char field (address only, no parsing).
 * Sets the full formatted address string in the input.
 */
function initSimpleAddressAutocomplete(input) {
    if (!input || !window.google || !window.google.maps || !window.google.maps.places) return;
    if (autocompleteInstances.has(input)) return;

    const autocomplete = new google.maps.places.Autocomplete(input, {
        componentRestrictions: { country: 'ca' },
        types: ['address'],
        fields: ['formatted_address'],
    });

    autocomplete.addListener('place_changed', () => {
        const place = autocomplete.getPlace();
        if (place && place.formatted_address) {
            // Use native setter for OWL reactivity
            const nativeSetter = Object.getOwnPropertyDescriptor(
                window.HTMLInputElement.prototype, 'value'
            ).set;
            nativeSetter.call(input, place.formatted_address);
            input.dispatchEvent(new Event('input', { bubbles: true }));
            input.dispatchEvent(new Event('change', { bubbles: true }));
            console.log('[GooglePlaces] Simple address set:', place.formatted_address);
        }
    });

    autocompleteInstances.set(input, autocomplete);

    // Visual indicator
    input.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 24 24\' fill=\'%234CAF50\'%3E%3Cpath d=\'M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\'/%3E%3C/svg%3E")';
    input.style.backgroundRepeat = 'no-repeat';
    input.style.backgroundPosition = 'right 8px center';
    input.style.backgroundSize = '20px';
    input.style.paddingRight = '35px';

    console.log('[GooglePlaces] Simple address autocomplete attached');
}

/**
 * Setup autocomplete on simple address Char fields by name.
 * Works for res.users (x_fc_start_address) and res.config.settings (fc_technician_start_address).
 */
async function setupSimpleAddressFields(el, orm) {
    const apiKey = await getGoogleMapsApiKey(orm);
    if (!apiKey) return;
    try { await loadGoogleMapsApi(apiKey); } catch (e) { return; }

    const fieldNames = ['x_fc_start_address', 'fc_technician_start_address'];
    for (const name of fieldNames) {
        const selectors = [
            `div[name="${name}"] input`,
            `.o_field_widget[name="${name}"] input`,
            `[name="${name}"] input`,
        ];
        for (const sel of selectors) {
            const inp = el.querySelector(sel);
            if (inp) {
                initSimpleAddressAutocomplete(inp);
                break;
            }
        }
    }
}

/** REMOVED: LTC Facility autocomplete functions moved to fusion_ltc_management */

/**
 * Patch FormController to add Google autocomplete for partner forms and dialog detection
 */
patch(FormController.prototype, {
    setup() {
        super.setup();
        
        this.orm = useService("orm");
        
        onMounted(() => {
            // Store ORM globally for dialog watcher
            globalOrm = this.orm;
            
            // Direct partner form
            if (this.props.resModel === 'res.partner') {
                setTimeout(() => {
                    if (this.rootRef && this.rootRef.el) {
                        setupPartnerAutocomplete(this.rootRef.el, this.model, this.orm);
                    }
                }, 800);
                
                if (this.rootRef && this.rootRef.el) {
                    this._addressObserver = new MutationObserver((mutations) => {
                        const hasNewInputs = mutations.some(m => 
                            m.addedNodes.length > 0 && 
                            Array.from(m.addedNodes).some(n => 
                                n.nodeType === 1 && (n.tagName === 'INPUT' || n.querySelector?.('input'))
                            )
                        );
                        if (hasNewInputs) {
                            setTimeout(() => {
                                setupPartnerAutocomplete(this.rootRef.el, this.model, this.orm);
                            }, 300);
                        }
                    });
                    
                    this._addressObserver.observe(this.rootRef.el, {
                        childList: true,
                        subtree: true
                    });
                }
            }

            // Technician task form
            if (this.props.resModel === 'fusion.technician.task') {
                setTimeout(() => {
                    if (this.rootRef && this.rootRef.el) {
                        setupTaskAutocomplete(this.rootRef.el, this.model, this.orm);
                    }
                }, 800);

                if (this.rootRef && this.rootRef.el) {
                    this._taskAddressObserver = new MutationObserver((mutations) => {
                        const hasNewInputs = mutations.some(m =>
                            m.addedNodes.length > 0 &&
                            Array.from(m.addedNodes).some(n =>
                                n.nodeType === 1 && (n.tagName === 'INPUT' || n.querySelector?.('input'))
                            )
                        );
                        if (hasNewInputs) {
                            setTimeout(() => {
                                setupTaskAutocomplete(this.rootRef.el, this.model, this.orm);
                            }, 300);
                        }
                    });

                    this._taskAddressObserver.observe(this.rootRef.el, {
                        childList: true,
                        subtree: true,
                    });

                    // "Calculate Travel" button -- handle via JS to prevent dialog close
                    const calcBtn = this.rootRef.el.querySelector('.o_fc_calculate_travel');
                    if (calcBtn) {
                        const formModel = this.model;
                        const orm = this.orm;
                        calcBtn.addEventListener('click', async (ev) => {
                            ev.preventDefault();
                            ev.stopPropagation();
                            const resId = formModel.root.resId;
                            if (!resId) {
                                // New unsaved record -- save first
                                const saved = await formModel.root.save();
                                if (!saved) return;
                            } else {
                                // Existing record -- save pending changes
                                if (formModel.root.isDirty) {
                                    const saved = await formModel.root.save();
                                    if (!saved) return;
                                }
                            }
                            const id = formModel.root.resId;
                            if (!id) return;
                            // Show loading state on button
                            const origText = calcBtn.textContent;
                            calcBtn.disabled = true;
                            calcBtn.textContent = ' Calculating...';
                            try {
                                await orm.call(
                                    'fusion.technician.task',
                                    'action_calculate_travel_times',
                                    [id],
                                );
                                // Reload form data to show updated travel fields
                                await formModel.root.load();
                            } catch (e) {
                                console.error('[CalcTravel] Error:', e);
                            } finally {
                                calcBtn.disabled = false;
                                calcBtn.textContent = origText || ' Calculate Travel';
                            }
                        });
                    }
                }
            }

            // Simple address autocomplete: res.partner, res.users, res.config.settings
            if (this.props.resModel === 'res.partner' || this.props.resModel === 'res.users' || this.props.resModel === 'res.config.settings') {
                setTimeout(() => {
                    if (this.rootRef && this.rootRef.el) {
                        setupSimpleAddressFields(this.rootRef.el, this.orm);
                    }
                }, 800);

                if (this.rootRef && this.rootRef.el) {
                    this._simpleAddrObserver = new MutationObserver((mutations) => {
                        const hasNewInputs = mutations.some(m =>
                            m.addedNodes.length > 0 &&
                            Array.from(m.addedNodes).some(n =>
                                n.nodeType === 1 && (n.tagName === 'INPUT' || n.querySelector?.('input'))
                            )
                        );
                        if (hasNewInputs) {
                            setTimeout(() => {
                                setupSimpleAddressFields(this.rootRef.el, this.orm);
                            }, 300);
                        }
                    });
                    this._simpleAddrObserver.observe(this.rootRef.el, { childList: true, subtree: true });
                }
            }
            
            // Start global dialog watcher once
            _startDialogWatcher(this.orm);
        });
        
        onWillUnmount(() => {
            if (this._addressObserver) {
                this._addressObserver.disconnect();
            }
            if (this._taskAddressObserver) {
                this._taskAddressObserver.disconnect();
            }
            if (this._simpleAddrObserver) {
                this._simpleAddrObserver.disconnect();
            }
            if (this.rootRef && this.rootRef.el) {
                cleanupAutocomplete(this.rootRef.el);
            }
        });
    }
});

/**
 * Start the global dialog watcher (runs once, watches forever)
 */
let _dialogWatcherStarted = false;
let _dialogCheckTimer = null;
const _processedDialogs = new WeakSet();

function _startDialogWatcher(orm) {
    if (_dialogWatcherStarted) return;
    _dialogWatcherStarted = true;
    
    console.log('[GooglePlaces] Starting global dialog watcher...');
    
    // Pre-load the API key and Google Maps
    getGoogleMapsApiKey(orm).then(apiKey => {
        if (!apiKey) {
            console.log('[GooglePlaces] No API key, dialog watcher disabled');
            return;
        }
        
        loadGoogleMapsApi(apiKey).then(() => {
            console.log('[GooglePlaces] API loaded, dialog watcher active');
            
            // Watch for ANY DOM change on body
            const observer = new MutationObserver(() => {
                if (_dialogCheckTimer) clearTimeout(_dialogCheckTimer);
                _dialogCheckTimer = setTimeout(_checkDialogsForPartnerForms, 600);
            });
            
            observer.observe(document.body, { childList: true, subtree: true });
            
        }).catch(err => console.warn('[GooglePlaces] API load failed:', err));
    }).catch(err => console.warn('[GooglePlaces] API key fetch failed:', err));
}

/**
 * Check all open dialogs for partner address forms
 */
function _checkDialogsForPartnerForms() {
    // Get all visible modals/dialogs
    const modals = document.querySelectorAll(
        '.o_dialog, .modal, .o_FormViewDialog, [role="dialog"]'
    );
    
    for (const modal of modals) {
        // Skip already processed
        if (_processedDialogs.has(modal)) continue;
        
        // Skip hidden modals
        if (modal.offsetParent === null && !modal.classList.contains('show')) continue;
        
        // Check if this dialog has a street field (partner form)
        const streetInput = modal.querySelector(
            '[name="street"] input, ' +
            '.o_address_street input, ' +
            'div[name="street"] input, ' +
            '.o_field_widget[name="street"] input'
        );
        
        if (!streetInput) continue;
        
        // Mark as processed
        _processedDialogs.add(modal);
        
        console.log('[GooglePlaces] Found partner dialog with street field!');
        
        // Get form element and model
        const formEl = modal.querySelector('.o_form_view') || modal;
        let formModel = null;
        
        // Walk through ALL elements to find OWL component with model
        const allEls = formEl.querySelectorAll('*');
        for (const el of allEls) {
            if (el.__owl__?.component?.model) {
                formModel = el.__owl__.component.model;
                console.log('[GooglePlaces] Found form model via child element');
                break;
            }
        }
        
        // Also walk up from formEl
        if (!formModel) {
            let node = formEl;
            while (node) {
                if (node.__owl__?.component?.model) {
                    formModel = node.__owl__.component.model;
                    console.log('[GooglePlaces] Found form model via parent');
                    break;
                }
                node = node.parentElement;
            }
        }
        
        // If still no model, try the modal itself and its controller
        if (!formModel) {
            let node = modal;
            while (node) {
                const comp = node.__owl__?.component;
                if (comp) {
                    // Check if this component has a model property
                    if (comp.model) {
                        formModel = comp.model;
                        console.log('[GooglePlaces] Found form model via modal OWL component');
                        break;
                    }
                    // Check props for FormViewDialog
                    if (comp.props?.record) {
                        formModel = { root: comp.props.record };
                        console.log('[GooglePlaces] Found form model via dialog props.record');
                        break;
                    }
                }
                node = node.parentElement;
            }
        }
        
        if (!formModel) {
            console.log('[GooglePlaces] No form model found - will use DOM-only approach for dialog');
        }
        
        // Initialize autocomplete on the street field, with a special dialog handler
        _initDialogAutocomplete(streetInput, formEl, formModel, modal);
        
        // Watch for re-renders inside the dialog
        let innerTimer = null;
        const innerObs = new MutationObserver(() => {
            if (innerTimer) clearTimeout(innerTimer);
            innerTimer = setTimeout(() => {
                const newStreet = modal.querySelector(
                    '[name="street"] input, .o_address_street input, div[name="street"] input'
                );
                if (newStreet && !autocompleteInstances.has(newStreet)) {
                    _initDialogAutocomplete(newStreet, formEl, formModel, modal);
                }
            }, 400);
        });
        innerObs.observe(modal, { childList: true, subtree: true });
    }
}

/**
 * Initialize autocomplete specifically for dialog forms (handles DOM-only updates)
 */
function _initDialogAutocomplete(streetInput, formEl, formModel, modal) {
    if (!streetInput || !window.google?.maps?.places) return;
    if (autocompleteInstances.has(streetInput)) return;
    
    const autocomplete = new google.maps.places.Autocomplete(streetInput, {
        componentRestrictions: { country: 'ca' },
        types: ['address'],
        fields: ['address_components', 'formatted_address']
    });
    
    autocomplete.addListener('place_changed', async () => {
        const place = autocomplete.getPlace();
        if (!place.address_components) return;
        
        // Parse address components
        let streetNumber = '', streetName = '', unitNumber = '';
        let city = '', province = '', postalCode = '', countryCode = '';
        
        for (const c of place.address_components) {
            const t = c.types;
            if (t.includes('street_number')) streetNumber = c.long_name;
            else if (t.includes('route')) streetName = c.long_name;
            else if (t.includes('subpremise')) unitNumber = c.long_name;
            else if (t.includes('floor') && !unitNumber) unitNumber = 'Floor ' + c.long_name;
            else if (t.includes('locality')) city = c.long_name;
            else if (t.includes('sublocality_level_1') && !city) city = c.long_name;
            else if (t.includes('administrative_area_level_1')) province = c.short_name;
            else if (t.includes('postal_code')) postalCode = c.long_name;
            else if (t.includes('country')) countryCode = c.short_name;
        }
        
        const street = streetNumber ? `${streetNumber} ${streetName}` : streetName;
        console.log('[GooglePlaces Dialog] Parsed:', { street, unitNumber, city, province, postalCode, countryCode });
        
        // Try record.update first (works if formModel is available)
        if (formModel?.root) {
            try {
                const textUpdate = {};
                if (street) textUpdate.street = street;
                if (unitNumber) textUpdate.street2 = unitNumber;
                if (city) textUpdate.city = city;
                if (postalCode) textUpdate.zip = postalCode;
                await formModel.root.update(textUpdate);
                console.log('[GooglePlaces Dialog] Text fields updated via model');
                
                // Handle country and state via model
                if (countryCode && globalOrm) {
                    const countries = await globalOrm.searchRead('res.country', [['code', '=', countryCode]], ['id'], { limit: 1 });
                    if (countries.length) {
                        await formModel.root.update({ country_id: countries[0].id });
                        console.log('[GooglePlaces Dialog] Country set via model');
                        
                        if (province) {
                            await new Promise(r => setTimeout(r, 300));
                            const states = await globalOrm.searchRead('res.country.state', [['code', '=', province], ['country_id', '=', countries[0].id]], ['id'], { limit: 1 });
                            if (states.length) {
                                await formModel.root.update({ state_id: states[0].id });
                                console.log('[GooglePlaces Dialog] State set via model');
                            }
                        }
                    }
                }
                return;
            } catch (err) {
                console.log('[GooglePlaces Dialog] Model update failed, falling back to DOM:', err.message);
            }
        }
        
        // DOM fallback - directly set input values in the dialog
        console.log('[GooglePlaces Dialog] Using DOM fallback');
        
        function setFieldValue(container, fieldName, value) {
            if (!value) return;
            const field = container.querySelector(`[name="${fieldName}"] input, div[name="${fieldName}"] input`);
            if (field) {
                // Set value and trigger input event for OWL reactivity
                const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
                nativeInputValueSetter.call(field, value);
                field.dispatchEvent(new Event('input', { bubbles: true }));
                field.dispatchEvent(new Event('change', { bubbles: true }));
                console.log(`[GooglePlaces Dialog] Set ${fieldName} = ${value}`);
            } else {
                console.log(`[GooglePlaces Dialog] Field ${fieldName} input not found`);
            }
        }
        
        // Set text fields via DOM
        setFieldValue(modal, 'street', street);
        setFieldValue(modal, 'street2', unitNumber);
        setFieldValue(modal, 'city', city);
        setFieldValue(modal, 'zip', postalCode);
        
        // Set country and state via Many2one simulation
        if (countryCode && globalOrm) {
            try {
                const countries = await globalOrm.searchRead('res.country', [['code', '=', countryCode]], ['id', 'display_name'], { limit: 1 });
                if (countries.length) {
                    await simulateMany2OneSelection(modal, 'country_id', countries[0].id, countries[0].display_name);
                    
                    if (province) {
                        await new Promise(r => setTimeout(r, 500));
                        const states = await globalOrm.searchRead('res.country.state', [['code', '=', province], ['country_id', '=', countries[0].id]], ['id', 'display_name'], { limit: 1 });
                        if (states.length) {
                            await simulateMany2OneSelection(modal, 'state_id', states[0].id, states[0].display_name);
                        }
                    }
                }
            } catch (err) {
                console.error('[GooglePlaces Dialog] Country/state lookup failed:', err);
            }
        }
    });
    
    autocompleteInstances.set(streetInput, autocomplete);
    
    // Add visual indicator
    streetInput.style.backgroundImage = 'url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' viewBox=\'0 0 24 24\' fill=\'%234CAF50\'%3E%3Cpath d=\'M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\'/%3E%3C/svg%3E")';
    streetInput.style.backgroundRepeat = 'no-repeat';
    streetInput.style.backgroundPosition = 'right 8px center';
    streetInput.style.backgroundSize = '20px';
    streetInput.style.paddingRight = '35px';
    
    console.log('[GooglePlaces Dialog] Autocomplete initialized on dialog street field');
}
