# Shipping Address Fields - Dynamic via Hooks

## Philosophy: Addon Responsibility, Not Hardcoding

WooNooW should **listen to WooCommerce hooks** to determine which fields are required, not hardcode assumptions about Indonesian vs International shipping.

---

## The Problem with Hardcoding

**Bad Approach (What we almost did):**
```javascript
// ❌ DON'T DO THIS
if (country === 'ID') {
  showSubdistrict = true; // Hardcoded assumption
}
```

**Why it's bad:**
- Assumes all Indonesian shipping needs subdistrict
- Breaks if addon changes requirements
- Not extensible for other countries
- Violates separation of concerns

---

## The Right Approach: Listen to Hooks

**WooCommerce Core Hooks:**

### 1. `woocommerce_checkout_fields` Filter
Addons use this to add/modify/remove fields:

```php
// Example: Indonesian Shipping Addon
add_filter('woocommerce_checkout_fields', function($fields) {
    // Add subdistrict field
    $fields['shipping']['shipping_subdistrict'] = [
        'label'       => __('Subdistrict'),
        'required'    => true,
        'class'       => ['form-row-wide'],
        'priority'    => 65,
    ];
    
    return $fields;
});
```

### 2. `woocommerce_default_address_fields` Filter
Modifies default address fields:

```php
add_filter('woocommerce_default_address_fields', function($fields) {
    // Make postal code required for UPS
    $fields['postcode']['required'] = true;
    
    return $fields;
});
```

### 3. Field Validation Hooks
```php
add_action('woocommerce_checkout_process', function() {
    if (empty($_POST['shipping_subdistrict'])) {
        wc_add_notice(__('Subdistrict is required'), 'error');
    }
});
```

---

## Implementation in WooNooW

### Backend: Expose Checkout Fields via API

**New Endpoint:** `GET /checkout/fields`

```php
// includes/Api/CheckoutController.php

public function get_checkout_fields(WP_REST_Request $request) {
    // Get fields with all filters applied
    $fields = WC()->checkout()->get_checkout_fields();
    
    // Format for frontend
    $formatted = [];
    
    foreach ($fields as $fieldset_key => $fieldset) {
        foreach ($fieldset as $key => $field) {
            $formatted[] = [
                'key'         => $key,
                'fieldset'    => $fieldset_key, // billing, shipping, account, order
                'type'        => $field['type'] ?? 'text',
                'label'       => $field['label'] ?? '',
                'placeholder' => $field['placeholder'] ?? '',
                'required'    => $field['required'] ?? false,
                'class'       => $field['class'] ?? [],
                'priority'    => $field['priority'] ?? 10,
                'options'     => $field['options'] ?? null, // For select fields
                'custom'      => $field['custom'] ?? false, // Custom field flag
            ];
        }
    }
    
    // Sort by priority
    usort($formatted, function($a, $b) {
        return $a['priority'] <=> $b['priority'];
    });
    
    return new WP_REST_Response($formatted, 200);
}
```

### Frontend: Dynamic Field Rendering

**Create Order - Address Section:**

```typescript
// Fetch checkout fields from API
const { data: checkoutFields = [] } = useQuery({
  queryKey: ['checkout-fields'],
  queryFn: () => api.get('/checkout/fields'),
});

// Filter shipping fields
const shippingFields = checkoutFields.filter(
  field => field.fieldset === 'shipping'
);

// Render dynamically
{shippingFields.map(field => {
  // Standard WooCommerce fields
  if (['first_name', 'last_name', 'address_1', 'address_2', 'city', 'state', 'postcode', 'country'].includes(field.key)) {
    return <StandardField key={field.key} field={field} />;
  }
  
  // Custom fields (e.g., subdistrict from addon)
  if (field.custom) {
    return <CustomField key={field.key} field={field} />;
  }
  
  return null;
})}
```

**Field Components:**

```typescript
function StandardField({ field }) {
  return (
    <div className={cn('form-field', field.class)}>
      <label>
        {field.label}
        {field.required && <span className="required">*</span>}
      </label>
      <input
        type={field.type}
        name={field.key}
        placeholder={field.placeholder}
        required={field.required}
      />
    </div>
  );
}

function CustomField({ field }) {
  // Handle custom field types (select, textarea, etc.)
  if (field.type === 'select') {
    return (
      <div className={cn('form-field', field.class)}>
        <label>
          {field.label}
          {field.required && <span className="required">*</span>}
        </label>
        <select name={field.key} required={field.required}>
          {field.options?.map(option => (
            <option key={option.value} value={option.value}>
              {option.label}
            </option>
          ))}
        </select>
      </div>
    );
  }
  
  return <StandardField field={field} />;
}
```

---

## How Addons Work

### Example: Indonesian Shipping Addon

**Addon adds subdistrict field:**
```php
add_filter('woocommerce_checkout_fields', function($fields) {
    $fields['shipping']['shipping_subdistrict'] = [
        'type'        => 'select',
        'label'       => __('Subdistrict'),
        'required'    => true,
        'class'       => ['form-row-wide'],
        'priority'    => 65,
        'options'     => get_subdistricts(), // Addon provides this
        'custom'      => true, // Flag as custom field
    ];
    
    return $fields;
});
```

**WooNooW automatically:**
1. Fetches fields via API
2. Sees `shipping_subdistrict` with `required: true`
3. Renders it in Create Order form
4. Validates it on submit

**No hardcoding needed!**

---

## Benefits

✅ **Addon responsibility** - Addons declare their own requirements
✅ **No hardcoding** - WooNooW just renders what WooCommerce says
✅ **Extensible** - Works with ANY addon (Indonesian, UPS, custom)
✅ **Future-proof** - New addons work automatically
✅ **Separation of concerns** - Each addon manages its own fields

---

## Edge Cases

### Case 1: Subdistrict for Indonesian Shipping
- Addon adds `shipping_subdistrict` field
- WooNooW renders it
- ✅ Works!

### Case 2: UPS Requires Postal Code
- UPS addon sets `postcode.required = true`
- WooNooW renders it as required
- ✅ Works!

### Case 3: Custom Shipping Needs Extra Field
- Addon adds `shipping_delivery_notes` field
- WooNooW renders it
- ✅ Works!

### Case 4: No Custom Fields
- Standard WooCommerce fields only
- WooNooW renders them
- ✅ Works!

---

## Implementation Plan

1. **Backend:**
   - Create `GET /checkout/fields` endpoint
   - Return fields with all filters applied
   - Include field metadata (type, required, options, etc.)

2. **Frontend:**
   - Fetch checkout fields on Create Order page
   - Render fields dynamically based on API response
   - Handle standard + custom field types
   - Validate based on `required` flag

3. **Testing:**
   - Test with no addons (standard fields only)
   - Test with Indonesian shipping addon (subdistrict)
   - Test with UPS addon (postal code required)
   - Test with custom addon (custom fields)

---

## Next Steps

1. Create `CheckoutController.php` with `get_checkout_fields` endpoint
2. Update Create Order to fetch and render fields dynamically
3. Test with Indonesian shipping addon
4. Document for addon developers
