<?php
/*
 *  WordPress Contact Form 7 Creamailer extension
 *  Copyright (C) 2026 Creamailer

 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.

 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.

 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
namespace Gurumedia\CF7CMStandalone\Plugin;

// use \Gurumedia\CF7CMStandalone\API\API;
use \Gurumedia\CF7CMStandalone\Views\Index;

use \Gurumedia\CF7CMStandalone\Plugin\PluginBase as Base;
use \Gurumedia\CF7CMStandalone\Utility\UtilityBase as Utility;

use \BewitchingSource\CreamailerAPI\API as CMAPI;

class Plugin extends Base {
    public $data_options = [
        'opt-in' => '',
        'email' => '',
        'name' => '',
        'company' => '',
        'address' => '',
        'city' => '',
        'zip_code' => '',
        'country' => '',
        'phone' => '',
        'customer_number' => '',
        'send_autoresponders' => '',
        'send_autoresponders_if_exists' => ''
    ];

    public function __construct() {
        $options = [
            'id' => 'creamailer-extension',
            'tab_title' => 'Creamailer',
            'short_name' => 'cm',
        ];
        $api_options = [
            'url' => 'https://api.cmfile.net/v1/api',
            'key' => '',
            'shared_key' => '',
            'list_id' => '',
            'lists' => [],
            'status' => [],
            'required' => [
                'key',
                'shared_key'
            ]
        ];
        $required_data = [
            'email',
            'opt-in'
        ];
        parent::__construct($options, $api_options, $required_data);
    }

    /**
     * send
     * Get parent::send return value and print it out
     *
     * @return string
     */
    public function send($args) {
        $options = $this->getOptions($args);
        $this->newAPI($options['api_options']);
        $response = parent::send($args);
        echo Utility::debug($response);
    }

    /**
     * prepareRequest
     * Prepares the request
     *
     * @return array
     */
    public function prepareRequest() {
        $posted_data = $this->getPostedData();
        $opt_in = $this->data_options['opt-in'];
        $list_id = $this->data_options['list_id'];
        $data_items = array_filter($this->data_options, function ($k) {
            return !in_array($k, ['opt-in', 'key', 'shared_key', 'list_id']);
        }, ARRAY_FILTER_USE_KEY);
        $is_opt_in = isset($opt_in) && strlen($opt_in) > 0;
        $posted_opt_in = $this->getPostedOption($opt_in, $posted_data);
        $has_opt_in = !empty($posted_opt_in[0]);
        $data = [];

        echo Utility::debug($posted_data);
        echo Utility::debug($posted_opt_in);

        /**
         * Opt-in is always required, no exceptions! Also list ID must exist.
         */
        if (!$is_opt_in || !$has_opt_in || empty($list_id)) {
            $result = [
                'list_id' => $list_id,
                'is_opt_in' => $is_opt_in,
                'has_opt_in' => $has_opt_in
            ];
            echo Utility::debug($result);
            $this->log("prepareRequest opt-in not set or list ID missing: " . json_encode($result));
            return $data;
        }

        foreach ($data_items as $k => $v) {
            $value = $this->getPostedOption($v, $posted_data);
            if (!empty($value)) {
                $data[$k] = $value;
            }
        }

        echo Utility::debug($data);

        $this->log("prepareRequest data: " . json_encode($data));

        return $data;
    }

    /**
     * sendRequest
     * Sends the request
     *
     * @param array $args
     * @param array $data
     * @return array
     */
    public function sendRequest($args, $data) {
        $options = $this->getOptions($args);
        $query = [];
        $list_id = $options['api_options']['list_id'];
        $sar = $options['data_options']['send_autoresponders'];
        $sarie = $options['data_options']['send_autoresponders_if_exists'];
        $autoresponders = [
            'send_autoresponders' => (bool)$sar
                ? true
                : false,
            'send_autoresponders_if_exists' => (bool)$sar && (bool)$sarie
                ? true
                : false
        ];
        $payload = [
            'json' => [
                "Subscribers" => [
                    array_merge(
                        $data,
                        $autoresponders,
                        ["update_existing" => true]
                    )
                ]
            ]];
        return $this->api
                    ->Subscribers
                    ->post($list_id, $payload);
    }

    /**
     * display
     * Displays settings
     *
     * @return string
     */
    public function display() {
        $admin_options = $this->getAdminOptions();
        $status = $this->api->ConnectionTest->get();
        $this->log("display " . json_encode($status->body));
        $admin_options['status'] = (array)$status->body;
        echo Utility::debug($status);
        echo Utility::debug($admin_options);
        if (isset($status->body->success) && $status->body->success) {
            $admin_options['lists'] = $this->getLists();
        }
        return Index::render($admin_options, $this->options, $this->plugin_options);
    }

    /**
     * resultsFix
     * Kludge workaround for Creamailer API result which can be either array
     * or object
     *
     * @param object $obj
     * @return array
     */
    public function resultsFix($obj) {
        return is_array($obj->Results) && $obj->Results === array_values($obj->Results)
            ? $obj->Results
            : [$obj->Results];
    }

    /**
     * getLists
     * Get Creamailer lists
     *
     * @return array
     */
    public function getLists() {
        $res = $this->api->Lists->get();
        $this->log("getLists " . json_encode($res->body));
        $body = $res->body;
        return isset($body->Results)
            ? $this->resultsFix($body)
            : [];
    }

    /**
     * newAPI
     * Create new API instance
     *
     * @param array $options
     * @return bool
     */
    public function newAPI($options = null) {
        $options = $options
            ? $options
            : $this->getOptions()['api_options'];
        list($a, $b) = [$options["key"], $options["shared_key"]];
        $this->api = new CMAPI($a, $b);
        echo Utility::debug($this->log("newAPI"));

        return true;
    }
}
