<?php
/**
 * Form Field Model for BoostBot.
 *
 * Database model for managing form widget fields.
 *
 * @package BoostBot
 * @since   1.0.0
 */

// Prevent direct access.
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Class BoostBot_Form_Field_Model
 *
 * Handles CRUD operations for form fields.
 *
 * @since 1.0.0
 */
class BoostBot_Form_Field_Model extends BoostBot_Base_Model {

    /**
     * Field type constants.
     */
    const TYPE_TEXT     = 'text';
    const TYPE_EMAIL    = 'email';
    const TYPE_PHONE    = 'phone';
    const TYPE_TEXTAREA = 'textarea';
    const TYPE_SELECT   = 'select';
    const TYPE_DATE     = 'date';
    const TYPE_NUMBER   = 'number';
    const TYPE_CHECKBOX = 'checkbox';

    /**
     * Constructor.
     */
    public function __construct() {
        parent::__construct();
        $this->table_name = self::sanitize_identifier( $this->wpdb->prefix . 'boostbot_form_fields' );
        $this->fillable   = array(
            'widget_id',
            'field_type',
            'label',
            'placeholder',
            'name',
            'is_required',
            'validation_rules',
            'options',
            'sort_order',
        );
        $this->column_types = array(
            'id'          => 'bigint',
            'widget_id'   => 'bigint',
            'is_required' => 'tinyint',
            'sort_order'  => 'integer',
        );
    }

    /**
     * Get all valid field types.
     *
     * @return array Field types with labels.
     */
    public static function get_field_types() {
        return array(
            self::TYPE_TEXT     => __( 'טקסט', 'boostbot' ),
            self::TYPE_EMAIL    => __( 'אימייל', 'boostbot' ),
            self::TYPE_PHONE    => __( 'טלפון', 'boostbot' ),
            self::TYPE_TEXTAREA => __( 'אזור טקסט', 'boostbot' ),
            self::TYPE_SELECT   => __( 'בחירה', 'boostbot' ),
            self::TYPE_DATE     => __( 'תאריך', 'boostbot' ),
            self::TYPE_NUMBER   => __( 'מספר', 'boostbot' ),
            self::TYPE_CHECKBOX => __( 'תיבת סימון', 'boostbot' ),
        );
    }

    /**
     * Validate data before insert/update.
     *
     * @param array    $data The data to validate.
     * @param int|null $id   Optional. The record ID for updates.
     * @return true|WP_Error True if valid, WP_Error otherwise.
     */
    public function validate( $data, $id = null ) {
        $errors = new WP_Error();

        // Validate widget_id on create.
        if ( null === $id && ( ! isset( $data['widget_id'] ) || empty( $data['widget_id'] ) ) ) {
            $errors->add( 'widget_id_required', __( 'מזהה ווידג\'ט הוא שדה חובה', 'boostbot' ) );
        }

        // Validate field_type.
        if ( isset( $data['field_type'] ) ) {
            $valid_types = array_keys( self::get_field_types() );
            if ( ! in_array( $data['field_type'], $valid_types, true ) ) {
                $errors->add( 'invalid_field_type', __( 'סוג שדה לא תקין', 'boostbot' ) );
            }
        } elseif ( null === $id ) {
            $errors->add( 'field_type_required', __( 'סוג שדה הוא שדה חובה', 'boostbot' ) );
        }

        // Validate label.
        if ( isset( $data['label'] ) && empty( trim( $data['label'] ) ) ) {
            $errors->add( 'label_required', __( 'תווית השדה היא שדה חובה', 'boostbot' ) );
        } elseif ( null === $id && ! isset( $data['label'] ) ) {
            $errors->add( 'label_required', __( 'תווית השדה היא שדה חובה', 'boostbot' ) );
        }

        // Validate name.
        if ( isset( $data['name'] ) && empty( trim( $data['name'] ) ) ) {
            $errors->add( 'name_required', __( 'שם השדה הוא שדה חובה', 'boostbot' ) );
        } elseif ( null === $id && ! isset( $data['name'] ) ) {
            $errors->add( 'name_required', __( 'שם השדה הוא שדה חובה', 'boostbot' ) );
        }

        if ( $errors->has_errors() ) {
            return $errors;
        }

        return true;
    }

    /**
     * Sanitize data before insert/update.
     *
     * @param array $data The data to sanitize.
     * @return array The sanitized data.
     */
    public function sanitize( $data ) {
        $sanitized = array();

        if ( isset( $data['widget_id'] ) ) {
            $sanitized['widget_id'] = absint( $data['widget_id'] );
        }

        if ( isset( $data['field_type'] ) ) {
            $sanitized['field_type'] = sanitize_key( $data['field_type'] );
        }

        if ( isset( $data['label'] ) ) {
            $sanitized['label'] = sanitize_text_field( $data['label'] );
        }

        if ( isset( $data['placeholder'] ) ) {
            $sanitized['placeholder'] = sanitize_text_field( $data['placeholder'] );
        }

        if ( isset( $data['name'] ) ) {
            $sanitized['name'] = sanitize_key( $data['name'] );
        }

        if ( isset( $data['is_required'] ) ) {
            $sanitized['is_required'] = absint( $data['is_required'] ) ? 1 : 0;
        }

        if ( isset( $data['validation_rules'] ) ) {
            if ( is_array( $data['validation_rules'] ) ) {
                $sanitized['validation_rules'] = wp_json_encode( $data['validation_rules'] );
            } else {
                $sanitized['validation_rules'] = $data['validation_rules'];
            }
        }

        if ( isset( $data['options'] ) ) {
            if ( is_array( $data['options'] ) ) {
                $sanitized['options'] = wp_json_encode( $data['options'] );
            } else {
                $sanitized['options'] = $data['options'];
            }
        }

        if ( isset( $data['sort_order'] ) ) {
            $sanitized['sort_order'] = absint( $data['sort_order'] );
        }

        return $sanitized;
    }

    /**
     * Get fields by widget ID.
     *
     * @param int $widget_id Widget ID.
     * @return array Array of field objects.
     */
    public function get_by_widget( $widget_id ) {
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $fields = $this->wpdb->get_results(
            // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
            $this->wpdb->prepare(
                "SELECT * FROM {$this->table_name} WHERE widget_id = %d ORDER BY sort_order ASC", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
                $widget_id
            )
        );

        // Decode JSON fields.
        foreach ( $fields as $field ) {
            if ( ! empty( $field->validation_rules ) ) {
                $field->validation_rules = json_decode( $field->validation_rules, true );
            }
            if ( ! empty( $field->options ) ) {
                $field->options = json_decode( $field->options, true );
            }
        }

        return $fields;
    }

    /**
     * Create field with auto sort_order.
     *
     * @param array $data Field data.
     * @return int|false New field ID or false.
     */
    public function create( $data ) {
        // Auto-calculate sort_order if not provided.
        if ( ! isset( $data['sort_order'] ) && isset( $data['widget_id'] ) ) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $max_order = $this->wpdb->get_var(
                // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
                $this->wpdb->prepare(
                    "SELECT MAX(sort_order) FROM {$this->table_name} WHERE widget_id = %d", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
                    $data['widget_id']
                )
            );
            $data['sort_order'] = ( (int) $max_order ) + 1;
        }

        return parent::create( $data );
    }

    /**
     * Delete all fields for a widget.
     *
     * @param int $widget_id Widget ID.
     * @return bool True on success.
     */
    public function delete_by_widget( $widget_id ) {
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $result = $this->wpdb->delete(
            $this->table_name,
            array( 'widget_id' => $widget_id ),
            array( '%d' )
        );

        return false !== $result;
    }

    /**
     * Reorder fields.
     *
     * @param int   $widget_id Widget ID.
     * @param array $field_ids Ordered array of field IDs.
     * @return bool True on success.
     */
    public function reorder_fields( $widget_id, $field_ids ) {
        foreach ( $field_ids as $index => $field_id ) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $this->wpdb->update(
                $this->table_name,
                array( 'sort_order' => $index ),
                array(
                    'id'        => $field_id,
                    'widget_id' => $widget_id,
                ),
                array( '%d' ),
                array( '%d', '%d' )
            );
        }

        return true;
    }

    /**
     * Duplicate fields from one widget to another.
     *
     * @param int $source_widget_id Source widget ID.
     * @param int $target_widget_id Target widget ID.
     * @return bool True on success.
     */
    public function duplicate_fields( $source_widget_id, $target_widget_id ) {
        $fields = $this->get_by_widget( $source_widget_id );

        foreach ( $fields as $field ) {
            $new_field_data = array(
                'widget_id'        => $target_widget_id,
                'field_type'       => $field->field_type,
                'label'            => $field->label,
                'placeholder'      => $field->placeholder,
                'name'             => $field->name,
                'is_required'      => $field->is_required,
                'validation_rules' => $field->validation_rules,
                'options'          => $field->options,
                'sort_order'       => $field->sort_order,
            );

            $this->create( $new_field_data );
        }

        return true;
    }
}




