<?php
/**
 * Free local integrations.
 *
 * @package SwairishXHeaderBarNotificationOffer
 */

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

class SwairishX_Integrations {
    private $storage;

    public function __construct(SwairishX_Storage $storage) {
        $this->storage = $storage;
    }

    public function hooks() {
        add_action('comment_post', array($this, 'comment_created'), 10, 3);
        add_action('woocommerce_order_status_completed', array($this, 'woocommerce_order'));
        add_action('edd_complete_purchase', array($this, 'edd_purchase'));
        add_action('give_insert_payment', array($this, 'give_donation'), 10, 2);
        add_action('tutor_after_enrolled', array($this, 'tutor_enrollment'), 10, 2);
        add_action('wpcf7_mail_sent', array($this, 'contact_form_7'));
        add_action('ninja_forms_after_submission', array($this, 'ninja_forms'));
        add_action('wpforms_process_complete', array($this, 'wpforms'), 10, 4);
        add_action('swairishx_sync_wordpress_org', array($this, 'sync_wordpress_org'));
    }

    public function sync_wordpress_org() {
        $slugs = array();
        foreach ($this->storage->campaigns(array('publish', 'draft')) as $campaign) {
            $config = $this->storage->get_campaign($campaign->ID);
            if ($config && 'wordpress_org' === $config['integration'] && !empty($config['source_identifier'])) {
                $slugs[] = sanitize_key($config['source_identifier']);
            }
        }
        foreach (array_unique(array_filter($slugs)) as $slug) {
            $url = add_query_arg(array('action' => 'plugin_information', 'request[slug]' => $slug), 'https://api.wordpress.org/plugins/info/1.2/');
            $response = wp_safe_remote_get($url, array('timeout' => 15, 'user-agent' => 'SwairishX/' . SWAIRISHX_VERSION . '; ' . home_url('/')));
            if (is_wp_error($response) || 200 !== wp_remote_retrieve_response_code($response)) {
                continue;
            }
            $data = json_decode(wp_remote_retrieve_body($response), true);
            if (!is_array($data) || empty($data['name'])) {
                continue;
            }
            $rating = isset($data['rating']) ? round(floatval($data['rating']) / 20, 1) : 0;
            $installs = isset($data['active_installs']) ? absint($data['active_installs']) : 0;
            $this->storage->capture_event('wordpress_org', 'plugin_stats', array(
                'actor' => 'WordPress.org',
                /* translators: 1: Plugin name, 2: Active install count, 3: Rating out of five. */
                'subject' => sprintf(__('%1$s has %2$s active installs and a %3$s/5 rating', 'swairish-header-bar-offer-notifications'), sanitize_text_field($data['name']), number_format_i18n($installs), $rating),
                'location' => '',
                'url' => 'https://wordpress.org/plugins/' . rawurlencode($slug) . '/',
            ), 'wordpress-org:' . $slug . ':' . gmdate('Y-m-d-H'));
        }
    }

    public function comment_created($comment_id, $approved, $commentdata) {
        if (1 !== (int) $approved) {
            return;
        }
        $this->storage->capture_event('wordpress_comments', 'comment', array(
            'actor' => __('A reader', 'swairish-header-bar-offer-notifications'),
            'subject' => get_the_title(absint($commentdata['comment_post_ID'])),
            'url' => get_comment_link($comment_id),
        ), $this->event_key('comment', $comment_id));
    }

    public function woocommerce_order($order_id) {
        if (!function_exists('wc_get_order')) {
            return;
        }
        $order = wc_get_order($order_id);
        if (!$order) {
            return;
        }
        $items = $order->get_items();
        $item = reset($items);
        $this->storage->capture_event('woocommerce', 'sale', array(
            'actor' => __('A customer', 'swairish-header-bar-offer-notifications'),
            'subject' => $item ? sanitize_text_field($item->get_name()) : __('an item', 'swairish-header-bar-offer-notifications'),
            'location' => '',
            'url' => $item && $item->get_product() ? get_permalink($item->get_product_id()) : home_url('/'),
        ), $this->event_key('woo', $order_id));
    }

    public function edd_purchase($payment_id) {
        $downloads = function_exists('edd_get_payment_meta_cart_details') ? edd_get_payment_meta_cart_details($payment_id) : array();
        $first = is_array($downloads) ? reset($downloads) : array();
        $this->storage->capture_event('easy_digital_downloads', 'sale', array(
            'actor' => __('A customer', 'swairish-header-bar-offer-notifications'),
            'subject' => isset($first['name']) ? sanitize_text_field($first['name']) : __('a download', 'swairish-header-bar-offer-notifications'),
            'url' => home_url('/'),
        ), $this->event_key('edd', $payment_id));
    }

    public function give_donation($payment_id) {
        $this->storage->capture_event('givewp', 'donation', array(
            'actor' => __('A supporter', 'swairish-header-bar-offer-notifications'),
            'subject' => __('made a donation', 'swairish-header-bar-offer-notifications'),
            'url' => home_url('/'),
        ), $this->event_key('give', $payment_id));
    }

    public function tutor_enrollment($course_id, $user_id) {
        $this->storage->capture_event('tutor_lms', 'enrollment', array(
            'actor' => __('A learner', 'swairish-header-bar-offer-notifications'),
            'subject' => get_the_title($course_id),
            'url' => get_permalink($course_id),
        ), $this->event_key('tutor', $course_id, $user_id));
    }

    public function contact_form_7($form) {
        $this->form_event('contact_form_7', method_exists($form, 'id') ? $form->id() : 0, method_exists($form, 'title') ? $form->title() : __('a form', 'swairish-header-bar-offer-notifications'));
    }

    public function ninja_forms($form_data) {
        $id = isset($form_data['form_id']) ? absint($form_data['form_id']) : 0;
        $this->form_event('ninja_forms', $id, __('a form', 'swairish-header-bar-offer-notifications'));
    }

    public function wpforms($fields, $entry, $form_data, $entry_id) {
        $title = isset($form_data['settings']['form_title']) ? $form_data['settings']['form_title'] : __('a form', 'swairish-header-bar-offer-notifications');
        $this->form_event('wpforms', $entry_id, $title);
    }

    private function form_event($source, $id, $title) {
        $this->storage->capture_event($source, 'form_submission', array(
            'actor' => __('A visitor', 'swairish-header-bar-offer-notifications'),
            'subject' => sanitize_text_field($title),
            'url' => home_url('/'),
        ), $this->event_key($source, $id, wp_generate_uuid4()));
    }

    private function event_key($source, ...$identifiers) {
        $value = implode('|', array_map('strval', $identifiers));
        return sanitize_key($source) . ':' . hash_hmac('sha256', $value, wp_salt('auth'));
    }
}
