<?php
/**
 * Lead Form Widget for BoostBot
 *
 * Interactive lead capture form with animated labels.
 *
 * @package BoostBot
 * @since 1.0.0
 */

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

/**
 * Class BoostBot_Lead_Form_Widget
 *
 * Lead capture form with animated labels and multi-step support.
 */
class BoostBot_Lead_Form_Widget extends BoostBot_Widget_Base {

    /**
     * Widget ID.
     *
     * @var string
     */
    protected $id = 'lead_form';

    /**
     * Available in free version (for homepage only).
     *
     * @var bool
     */
    protected $is_free = true;

    /**
     * Get widget name.
     *
     * @since 1.0.0
     * @return string Widget name.
     */
    public function get_name(): string {
        return __( 'Lead Form', 'boostbot' );
    }

    /**
     * Get widget description.
     *
     * @since 1.0.0
     * @return string Widget description.
     */
    public function get_description(): string {
        return __( 'Interactive form for capturing leads with animations', 'boostbot' );
    }

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

    /**
     * Get widget schema.
     *
     * @since 1.0.0
     * @return array Widget schema.
     */
    public function get_schema(): array {
        // Use Hebrew strings directly (plugin is Hebrew-only for now)
        return array(
            'title'           => 'השאירו פרטים',
            'fields'          => $this->get_default_fields(),
            'submit_text'     => 'שלח',
            'success_message' => 'תודה! נחזור אליכם בהקדם',
            'animation'       => array(
                'enabled'       => true,
                'type'          => 'typewriter', // typewriter, fade, slide
                'speed'         => 30, // ms per character
                'cursor'        => true,
            ),
        );
    }

    /**
     * Get default form fields.
     *
     * @since 1.0.0
     * @return array Default fields.
     */
    private function get_default_fields(): array {
        // Use Hebrew strings directly (plugin is Hebrew-only for now)
        return array(
            array(
                'name'          => 'name',
                'type'          => 'text',
                'label'         => 'שם מלא',
                'required'      => true,
                'placeholder'   => 'הזינו את שמכם',
                'focus_message' => 'נשמח לדעת איך לפנות אליכם',
                'icon'          => 'user',
            ),
            array(
                'name'          => 'email',
                'type'          => 'email',
                'label'         => 'אימייל',
                'required'      => true,
                'placeholder'   => 'your@email.com',
                'focus_message' => 'נשלח לכאן את הפרטים',
                'icon'          => 'mail',
            ),
            array(
                'name'          => 'phone',
                'type'          => 'tel',
                'label'         => 'טלפון',
                'required'      => false,
                'placeholder'   => '050-0000000',
                'focus_message' => 'כדי שנוכל להתקשר אליכם',
                'icon'          => 'phone',
            ),
            array(
                'name'          => 'message',
                'type'          => 'textarea',
                'label'         => 'הודעה',
                'required'      => false,
                'placeholder'   => 'ספרו לנו איך נוכל לעזור...',
                'focus_message' => 'נשמח לשמוע מה על לבכם',
                'icon'          => 'message-square',
                'rows'          => 3,
            ),
        );
    }

    /**
     * Get widget configuration.
     *
     * @since 1.0.0
     * @param array $data Optional custom data.
     * @return array Widget configuration.
     */
    public function get_config( array $data = array() ): array {
        $config = parent::get_config( $data );

        // Merge custom fields if provided
        if ( ! empty( $data['custom_fields'] ) && is_array( $data['custom_fields'] ) ) {
            $config['schema']['fields'] = array_merge(
                $config['schema']['fields'],
                $data['custom_fields']
            );
        }

        // Allow customizing submit text
        if ( ! empty( $data['submit_text'] ) ) {
            $config['schema']['submit_text'] = sanitize_text_field( $data['submit_text'] );
        }

        // Allow customizing success message
        if ( ! empty( $data['success_message'] ) ) {
            $config['schema']['success_message'] = sanitize_text_field( $data['success_message'] );
        }

        // Add form settings
        $config['settings'] = array(
            'auto_focus'     => true,
            'show_progress'  => false,
            'instant_submit' => false,
        );

        return $config;
    }

    /**
     * Validate submitted data.
     *
     * @since 1.0.0
     * @param array $data Submitted data.
     * @return array Validation result.
     */
    public function validate( array $data ): array {
        $errors = array();
        $schema = $this->get_schema();

        foreach ( $schema['fields'] as $field ) {
            $field_name  = $field['name'];
            $field_value = $data[ $field_name ] ?? '';
            $field_label = $field['label'];

            // Check required
            if ( ! empty( $field['required'] ) ) {
                $error = $this->validate_required( $field_value, $field_label );
                if ( $error ) {
                    $errors[ $field_name ] = $error;
                    continue;
                }
            }

            // Type-specific validation
            if ( ! empty( $field_value ) ) {
                switch ( $field['type'] ) {
                    case 'email':
                        $error = $this->validate_email( $field_value );
                        if ( $error ) {
                            $errors[ $field_name ] = $error;
                        }
                        break;

                    case 'tel':
                    case 'phone':
                        $error = $this->validate_phone( $field_value );
                        if ( $error ) {
                            $errors[ $field_name ] = $error;
                        }
                        break;
                }
            }
        }

        // Allow filtering validation
        $errors = $this->apply_filters( 'validation_errors', $errors, $data );

        return array(
            'valid'  => empty( $errors ),
            'errors' => $errors,
        );
    }

    /**
     * Process submitted data.
     *
     * @since 1.0.0
     * @param array $data    Submitted data.
     * @param array $context Submission context.
     * @return array Processing result.
     */
    public function process( array $data, array $context = array() ): array {
        // Sanitize all fields
        $sanitized = array();
        $schema = $this->get_schema();

        foreach ( $schema['fields'] as $field ) {
            $field_name = $field['name'];
            if ( isset( $data[ $field_name ] ) ) {
                $sanitized[ $field_name ] = $this->sanitize_field(
                    $data[ $field_name ],
                    $field['type']
                );
            }
        }

        // Create lead
        $lead_model = new BoostBot_Lead_Model();

        $lead_data = array(
            'conversation_id' => $context['conversation_id'] ?? null,
            'visitor_id'      => $context['visitor_id'] ?? null,
            'name'            => $sanitized['name'] ?? '',
            'email'           => $sanitized['email'] ?? '',
            'phone'           => $sanitized['phone'] ?? '',
            'company'         => $sanitized['company'] ?? '',
            'lead_status'     => 'new',
            'lead_score'      => $this->calculate_lead_score( $sanitized ),
            'source_page'     => $context['page_url'] ?? '',
            'form_data'       => $sanitized,
            'notes'           => $sanitized['message'] ?? '',
        );

        // Allow filtering lead data before save
        $lead_data = $this->apply_filters( 'lead_data', $lead_data, $sanitized, $context );

        $lead_id = $lead_model->create( $lead_data );

        if ( ! $lead_id ) {
            throw new Exception( esc_html( __( 'Error saving lead', 'boostbot' ) ) );
        }

        BoostBot_Logger::info( 'Lead created from widget', array(
            'lead_id'         => $lead_id,
            'widget'          => $this->id,
            'conversation_id' => $context['conversation_id'] ?? '',
        ) );

        // Send notification if enabled
        $this->maybe_send_notification( $lead_id, $sanitized );

        // Fire action hook
        $this->do_action( 'lead_created', $lead_id, $sanitized, $context );

        // Also fire generic hook
        do_action( 'boostbot_lead_created', $lead_id, $sanitized );

        return array(
            'lead_id' => $lead_id,
            'message' => $this->get_schema()['success_message'],
        );
    }

    /**
     * Send notification email if enabled.
     *
     * @since 1.0.0
     * @param int   $lead_id Lead ID.
     * @param array $data    Lead data.
     */
    private function maybe_send_notification( int $lead_id, array $data ) {
        // Check if notifications are enabled
        $notify = BoostBot_Settings::get( 'lead_notifications', true );

        if ( ! $notify ) {
            return;
        }

        $subject = sprintf(
            /* translators: %s: Lead name */
            __( 'New Lead: %s', 'boostbot' ),
            $data['name'] ?? __( 'No name', 'boostbot' )
        );

        $message = __( 'A new lead was received from the chatbot:', 'boostbot' ) . "\n\n";
        $message .= __( 'Name:', 'boostbot' ) . ' ' . ( $data['name'] ?? '-' ) . "\n";
        $message .= __( 'Email:', 'boostbot' ) . ' ' . ( $data['email'] ?? '-' ) . "\n";
        $message .= __( 'Phone:', 'boostbot' ) . ' ' . ( $data['phone'] ?? __( 'Not provided', 'boostbot' ) ) . "\n";

        if ( ! empty( $data['message'] ) ) {
            $message .= __( 'Message:', 'boostbot' ) . "\n" . $data['message'] . "\n";
        }

        $message .= "\n" . sprintf(
            /* translators: %s: Admin URL */
            __( 'View lead: %s', 'boostbot' ),
            admin_url( 'admin.php?page=boostbot#/leads/' . $lead_id )
        );

        $this->send_admin_notification( $subject, $message );
    }
}
