<?php
/**
 * Form Handler Class
 *
 * Handles form submission, validation, and storage.
 *
 * @package PCFormBuilder
 */

class PC_Form_Handler {

    private static $instance = null;

    public static function get_instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct() {
        add_action( 'wp_ajax_pcfb_submit_form', array( $this, 'handle_form_submission' ) );
        add_action( 'wp_ajax_nopriv_pcfb_submit_form', array( $this, 'handle_form_submission' ) );
        add_action( 'wp_ajax_pcfb_add_field', array( $this, 'handle_add_field' ) );
        add_shortcode( 'pcfb-form', array( $this, 'shortcode_form' ) );
    }

    public function handle_add_field() {
        check_ajax_referer( 'pcfb_admin_nonce', 'nonce' );

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( array( 'message' => __( 'Permission denied.', 'pc-form-builder-xyz123' ) ) );
        }

        $field_type = isset( $_POST['field_type'] ) ? sanitize_text_field( $_POST['field_type'] ) : '';
        $field_index = isset( $_POST['field_index'] ) ? intval( $_POST['field_index'] ) : 0;

        if ( empty( $field_type ) ) {
            wp_send_json_error( array( 'message' => __( 'Field type is required.', 'pc-form-builder-xyz123' ) ) );
        }

        require_once PCFB_PLUGIN_DIR . 'admin/class-admin-helper.php';
        $helper = PCFB_Admin_Helper::get_instance();

        ob_start();
        $helper->render_new_field_item( $field_type, $field_index );
        $html = ob_get_clean();

        wp_send_json_success( array( 'html' => $html ) );
    }

    public function shortcode_form( $atts ) {
        $atts = shortcode_atts( array(
            'id' => 0,
        ), $atts );

        if ( empty( $atts['id'] ) ) {
            return '<p>' . esc_html__( 'Form ID is required.', 'pc-form-builder-xyz123' ) . '</p>';
        }

        $form = $this->get_form( intval( $atts['id'] ) );

        if ( ! $form ) {
            return '<p>' . esc_html__( 'Form not found.', 'pc-form-builder-xyz123' ) . '</p>';
        }

        if ( 'active' !== $form->status ) {
            return '<p>' . esc_html__( 'This form is not currently active.', 'pc-form-builder-xyz123' ) . '</p>';
        }

        $fields = $this->get_form_fields( $form->id );
        $settings = maybe_unserialize( $form->settings );

        ob_start();
        include PCFB_PLUGIN_DIR . 'public/templates/form-display.php';
        return ob_get_clean();
    }

    private function get_form( $form_id ) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'pcfb_forms';
        return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table_name} WHERE id = %d", $form_id ) );
    }

    private function get_form_fields( $form_id ) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'pcfb_fields';
        return $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table_name} WHERE form_id = %d ORDER BY sort_order ASC", $form_id ) );
    }

    public function handle_form_submission() {
        check_ajax_referer( 'pcfb_public_nonce', 'nonce' );

        $form_id = isset( $_POST['form_id'] ) ? intval( $_POST['form_id'] ) : 0;
        $form_data = isset( $_POST['form_data'] ) ? $_POST['form_data'] : array();

        if ( empty( $form_id ) ) {
            wp_send_json_error( array( 'message' => __( 'Invalid form ID.', 'pc-form-builder-xyz123' ) ) );
        }

        $form = $this->get_form( $form_id );

        if ( ! $form ) {
            wp_send_json_error( array( 'message' => __( 'Form not found.', 'pc-form-builder-xyz123' ) ) );
        }

        $fields = $this->get_form_fields( $form_id );
        $errors = array();
        $clean_data = array();

        foreach ( $fields as $field ) {
            $value = isset( $form_data[ $field->field_name ] ) ? trim( $form_data[ $field->field_name ] ) : '';
            $validation_rules = maybe_unserialize( $field->validation_rules );

            if ( ! empty( $validation_rules['required'] ) && empty( $value ) ) {
                $errors[ $field->field_name ] = sprintf(
                    __( '%s is required.', 'pc-form-builder-xyz123' ),
                    $field->field_label
                );
            }

            if ( ! empty( $value ) && 'email' === $field->field_type ) {
                if ( ! is_email( $value ) ) {
                    $errors[ $field->field_name ] = __( 'Please enter a valid email address.', 'pc-form-builder-xyz123' );
                }
            }

            $clean_data[ $field->id ] = sanitize_text_field( $value );
        }

        if ( ! empty( $errors ) ) {
            wp_send_json_error( array( 'message' => __( 'Please fix the errors below.', 'pc-form-builder-xyz123' ), 'errors' => $errors ) );
        }

        $response_id = $this->save_response( $form_id, $clean_data );

        if ( $response_id ) {
            $success_message = ! empty( $settings['success_message'] )
                ? $settings['success_message']
                : __( 'Thank you! Your response has been submitted.', 'pc-form-builder-xyz123' );

            wp_send_json_success( array( 'message' => $success_message, 'response_id' => $response_id ) );
        } else {
            wp_send_json_error( array( 'message' => __( 'Failed to save your response. Please try again.', 'pc-form-builder-xyz123' ) ) );
        }
    }

    private function save_response( $form_id, $field_data ) {
        global $wpdb;

        $responses_table = $wpdb->prefix . 'pcfb_responses';
        $response_data_table = $wpdb->prefix . 'pcfb_response_data';

        $user_ip = $_SERVER['REMOTE_ADDR'] ?? '';
        $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';

        $wpdb->insert(
            $responses_table,
            array(
                'form_id'   => $form_id,
                'user_ip'   => $user_ip,
                'user_agent'=> $user_agent,
                'status'    => 'new',
            )
        );

        if ( ! $wpdb->insert_id ) {
            return false;
        }

        $response_id = $wpdb->insert_id;

        foreach ( $field_data as $field_id => $value ) {
            $wpdb->insert(
                $response_data_table,
                array(
                    'response_id' => $response_id,
                    'field_id'    => $field_id,
                    'field_value' => $value,
                )
            );
        }

        return $response_id;
    }

    public static function get_forms( $args = array() ) {
        global $wpdb;

        $defaults = array(
            'status'    => 'active',
            'orderby'   => 'created_at',
            'order'     => 'DESC',
            'limit'     => -1,
        );

        $args = wp_parse_args( $args, $defaults );

        $table_name = $wpdb->prefix . 'pcfb_forms';
        $sql = "SELECT * FROM {$table_name}";

        if ( ! empty( $args['status'] ) ) {
            $sql .= $wpdb->prepare( " WHERE status = %s", $args['status'] );
        }

        $sql .= " ORDER BY {$args['orderby']} {$args['order']}";

        if ( $args['limit'] > 0 ) {
            $sql .= $wpdb->prepare( " LIMIT %d", $args['limit'] );
        }

        return $wpdb->get_results( $sql );
    }

    public static function get_form_by_id( $form_id ) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'pcfb_forms';
        return $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table_name} WHERE id = %d", $form_id ) );
    }

    public static function get_form_count( $status = 'active' ) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'pcfb_forms';
        return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$table_name} WHERE status = %s", $status ) );
    }

    public static function get_form_response_count( $form_id ) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'pcfb_responses';
        return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$table_name} WHERE form_id = %d", $form_id ) );
    }

    public static function get_form_responses( $form_id, $args = array() ) {
        global $wpdb;

        $defaults = array(
            'limit'     => 20,
            'offset'    => 0,
            'orderby'   => 'created_at',
            'order'     => 'DESC',
        );

        $args = wp_parse_args( $args, $defaults );

        $responses_table = $wpdb->prefix . 'pcfb_responses';
        $response_data_table = $wpdb->prefix . 'pcfb_response_data';
        $fields_table = $wpdb->prefix . 'pcfb_fields';

        $sql = $wpdb->prepare(
            "SELECT r.* FROM {$responses_table} r
             WHERE r.form_id = %d
             ORDER BY r.{$args['orderby']} {$args['order']}
             LIMIT %d OFFSET %d",
            $form_id,
            $args['limit'],
            $args['offset']
        );

        return $wpdb->get_results( $sql );
    }

    public static function get_response_data( $response_id ) {
        global $wpdb;

        $response_data_table = $wpdb->prefix . 'pcfb_response_data';
        $fields_table = $wpdb->prefix . 'pcfb_fields';

        return $wpdb->get_results(
            $wpdb->prepare(
                "SELECT rd.*, f.field_name, f.field_label, f.field_type
                 FROM {$response_data_table} rd
                 JOIN {$fields_table} f ON rd.field_id = f.id
                 WHERE rd.response_id = %d",
                $response_id
            )
        );
    }

    public static function delete_form( $form_id ) {
        global $wpdb;

        $forms_table = $wpdb->prefix . 'pcfb_forms';
        $fields_table = $wpdb->prefix . 'pcfb_fields';
        $responses_table = $wpdb->prefix . 'pcfb_responses';
        $response_data_table = $wpdb->prefix . 'pcfb_response_data';

        $response_ids = $wpdb->get_col( $wpdb->prepare( "SELECT id FROM {$responses_table} WHERE form_id = %d", $form_id ) );

        if ( ! empty( $response_ids ) ) {
            $response_ids_placeholder = implode( ',', array_map( 'intval', $response_ids ) );
            $wpdb->query( "DELETE FROM {$response_data_table} WHERE response_id IN ({$response_ids_placeholder})" );
            $wpdb->query( "DELETE FROM {$responses_table} WHERE form_id = {$form_id}" );
        }

        $wpdb->query( "DELETE FROM {$fields_table} WHERE form_id = {$form_id}" );
        return $wpdb->delete( $forms_table, array( 'id' => $form_id ) );
    }

    public function save_form( $data, $fields = array() ) {
        global $wpdb;

        $forms_table = $wpdb->prefix . 'pcfb_forms';
        $fields_table = $wpdb->prefix . 'pcfb_fields';

        $form_data = array(
            'name'        => sanitize_text_field( $data['name'] ),
            'description' => sanitize_text_field( $data['description'] ),
            'settings'    => maybe_serialize( isset( $data['settings'] ) ? $data['settings'] : array() ),
            'status'      => isset( $data['status'] ) ? sanitize_text_field( $data['status'] ) : 'active',
        );

        if ( ! empty( $data['id'] ) ) {
            $form_id = intval( $data['id'] );
            $wpdb->update( $forms_table, $form_data, array( 'id' => $form_id ) );

            $existing_fields = $wpdb->get_col( $wpdb->prepare( "SELECT id FROM {$fields_table} WHERE form_id = %d", $form_id ) );
            $existing_field_ids = ! empty( $existing_fields ) ? array_map( 'intval', $existing_fields ) : array();

            $submitted_field_ids = array();
            $sort_order = 0;

            if ( ! empty( $fields ) && is_array( $fields ) ) {
                foreach ( $fields as $field ) {
                    $field_data = array(
                        'form_id'       => $form_id,
                        'field_type'    => sanitize_text_field( $field['field_type'] ),
                        'field_label'   => sanitize_text_field( $field['field_label'] ),
                        'field_name'    => $this->generate_field_name( $field['field_label'], $form_id, isset( $field['id'] ) ? $field['id'] : 0 ),
                        'placeholder'   => isset( $field['placeholder'] ) ? sanitize_text_field( $field['placeholder'] ) : '',
                        'options'       => isset( $field['options'] ) ? maybe_serialize( $field['options'] ) : '',
                        'validation_rules' => isset( $field['validation_rules'] ) ? maybe_serialize( $field['validation_rules'] ) : '',
                        'sort_order'    => $sort_order++,
                    );

                    if ( ! empty( $field['id'] ) ) {
                        $submitted_field_ids[] = intval( $field['id'] );
                        $wpdb->update( $fields_table, $field_data, array( 'id' => intval( $field['id'] ) ) );
                    } else {
                        $wpdb->insert( $fields_table, $field_data );
                        $submitted_field_ids[] = $wpdb->insert_id;
                    }
                }
            }

            foreach ( $existing_field_ids as $field_id ) {
                if ( ! in_array( $field_id, $submitted_field_ids ) ) {
                    $wpdb->delete( $fields_table, array( 'id' => $field_id ) );
                }
            }

            return $form_id;
        } else {
            $wpdb->insert( $forms_table, $form_data );
            $form_id = $wpdb->insert_id;

            if ( $form_id && ! empty( $fields ) && is_array( $fields ) ) {
                $sort_order = 0;
                foreach ( $fields as $field ) {
                    $field_data = array(
                        'form_id'       => $form_id,
                        'field_type'    => sanitize_text_field( $field['field_type'] ),
                        'field_label'   => sanitize_text_field( $field['field_label'] ),
                        'field_name'    => $this->generate_field_name( $field['field_label'], $form_id ),
                        'placeholder'   => isset( $field['placeholder'] ) ? sanitize_text_field( $field['placeholder'] ) : '',
                        'options'       => isset( $field['options'] ) ? maybe_serialize( $field['options'] ) : '',
                        'validation_rules' => isset( $field['validation_rules'] ) ? maybe_serialize( $field['validation_rules'] ) : '',
                        'sort_order'    => $sort_order++,
                    );
                    $wpdb->insert( $fields_table, $field_data );
                }
            }

            return $form_id;
        }
    }

    private function generate_field_name( $label, $form_id, $existing_id = 0 ) {
        $base_name = sanitize_title( $label );
        $base_name = preg_replace( '/[^a-z0-9_]/', '', strtolower( $base_name ) );

        if ( empty( $base_name ) ) {
            $base_name = 'field_' . time();
        }

        global $wpdb;
        $fields_table = $wpdb->prefix . 'pcfb_fields';

        $query = $wpdb->prepare(
            "SELECT COUNT(*) FROM {$fields_table} WHERE form_id = %d AND field_name LIKE %s",
            $form_id,
            $base_name . '%'
        );

        $count = $wpdb->get_var( $query );

        if ( $count > 0 ) {
            return $base_name . '_' . ( $count + 1 );
        }

        return $base_name;
    }
}
