<?php

namespace PloverCRM\Modules\NativeCRM;

/**
 * Custom Fields Manager
 * 
 * Handles CRUD operations for custom fields
 */
class CustomFieldsManager
{
    /**
     * Get all custom fields
     * 
     * @return array
     */
    public function getAllFields(): array
    {
        return get_option('plover_crm_custom_fields', []);
    }

    /**
     * Save custom fields
     * 
     * @param array $fields
     * @return bool
     */
    public function saveFields(array $fields): bool
    {
        return update_option('plover_crm_custom_fields', $fields);
    }

    /**
     * Add a new custom field
     * 
     * @param array $field
     * @return bool
     */
    public function addField(array $field): bool
    {
        $fields = $this->getAllFields();
        
        // Generate slug if not provided
        if (empty($field['slug'])) {
            $field['slug'] = sanitize_title($field['label']);
        }
        
        // Check if slug already exists
        foreach ($fields as $existingField) {
            if ($existingField['slug'] === $field['slug']) {
                return false;
            }
        }
        
        // Add order if not set
        if (!isset($field['order'])) {
            $field['order'] = count($fields);
        }
        
        // Sanitize field data
        $field = $this->sanitizeFieldData($field);
        
        $fields[] = $field;
        
        return $this->saveFields($fields);
    }

    /**
     * Update an existing custom field
     * 
     * @param string $slug
     * @param array $field
     * @return bool
     */
    public function updateField(string $slug, array $field): bool
    {
        $fields = $this->getAllFields();
        $updated = false;
        
        // Sanitize field data
        $field = $this->sanitizeFieldData($field);
        
        foreach ($fields as $key => $existingField) {
            if ($existingField['slug'] === $slug) {
                $fields[$key] = array_merge($existingField, $field);
                $updated = true;
                break;
            }
        }
        
        if (!$updated) {
            return false;
        }
        
        return $this->saveFields($fields);
    }

    /**
     * Delete a custom field
     * 
     * @param string $slug
     * @return bool
     */
    public function deleteField(string $slug): bool
    {
        $fields = $this->getAllFields();
        $newFields = [];
        
        foreach ($fields as $field) {
            if ($field['slug'] !== $slug) {
                $newFields[] = $field;
            }
        }
        
        return $this->saveFields($newFields);
    }

    /**
     * Reorder custom fields
     * 
     * @param array $order Array of slugs in desired order
     * @return bool
     */
    public function reorderFields(array $order): bool
    {
        $fields = $this->getAllFields();
        $orderedFields = [];
        
        // Create a map of slug => field
        $fieldMap = [];
        foreach ($fields as $field) {
            $fieldMap[$field['slug']] = $field;
        }
        
        // Reorder based on provided order
        foreach ($order as $index => $slug) {
            if (isset($fieldMap[$slug])) {
                $fieldMap[$slug]['order'] = $index;
                $orderedFields[] = $fieldMap[$slug];
            }
        }
        
        return $this->saveFields($orderedFields);
    }

    /**
     * Sanitize field data
     * 
     * Converts string booleans from AJAX to actual booleans
     * 
     * @param array $field
     * @return array
     */
    private function sanitizeFieldData(array $field): array
    {
        // Convert readonly to boolean
        // AJAX sends "true"/"false" strings or "1"/"0" or actual booleans
        if (isset($field['readonly'])) {
            $field['readonly'] = filter_var($field['readonly'], FILTER_VALIDATE_BOOLEAN);
        } else {
            $field['readonly'] = false;
        }

        if (isset($field['system'])) {
            $field['system'] = filter_var($field['system'], FILTER_VALIDATE_BOOLEAN);
        }
        
        // Sanitize other fields
        if (isset($field['label'])) {
            $field['label'] = sanitize_text_field($field['label']);
        }
        
        if (isset($field['slug'])) {
            $field['slug'] = sanitize_key($field['slug']);
        }
        
        if (isset($field['type'])) {
            $field['type'] = sanitize_text_field($field['type']);
        }
        
        if (isset($field['group'])) {
            $field['group'] = sanitize_text_field($field['group']);
        }
        
        if (isset($field['help_text'])) {
            $field['help_text'] = sanitize_text_field($field['help_text']);
        }

        if (isset($field['owner_capability'])) {
            $field['owner_capability'] = sanitize_text_field($field['owner_capability']);
        }

        if (isset($field['visibility'])) {
            $field['visibility'] = sanitize_text_field($field['visibility']);
        }
        
        // Sanitize options array
        if (isset($field['options']) && is_array($field['options'])) {
            $field['options'] = array_map('sanitize_text_field', $field['options']);
        }
        
        return $field;
    }

    /**
     * Get custom field value for a contact
     * 
     * @param int $contact_id
     * @param string $slug
     * @return mixed
     */
    public function getContactFieldValue(int $contact_id, string $slug)
    {
        return get_post_meta($contact_id, 'plover_crm_cf_' . $slug, true);
    }

    /**
     * Get all custom field values for a contact
     * 
     * @param int $contact_id
     * @return array
     */
    public function getContactCustomFields(int $contact_id): array
    {
        $fields = $this->getAllFields();
        $values = [];
        
        foreach ($fields as $field) {
            $values[$field['slug']] = $this->getContactFieldValue($contact_id, $field['slug']);
        }
        
        return $values;
    }

    /**
     * Save custom field values for a contact
     * 
     * @param int $contact_id
     * @param array $post_data
     * @return void
     */
    public function saveContactCustomFields(int $contact_id, array $post_data): void
    {
        $fields = $this->getAllFields();
        
        foreach ($fields as $field) {
            $key = 'plover_crm_cf_' . $field['slug'];
            
            if (isset($post_data[$key])) {
                $value = $this->sanitizeFieldValue($post_data[$key], $field['type']);
                update_post_meta($contact_id, $key, $value);
            }
        }
    }

    /**
     * Sanitize field value based on type
     * 
     * @param mixed $value
     * @param string $type
     * @return mixed
     */
    private function sanitizeFieldValue($value, string $type)
    {
        switch ($type) {
            case 'text':
            case 'select':
            case 'radio':
                return sanitize_text_field($value);
            
            case 'textarea':
                return sanitize_textarea_field($value);
            
            case 'email':
                return sanitize_email($value);
            
            case 'url':
                return esc_url_raw($value);
            
            case 'number':
                return floatval($value);
            
            case 'checkbox':
                // Handle array of values for multiple checkboxes
                if (is_array($value)) {
                    return array_map('sanitize_text_field', $value);
                }
                return (bool) $value;
            
            case 'date':
                return sanitize_text_field($value);
            
            default:
                return sanitize_text_field($value);
        }
    }
}
