<?php
/**
 * Plugin Name: Algo Forms
 * Plugin URI: https://algorisys.com/wordpress-plugins/
 * Description: Standalone contact / enquiry forms with built-in SMTP delivery. Shortcode: [algo_form name="form-name"]
 * Version: 1.4.1
 * Author: Algorisys
 * Author URI: https://algorisys.com
 * Text Domain: algo-forms
 * Requires at least: 5.8
 * Requires PHP: 7.4
 */

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

define('ALGO_FORMS_VERSION', '1.4.1');
define('ALGO_FORMS_OPTIONS_KEY', 'algo_forms_options');
define('ALGO_FORMS_DB_VERSION', '3');
define('ALGO_FORMS_CAP', 'manage_options');
define('ALGO_FORMS_PLUGIN_FILE', __FILE__);
define('ALGO_FORMS_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('ALGO_FORMS_PLUGIN_URL', plugin_dir_url(__FILE__));

require_once ALGO_FORMS_PLUGIN_DIR . 'includes/helpers.php';
require_once ALGO_FORMS_PLUGIN_DIR . 'includes/pro.php';
require_once ALGO_FORMS_PLUGIN_DIR . 'includes/spam.php';
require_once ALGO_FORMS_PLUGIN_DIR . 'includes/delivery-log.php';
require_once ALGO_FORMS_PLUGIN_DIR . 'includes/mail-smtp.php';
require_once ALGO_FORMS_PLUGIN_DIR . 'includes/form-render.php';
require_once ALGO_FORMS_PLUGIN_DIR . 'includes/ajax.php';
require_once ALGO_FORMS_PLUGIN_DIR . 'admin/admin-assets.php';
require_once ALGO_FORMS_PLUGIN_DIR . 'admin/dashboard.php';
require_once ALGO_FORMS_PLUGIN_DIR . 'admin/admin-page.php';
require_once ALGO_FORMS_PLUGIN_DIR . 'admin/smtp-settings.php';
require_once ALGO_FORMS_PLUGIN_DIR . 'admin/email-settings.php';
require_once ALGO_FORMS_PLUGIN_DIR . 'admin/pro-settings.php';
require_once ALGO_FORMS_PLUGIN_DIR . 'admin/delivery-log.php';

/**
 * @return void
 */
function algo_forms_activate()
{
    global $wpdb;
    $charset = $wpdb->get_charset_collate();

    $forms = $wpdb->prefix . 'algo_forms';
    $subs = $wpdb->prefix . 'algo_form_submissions';

    $sql_forms = "CREATE TABLE $forms (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        form_name varchar(100) NOT NULL,
        form_title varchar(255) NOT NULL,
        fields longtext NOT NULL,
        messages longtext NULL,
        notify_emails longtext NULL,
        email_subject varchar(255) NULL DEFAULT NULL,
        created_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
        PRIMARY KEY  (id),
        UNIQUE KEY form_name (form_name)
    ) $charset;";

    $sql_subs = "CREATE TABLE $subs (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        form_id mediumint(9) NOT NULL,
        form_data longtext NOT NULL,
        submission_date datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
        PRIMARY KEY  (id),
        KEY form_id (form_id)
    ) $charset;";

    require_once ABSPATH . 'wp-admin/includes/upgrade.php';
    dbDelta($sql_forms);
    dbDelta($sql_subs);
    update_option('algo_forms_db_version', ALGO_FORMS_DB_VERSION);

    if (function_exists('algo_forms_install_mail_log_table')) {
        algo_forms_install_mail_log_table();
    }
    if (function_exists('algo_forms_maybe_upgrade_submissions_pro_columns')) {
        algo_forms_maybe_upgrade_submissions_pro_columns();
    }

    algo_forms_ensure_default_contact_form();
    algo_forms_ensure_default_plugin_request_form();
}
register_activation_hook(__FILE__, 'algo_forms_activate');

/**
 * Ensure default forms exist after upgrades / first load.
 *
 * @return void
 */
function algo_forms_maybe_seed_contact_form()
{
    algo_forms_maybe_upgrade_db();

    if (get_option('algo_forms_contact_seeded')) {
        algo_forms_maybe_enable_contact_show_title();
    } else {
        algo_forms_ensure_default_contact_form();
        algo_forms_maybe_enable_contact_show_title();
    }

    if (!get_option('algo_forms_plugin_request_seeded')) {
        algo_forms_ensure_default_plugin_request_form();
    }
}
add_action('init', 'algo_forms_maybe_seed_contact_form', 5);

/**
 * Upgrade forms table schema when needed.
 *
 * @return void
 */
function algo_forms_maybe_upgrade_db()
{
    $installed = (string) get_option('algo_forms_db_version', '0');
    if (version_compare($installed, ALGO_FORMS_DB_VERSION, '>=')) {
        return;
    }

    algo_forms_activate();
}

/**
 * Add Pro inbox columns to submissions (safe / idempotent).
 *
 * @return void
 */
function algo_forms_maybe_upgrade_submissions_pro_columns()
{
    global $wpdb;
    $table = $wpdb->prefix . 'algo_form_submissions';

    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    $exists = $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $wpdb->esc_like($table)));
    if ($exists !== $table) {
        return;
    }

    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    $cols = $wpdb->get_col("DESCRIBE {$table}", 0);
    if (!is_array($cols)) {
        $cols = array();
    }

    if (!in_array('status', $cols, true)) {
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
        $wpdb->query("ALTER TABLE {$table} ADD COLUMN status varchar(20) NOT NULL DEFAULT 'unread'");
    }
    if (!in_array('admin_notes', $cols, true)) {
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
        $wpdb->query("ALTER TABLE {$table} ADD COLUMN admin_notes longtext NULL");
    }
    if (!in_array('ip_hash', $cols, true)) {
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange
        $wpdb->query("ALTER TABLE {$table} ADD COLUMN ip_hash varchar(64) NOT NULL DEFAULT ''");
    }

    wp_cache_delete('algo_forms_submissions_pro_cols', 'algo_forms');
}

/**
 * Whether submissions table already has Pro inbox columns.
 *
 * @return bool
 */
function algo_forms_submissions_have_pro_columns()
{
    $cached = wp_cache_get('algo_forms_submissions_pro_cols', 'algo_forms');
    if ($cached === '1' || $cached === '0') {
        return $cached === '1';
    }

    global $wpdb;
    $table = $wpdb->prefix . 'algo_form_submissions';
    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    $exists = $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $wpdb->esc_like($table)));
    if ($exists !== $table) {
        wp_cache_set('algo_forms_submissions_pro_cols', '0', 'algo_forms', 300);
        return false;
    }

    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
    $cols = $wpdb->get_col("DESCRIBE {$table}", 0);
    $ok = is_array($cols)
        && in_array('status', $cols, true)
        && in_array('admin_notes', $cols, true)
        && in_array('ip_hash', $cols, true);

    wp_cache_set('algo_forms_submissions_pro_cols', $ok ? '1' : '0', 'algo_forms', 300);
    return $ok;
}

/**
 * @return void
 */
function algo_forms_enqueue_assets()
{
    $css = ALGO_FORMS_PLUGIN_DIR . 'assets/css/algo-forms.css';
    $js = ALGO_FORMS_PLUGIN_DIR . 'assets/js/algo-forms.js';

    wp_enqueue_style(
        'algo-forms',
        ALGO_FORMS_PLUGIN_URL . 'assets/css/algo-forms.css',
        array(),
        file_exists($css) ? (string) filemtime($css) : ALGO_FORMS_VERSION
    );

    wp_enqueue_script('jquery');
    wp_register_script(
        'algo-forms',
        ALGO_FORMS_PLUGIN_URL . 'assets/js/algo-forms.js',
        array('jquery'),
        file_exists($js) ? (string) filemtime($js) : ALGO_FORMS_VERSION,
        true
    );
    wp_enqueue_script('algo-forms');
    wp_localize_script('algo-forms', 'algoForms', array(
        'ajaxurl' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('algo_forms_nonce'),
    ));
}

/**
 * Shortcode: [algo_form name="contact" plugin_name="Algo Media Desk"]
 *
 * Title display is controlled in Algo Forms → Edit form → Show form title.
 * Optional shortcode override: show_title="1" or show_title="0".
 *
 * @param array<string, string>|string $atts
 * @return string
 */
function algo_forms_shortcode($atts)
{
    $atts = shortcode_atts(array(
        'name' => '',
        'show_title' => '',
        'plugin_name' => '',
    ), $atts, 'algo_form');

    if ($atts['name'] === '') {
        return esc_html__('Form name is required.', 'algo-forms');
    }

    global $wpdb;
    $form = $wpdb->get_row($wpdb->prepare(
        "SELECT * FROM {$wpdb->prefix}algo_forms WHERE form_name = %s",
        sanitize_title($atts['name'])
    ));

    if (!$form) {
        return esc_html__('Form not found.', 'algo-forms');
    }

    $fields = algo_forms_normalize_fields(json_decode($form->fields, true) ?: array());
    $messages = algo_forms_get_form_messages($form);

    algo_forms_enqueue_assets();

    $page_url = '';
    $page_title = '';
    if (is_singular() && get_the_ID()) {
        $page_url = (string) get_permalink();
        $page_title = (string) get_the_title();
    }
    if ($page_title === '') {
        $page_title = wp_get_document_title();
    }
    if ($page_url === '') {
        $req = !empty($_SERVER['REQUEST_URI']) ? wp_unslash($_SERVER['REQUEST_URI']) : '/';
        $page_url = home_url(is_string($req) ? $req : '/');
    }

    $plugin_name = sanitize_text_field((string) $atts['plugin_name']);
    $show_title_attr = trim((string) $atts['show_title']);
    if ($show_title_attr === '' || $show_title_attr === 'auto') {
        $show_title = algo_forms_form_shows_title($form);
    } else {
        $show_title = $show_title_attr !== '0' && $show_title_attr !== 'false';
    }

    ob_start();
    algo_forms_render_markup(
        $form,
        $fields,
        $messages,
        $page_url,
        $page_title,
        $show_title,
        $plugin_name
    );
    return (string) ob_get_clean();
}
add_shortcode('algo_form', 'algo_forms_shortcode');

/**
 * Open "Visit plugin site" in a new tab on the Plugins screen.
 *
 * @param string[] $plugin_meta Plugin row meta links.
 * @param string   $plugin_file Plugin basename.
 * @param array    $plugin_data Plugin header data.
 * @return string[]
 */
function algo_forms_plugin_row_meta($plugin_meta, $plugin_file, $plugin_data)
{
    if ($plugin_file !== plugin_basename(ALGO_FORMS_PLUGIN_FILE)) {
        return $plugin_meta;
    }

    $uri = isset($plugin_data['PluginURI']) ? (string) $plugin_data['PluginURI'] : '';
    if ($uri === '') {
        return $plugin_meta;
    }

    foreach ($plugin_meta as $i => $html) {
        if (!is_string($html) || strpos($html, $uri) === false || strpos($html, 'target=') !== false) {
            continue;
        }
        $plugin_meta[$i] = preg_replace('/<a\s+/i', '<a target="_blank" rel="noopener noreferrer" ', $html, 1);
    }

    return $plugin_meta;
}
add_filter('plugin_row_meta', 'algo_forms_plugin_row_meta', 10, 3);
