<?php
/**
 * Widget Base Class for BoostBot
 *
 * Abstract base class for all interactive widgets.
 *
 * @package BoostBot
 * @since 1.0.0
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Abstract class BoostBot_Widget_Base
 *
 * Base class that all widgets must extend.
 */
abstract class BoostBot_Widget_Base {

    /**
     * Widget unique identifier.
     *
     * @var string
     */
    protected $id = '';

    /**
     * Whether widget is available in free version.
     *
     * @var bool
     */
    protected $is_free = false;

    /**
     * Get the widget name.
     *
     * @since 1.0.0
     * @return string Widget name.
     */
    abstract public function get_name(): string;

    /**
     * Get the widget description.
     *
     * @since 1.0.0
     * @return string Widget description.
     */
    abstract public function get_description(): string;

    /**
     * Get the widget schema (fields definition).
     *
     * @since 1.0.0
     * @return array Widget schema.
     */
    abstract public function get_schema(): array;

    /**
     * Validate submitted data.
     *
     * @since 1.0.0
     * @param array $data Submitted data.
     * @return array Validation result with 'valid' and 'errors' keys.
     */
    abstract public function validate( array $data ): array;

    /**
     * Process submitted data.
     *
     * @since 1.0.0
     * @param array $data    Submitted data.
     * @param array $context Submission context.
     * @return array Processing result.
     */
    abstract public function process( array $data, array $context = array() ): array;

    /**
     * Get widget icon.
     *
     * @since 1.0.0
     * @return string Icon name (Lucide icon).
     */
    public function get_icon(): string {
        return 'box';
    }

    /**
     * Check if widget is free.
     *
     * @since 1.0.0
     * @return bool True if free.
     */
    public function is_free(): bool {
        return $this->is_free;
    }

    /**
     * Get scripts required by widget.
     *
     * @since 1.0.0
     * @return array Script handles.
     */
    public function get_scripts(): array {
        return array();
    }

    /**
     * Get styles required by widget.
     *
     * @since 1.0.0
     * @return array Style handles.
     */
    public function get_styles(): array {
        return array();
    }

    /**
     * Get widget configuration for frontend.
     *
     * @since 1.0.0
     * @param array $data Optional data.
     * @return array Configuration.
     */
    public function get_config( array $data = array() ): array {
        return array(
            'id'          => $this->id,
            'name'        => $this->get_name(),
            'description' => $this->get_description(),
            'schema'      => $this->get_schema(),
            'is_rtl'      => is_rtl(),
            'colors'      => array(
                'primary' => BoostBot_Settings::get( 'primary_color', '#3BC2D0' ),
                'accent'  => BoostBot_Settings::get( 'accent_color', '#E32774' ),
            ),
        );
    }

    /**
     * Sanitize a field value.
     *
     * @since 1.0.0
     * @param mixed  $value Field value.
     * @param string $type  Field type.
     * @return mixed Sanitized value.
     */
    protected function sanitize_field( $value, string $type ) {
        switch ( $type ) {
            case 'email':
                return sanitize_email( $value );

            case 'phone':
            case 'tel':
                return preg_replace( '/[^\d\+\-\s\(\)]/', '', $value );

            case 'url':
                return esc_url_raw( $value );

            case 'number':
            case 'integer':
                return absint( $value );

            case 'float':
                return floatval( $value );

            case 'textarea':
                return sanitize_textarea_field( $value );

            case 'html':
                return wp_kses_post( $value );

            case 'date':
                return sanitize_text_field( $value );

            case 'time':
                return sanitize_text_field( $value );

            case 'text':
            default:
                return sanitize_text_field( $value );
        }
    }

    /**
     * Validate a required field.
     *
     * @since 1.0.0
     * @param mixed  $value      Field value.
     * @param string $field_name Field name for error message.
     * @return string|null Error message or null if valid.
     */
    protected function validate_required( $value, string $field_name ): ?string {
        if ( empty( $value ) && $value !== '0' && $value !== 0 ) {
            return sprintf(
                /* translators: %s: field name */
                __( '%s is a required field', 'boostbot' ),
                $field_name
            );
        }
        return null;
    }

    /**
     * Validate email field.
     *
     * @since 1.0.0
     * @param string $email Email to validate.
     * @return string|null Error message or null if valid.
     */
    protected function validate_email( string $email ): ?string {
        if ( ! empty( $email ) && ! is_email( $email ) ) {
            return __( 'Invalid email address', 'boostbot' );
        }
        return null;
    }

    /**
     * Validate phone field.
     *
     * @since 1.0.0
     * @param string $phone Phone to validate.
     * @return string|null Error message or null if valid.
     */
    protected function validate_phone( string $phone ): ?string {
        if ( ! empty( $phone ) ) {
            // Remove all non-digit characters for validation
            $digits_only = preg_replace( '/\D/', '', $phone );

            // Israeli phones: 9-10 digits (with or without country code)
            if ( strlen( $digits_only ) < 9 || strlen( $digits_only ) > 15 ) {
                return __( 'Invalid phone number', 'boostbot' );
            }
        }
        return null;
    }

    /**
     * Send admin notification.
     *
     * @since 1.0.0
     * @param string $subject Email subject.
     * @param string $message Email message.
     * @return bool True if sent.
     */
    protected function send_admin_notification( string $subject, string $message ): bool {
        $admin_email = get_option( 'admin_email' );

        if ( ! $admin_email ) {
            return false;
        }

        // Add site name to subject
        $subject = '[' . get_bloginfo( 'name' ) . '] ' . $subject;

        // Add footer to message
        $message .= "\n\n---\n";
        $message .= sprintf(
            /* translators: %s: site URL */
            __( 'This message was sent from %s', 'boostbot' ),
            home_url()
        );

        return wp_mail( $admin_email, $subject, $message );
    }

    /**
     * Calculate lead score from data.
     *
     * @since 1.0.0
     * @param array $data Lead data.
     * @return int Score (0-100).
     */
    protected function calculate_lead_score( array $data ): int {
        $score = 0;

        // Base score for having email
        if ( ! empty( $data['email'] ) ) {
            $score += 20;
        }

        // Name provided
        if ( ! empty( $data['name'] ) ) {
            $score += 10;
        }

        // Phone provided
        if ( ! empty( $data['phone'] ) ) {
            $score += 25;
        }

        // Company provided
        if ( ! empty( $data['company'] ) ) {
            $score += 15;
        }

        // Message provided
        if ( ! empty( $data['message'] ) ) {
            $score += 10;
            // Longer messages = more engaged
            if ( mb_strlen( $data['message'] ) > 50 ) {
                $score += 10;
            }
        }

        // Specific product interest
        if ( ! empty( $data['product_id'] ) ) {
            $score += 10;
        }

        return min( 100, $score );
    }

    /**
     * Fire widget action hook.
     *
     * @since 1.0.0
     * @param string $action Action name (without prefix).
     * @param mixed  ...$args Additional arguments.
     */
    protected function do_action( string $action, ...$args ) {
        do_action( "boostbot_widget_{$this->id}_{$action}", ...$args );
    }

    /**
     * Apply widget filter hook.
     *
     * @since 1.0.0
     * @param string $filter Filter name (without prefix).
     * @param mixed  $value  Value to filter.
     * @param mixed  ...$args Additional arguments.
     * @return mixed Filtered value.
     */
    protected function apply_filters( string $filter, $value, ...$args ) {
        return apply_filters( "boostbot_widget_{$this->id}_{$filter}", $value, ...$args );
    }
}








