export function hvacInstallationCalculator(form: FormTs) {
// Base installation costs by system type
const systemBaseCosts: Record<string, number> = {
'central-ac': 3500,
'furnace-gas': 2800,
'furnace-electric': 2200,
'heat-pump': 4500,
'mini-split': 3000,
'full-system': 6500
};
// SEER rating multipliers for AC/Heat pumps
const efficiencyMultipliers: Record<string, number> = {
'standard': 1.0, // 14-15 SEER
'high': 1.25, // 16-17 SEER
'premium': 1.5, // 18-20 SEER
'ultra': 1.8 // 21+ SEER
};
// Home size adjustments (per 500 sq ft over 1500)
const sizeAdjustmentPer500 = 350;
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'HVAC Installation Estimate',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Service Location Section
const locationSection = form.addSubform('serviceLocation', { title: '๐ Service Location' });
locationSection.addRow(row => {
row.addAddress('propertyAddress', {
label: 'Property Address',
placeholder: 'Enter your property address...',
showMap: true,
showDistance: true,
referenceAddress: {
formattedAddress: 'Service Center, Denver, CO',
coordinates: { lat: 39.7392, lng: -104.9903 }
},
restrictToCountries: ['US', 'CA'],
distanceUnit: 'miles',
isRequired: true
});
});
locationSection.addRow(row => {
row.addTextPanel('serviceAreaInfo', {
computedValue: () => {
const addressField = locationSection.address('propertyAddress');
const miles = addressField?.distance();
if (miles == null) return '๐ Enter address to check service area';
if (miles <= 25) return '๐ Within service area - No travel fee';
if (miles <= 50) return '๐ Extended area - $150 travel fee';
if (miles <= 75) return '๐ Remote area - $300 travel fee';
return '๐ Outside standard area - Please call for availability';
},
customStyles: { 'font-size': '0.9rem', 'color': '#0369a1', 'background': '#e0f2fe', 'padding': '10px', 'border-radius': '6px' }
});
});
// Home Details Section
const homeSection = form.addSubform('homeDetails', { title: '๐ Home Details' });
homeSection.addRow(row => {
row.addInteger('squareFootage', {
label: 'Home Square Footage',
min: 500,
max: 10000,
defaultValue: 2000,
placeholder: 'e.g. 2000',
isRequired: true
}, '1fr');
row.addDropdown('homeType', {
label: 'Home Type',
options: [
{ id: 'single-story', name: 'Single Story' },
{ id: 'two-story', name: 'Two Story (+10%)' },
{ id: 'multi-story', name: 'Three+ Story (+20%)' },
{ id: 'mobile', name: 'Mobile Home' }
],
defaultValue: 'single-story',
isRequired: true
}, '1fr');
});
homeSection.addRow(row => {
row.addDropdown('homeAge', {
label: 'Home Age',
options: [
{ id: 'new', name: 'New Construction (under 5 years)' },
{ id: 'modern', name: 'Modern (5-20 years)' },
{ id: 'older', name: 'Older (20-40 years, +$500)' },
{ id: 'historic', name: 'Historic (40+ years, +$1000)' }
],
defaultValue: 'modern'
}, '1fr');
row.addDropdown('existingDucts', {
label: 'Existing Ductwork',
options: [
{ id: 'good', name: 'Good Condition' },
{ id: 'needs-repair', name: 'Needs Minor Repair (+$500)' },
{ id: 'needs-replacement', name: 'Needs Replacement (+$2500)' },
{ id: 'none', name: 'No Ductwork (+$4000)' }
],
defaultValue: 'good'
}, '1fr');
});
// System Selection Section
const systemSection = form.addSubform('systemSelection', { title: 'โ๏ธ System Selection' });
systemSection.addRow(row => {
row.addRadioButton('systemType', {
label: 'Installation Type',
options: [
{ id: 'central-ac', name: 'Central Air Conditioner Only ($3,500 base)' },
{ id: 'furnace-gas', name: 'Gas Furnace Only ($2,800 base)' },
{ id: 'furnace-electric', name: 'Electric Furnace Only ($2,200 base)' },
{ id: 'heat-pump', name: 'Heat Pump System ($4,500 base)' },
{ id: 'mini-split', name: 'Ductless Mini-Split ($3,000 base)' },
{ id: 'full-system', name: 'Complete HVAC System ($6,500 base)' }
],
defaultValue: 'full-system',
orientation: 'vertical',
isRequired: true
});
});
systemSection.addRow(row => {
row.addDropdown('efficiency', {
label: 'Efficiency Rating',
options: [
{ id: 'standard', name: 'Standard (14-15 SEER)' },
{ id: 'high', name: 'High Efficiency (16-17 SEER, +25%)' },
{ id: 'premium', name: 'Premium (18-20 SEER, +50%)' },
{ id: 'ultra', name: 'Ultra High (21+ SEER, +80%)' }
],
defaultValue: 'high'
}, '1fr');
row.addDropdown('brand', {
label: 'Brand Tier',
options: [
{ id: 'economy', name: 'Economy Brand' },
{ id: 'mid-range', name: 'Mid-Range Brand (+15%)' },
{ id: 'premium', name: 'Premium Brand (+30%)' },
{ id: 'luxury', name: 'Luxury Brand (+50%)' }
],
defaultValue: 'mid-range'
}, '1fr');
});
systemSection.addRow(row => {
row.addInteger('zones', {
label: 'Number of Zones',
min: 1,
max: 8,
defaultValue: 1,
isVisible: () => {
const type = systemSection.radioButton('systemType')?.value();
return type === 'mini-split' || type === 'full-system';
}
}, '1fr');
});
// Add-ons Section
const addonsSection = form.addSubform('addons', { title: 'โจ Additional Options' });
addonsSection.addRow(row => {
row.addCheckbox('smartThermostat', {
label: 'Smart Thermostat (+$350)',
defaultValue: false
}, '1fr');
row.addCheckbox('airPurifier', {
label: 'Whole-Home Air Purifier (+$800)',
defaultValue: false
}, '1fr');
});
addonsSection.addRow(row => {
row.addCheckbox('humidifier', {
label: 'Whole-Home Humidifier (+$500)',
defaultValue: false
}, '1fr');
row.addCheckbox('uvLight', {
label: 'UV Light Air Sanitizer (+$400)',
defaultValue: false
}, '1fr');
});
addonsSection.addRow(row => {
row.addCheckbox('zoning', {
label: 'Zoning System (+$2000)',
defaultValue: false,
isVisible: () => systemSection.radioButton('systemType')?.value() !== 'mini-split'
}, '1fr');
row.addCheckbox('extendedWarranty', {
label: 'Extended Warranty (+$500)',
defaultValue: false
}, '1fr');
});
addonsSection.addRow(row => {
row.addCheckbox('permitHandling', {
label: 'Permit Handling (+$200)',
defaultValue: true
}, '1fr');
row.addCheckbox('oldSystemRemoval', {
label: 'Old System Removal (+$300)',
defaultValue: true
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Helper to calculate travel fee
const getTravelFee = () => {
const addressField = locationSection.address('propertyAddress');
const miles = addressField?.distance();
if (miles == null || miles <= 25) return 0;
if (miles <= 50) return 150;
if (miles <= 75) return 300;
return 450;
};
// Quote Summary Section
const summarySection = form.addSubform('summary', { title: '๐ฐ Your Estimate', isCollapsible: false });
const getHomeTypeMultiplier = () => {
const type = homeSection.dropdown('homeType')?.value() || 'single-story';
const multipliers: Record<string, number> = {
'single-story': 1.0,
'two-story': 1.1,
'multi-story': 1.2,
'mobile': 0.9
};
return multipliers[type] || 1;
};
const getHomeAgeExtra = () => {
const age = homeSection.dropdown('homeAge')?.value() || 'modern';
const extras: Record<string, number> = {
'new': 0,
'modern': 0,
'older': 500,
'historic': 1000
};
return extras[age] || 0;
};
const getDuctworkExtra = () => {
const ducts = homeSection.dropdown('existingDucts')?.value() || 'good';
const extras: Record<string, number> = {
'good': 0,
'needs-repair': 500,
'needs-replacement': 2500,
'none': 4000
};
return extras[ducts] || 0;
};
const getBrandMultiplier = () => {
const brand = systemSection.dropdown('brand')?.value() || 'mid-range';
const multipliers: Record<string, number> = {
'economy': 1.0,
'mid-range': 1.15,
'premium': 1.3,
'luxury': 1.5
};
return multipliers[brand] || 1;
};
summarySection.addRow(row => {
row.addPriceDisplay('equipmentCost', {
label: 'Equipment Cost',
computedValue: () => {
const systemType = systemSection.radioButton('systemType')?.value() || 'full-system';
const efficiency = systemSection.dropdown('efficiency')?.value() || 'high';
const sqft = homeSection.integer('squareFootage')?.value() || 2000;
const zones = systemSection.integer('zones')?.value() || 1;
let baseCost = systemBaseCosts[systemType] || 6500;
const efficiencyMult = efficiencyMultipliers[efficiency] || 1;
const brandMult = getBrandMultiplier();
// Size adjustment
const sizeAdjustment = Math.max(0, Math.floor((sqft - 1500) / 500)) * sizeAdjustmentPer500;
// Zone adjustment for mini-splits
if (systemType === 'mini-split' && zones > 1) {
baseCost += (zones - 1) * 1200;
}
return Math.round(baseCost * efficiencyMult * brandMult + sizeAdjustment);
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('laborCost', {
label: 'Installation Labor',
computedValue: () => {
const systemType = systemSection.radioButton('systemType')?.value() || 'full-system';
const homeTypeMult = getHomeTypeMultiplier();
// Base labor costs by system type
const laborCosts: Record<string, number> = {
'central-ac': 1500,
'furnace-gas': 1200,
'furnace-electric': 1000,
'heat-pump': 1800,
'mini-split': 1200,
'full-system': 2500
};
const baseLaborCost = laborCosts[systemType] || 2500;
return Math.round(baseLaborCost * homeTypeMult);
},
variant: 'default'
}, '1fr');
});
summarySection.addRow(row => {
row.addPriceDisplay('additionalWork', {
label: 'Additional Work',
computedValue: () => {
return getHomeAgeExtra() + getDuctworkExtra();
},
variant: 'default',
prefix: '+'
}, '1fr');
row.addPriceDisplay('addonsTotal', {
label: 'Add-ons & Options',
computedValue: () => {
let total = 0;
if (addonsSection.checkbox('smartThermostat')?.value()) total += 350;
if (addonsSection.checkbox('airPurifier')?.value()) total += 800;
if (addonsSection.checkbox('humidifier')?.value()) total += 500;
if (addonsSection.checkbox('uvLight')?.value()) total += 400;
if (addonsSection.checkbox('zoning')?.value()) total += 2000;
if (addonsSection.checkbox('extendedWarranty')?.value()) total += 500;
if (addonsSection.checkbox('permitHandling')?.value()) total += 200;
if (addonsSection.checkbox('oldSystemRemoval')?.value()) total += 300;
return total;
},
variant: 'default',
prefix: '+'
}, '1fr');
});
summarySection.addRow(row => {
row.addPriceDisplay('travelFee', {
label: 'Travel Fee',
computedValue: () => getTravelFee(),
variant: 'default',
prefix: '+',
isVisible: () => getTravelFee() > 0
});
});
summarySection.addSpacer({ showLine: true, lineStyle: 'solid', lineColor: '#e2e8f0' });
summarySection.addRow(row => {
row.addPriceDisplay('totalEstimate', {
label: 'Total Estimated Cost',
computedValue: () => {
const systemType = systemSection.radioButton('systemType')?.value() || 'full-system';
const efficiency = systemSection.dropdown('efficiency')?.value() || 'high';
const sqft = homeSection.integer('squareFootage')?.value() || 2000;
const zones = systemSection.integer('zones')?.value() || 1;
// Equipment cost
let baseCost = systemBaseCosts[systemType] || 6500;
const efficiencyMult = efficiencyMultipliers[efficiency] || 1;
const brandMult = getBrandMultiplier();
const sizeAdjustment = Math.max(0, Math.floor((sqft - 1500) / 500)) * sizeAdjustmentPer500;
if (systemType === 'mini-split' && zones > 1) {
baseCost += (zones - 1) * 1200;
}
let equipmentCost = baseCost * efficiencyMult * brandMult + sizeAdjustment;
// Labor cost
const laborCosts: Record<string, number> = {
'central-ac': 1500,
'furnace-gas': 1200,
'furnace-electric': 1000,
'heat-pump': 1800,
'mini-split': 1200,
'full-system': 2500
};
const laborCost = (laborCosts[systemType] || 2500) * getHomeTypeMultiplier();
// Additional work
const additionalWork = getHomeAgeExtra() + getDuctworkExtra();
// Add-ons
let addons = 0;
if (addonsSection.checkbox('smartThermostat')?.value()) addons += 350;
if (addonsSection.checkbox('airPurifier')?.value()) addons += 800;
if (addonsSection.checkbox('humidifier')?.value()) addons += 500;
if (addonsSection.checkbox('uvLight')?.value()) addons += 400;
if (addonsSection.checkbox('zoning')?.value()) addons += 2000;
if (addonsSection.checkbox('extendedWarranty')?.value()) addons += 500;
if (addonsSection.checkbox('permitHandling')?.value()) addons += 200;
if (addonsSection.checkbox('oldSystemRemoval')?.value()) addons += 300;
const travelFee = getTravelFee();
return Math.round(equipmentCost + laborCost + additionalWork + addons + travelFee);
},
variant: 'large'
});
});
summarySection.addRow(row => {
row.addTextPanel('financing', {
computedValue: () => {
const systemType = systemSection.radioButton('systemType')?.value() || 'full-system';
const efficiency = systemSection.dropdown('efficiency')?.value() || 'high';
const sqft = homeSection.integer('squareFootage')?.value() || 2000;
// Calculate rough total for financing display
let total = (systemBaseCosts[systemType] || 6500) * (efficiencyMultipliers[efficiency] || 1) * getBrandMultiplier();
total += Math.max(0, Math.floor((sqft - 1500) / 500)) * sizeAdjustmentPer500;
total += 2500 + 500; // rough labor + base addons
const monthly = Math.round(total / 60);
return `Financing available: As low as $${monthly}/month for 60 months`;
},
customStyles: { 'font-size': '0.9rem', 'color': '#059669', 'font-weight': '500' }
});
});
const finalSection = form.addSubform('final', {
title: '๐งพ Summary',
isCollapsible: false,
sticky: 'bottom'
});
finalSection.addRow(row => {
row.addPriceDisplay('totalEstimate', {
label: 'Total Estimated Cost',
computedValue: () => {
const systemType = systemSection.radioButton('systemType')?.value() || 'full-system';
const efficiency = systemSection.dropdown('efficiency')?.value() || 'high';
const sqft = homeSection.integer('squareFootage')?.value() || 2000;
const zones = systemSection.integer('zones')?.value() || 1;
let baseCost = systemBaseCosts[systemType] || 6500;
const efficiencyMult = efficiencyMultipliers[efficiency] || 1;
const brandMult = getBrandMultiplier();
const sizeAdjustment = Math.max(0, Math.floor((sqft - 1500) / 500)) * sizeAdjustmentPer500;
if (systemType === 'mini-split' && zones > 1) {
baseCost += (zones - 1) * 1200;
}
let equipmentCost = baseCost * efficiencyMult * brandMult + sizeAdjustment;
const laborCosts: Record<string, number> = {
'central-ac': 1500,
'furnace-gas': 1200,
'furnace-electric': 1000,
'heat-pump': 1800,
'mini-split': 1200,
'full-system': 2500
};
const laborCost = (laborCosts[systemType] || 2500) * getHomeTypeMultiplier();
const additionalWork = getHomeAgeExtra() + getDuctworkExtra();
let addons = 0;
if (addonsSection.checkbox('smartThermostat')?.value()) addons += 350;
if (addonsSection.checkbox('airPurifier')?.value()) addons += 800;
if (addonsSection.checkbox('humidifier')?.value()) addons += 500;
if (addonsSection.checkbox('uvLight')?.value()) addons += 400;
if (addonsSection.checkbox('zoning')?.value()) addons += 2000;
if (addonsSection.checkbox('extendedWarranty')?.value()) addons += 500;
if (addonsSection.checkbox('permitHandling')?.value()) addons += 200;
if (addonsSection.checkbox('oldSystemRemoval')?.value()) addons += 300;
const travelFee = getTravelFee();
return Math.round(equipmentCost + laborCost + additionalWork + addons + travelFee);
},
variant: 'large'
});
});
finalSection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'Final price determined after on-site evaluation.',
customStyles: { 'font-size': '0.85rem', 'color': '#94a3b8', 'font-style': 'italic' }
});
});
form.configureSubmitButton({
label: 'Request Free Quote'
});
}