<?php

namespace Formatrica\REST;

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

use Formatrica\Forms\Form_Repository;
use Formatrica\Support\Secrets;
use WP_REST_Request;
use WP_REST_Response;

final class Integration_Controller extends Base_Rest_Controller implements Rest_Controller
{
    private Form_Repository $forms;

    public function __construct(?Form_Repository $forms = null)
    {
        $this->forms = $forms ?? new Form_Repository();
    }

    public function register_routes(): void
    {
        register_rest_route(
            self::NAMESPACE,
            '/integrations/mailchimp/lists',
            [
                'methods' => \WP_REST_Server::CREATABLE,
                'callback' => [$this, 'fetch_mailchimp_lists'],
                'permission_callback' => [$this, 'permissions_check'],
            ]
        );

        register_rest_route(
            self::NAMESPACE,
            '/integrations/brevo/lists',
            [
                'methods' => \WP_REST_Server::CREATABLE,
                'callback' => [$this, 'fetch_brevo_lists'],
                'permission_callback' => [$this, 'permissions_check'],
            ]
        );
    }

    /**
     * Fetch the account's Brevo contact lists for the settings list picker.
     */
    public function fetch_brevo_lists(WP_REST_Request $request): WP_REST_Response
    {
        $nonce_check = $this->verify_rest_nonce_or_error($request);
        if (is_wp_error($nonce_check)) {
            return new WP_REST_Response([
                'lists' => [],
                'message' => $nonce_check->get_error_message(),
            ], (int) ($nonce_check->get_error_data('status') ?: 403));
        }

        $api_key = trim((string) $request->get_param('apiKey'));
        $form_id = (int) $request->get_param('formId');

        // Fall back to the stored (encrypted) key when the field shows a mask.
        if ($api_key === '' && $form_id > 0) {
            $raw = $this->forms->raw_config($form_id);
            $raw_integrations = isset($raw['options']['integrations']) && is_array($raw['options']['integrations'])
                ? $raw['options']['integrations']
                : [];
            $stored_key = isset($raw_integrations['brevo']['api_key']) ? (string) $raw_integrations['brevo']['api_key'] : '';
            if ($stored_key !== '') {
                $api_key = Secrets::decrypt($stored_key);
            }
        }

        if ($api_key === '') {
            return new WP_REST_Response([
                'lists' => [],
                'message' => __('Brevo API key is required.', 'formatrica'),
            ], 400);
        }

        $response = wp_remote_get('https://api.brevo.com/v3/contacts/lists?limit=50&offset=0&sort=desc', [
            'headers' => [
                'api-key' => $api_key,
                'accept' => 'application/json',
            ],
            'timeout' => 10,
            'redirection' => 3,
            'reject_unsafe_urls' => true,
            'limit_response_size' => 256 * 1024,
        ]);

        if (is_wp_error($response)) {
            return new WP_REST_Response([
                'lists' => [],
                'message' => $response->get_error_message(),
            ], 502);
        }

        $code = (int) wp_remote_retrieve_response_code($response);
        $body = wp_remote_retrieve_body($response);

        if ($code < 200 || $code >= 300) {
            return new WP_REST_Response([
                'lists' => [],
                /* translators: %d: HTTP status code */
                'message' => sprintf(__('Brevo API returned HTTP %d.', 'formatrica'), $code),
            ], $code);
        }

        $decoded = json_decode($body, true);
        $lists = [];

        if (is_array($decoded) && isset($decoded['lists']) && is_array($decoded['lists'])) {
            foreach ($decoded['lists'] as $list) {
                if (!is_array($list) || !isset($list['id'])) {
                    continue;
                }
                $id = (string) $list['id'];
                $name = isset($list['name']) ? (string) $list['name'] : '';
                if ($id === '' || $name === '') {
                    continue;
                }
                $lists[] = ['id' => $id, 'name' => $name];
            }
        }

        return new WP_REST_Response(['lists' => $lists]);
    }

    public function permissions_check(WP_REST_Request $request)
    {
        return parent::permissions_check($request);
    }

    public function fetch_mailchimp_lists(WP_REST_Request $request): WP_REST_Response
    {
        $nonce_check = $this->verify_rest_nonce_or_error($request);
        if (is_wp_error($nonce_check)) {
            return new WP_REST_Response([
                'lists' => [],
                'message' => $nonce_check->get_error_message(),
            ], (int) ($nonce_check->get_error_data('status') ?: 403));
        }

        $api_key = trim((string) $request->get_param('apiKey'));
        $form_id = (int) $request->get_param('formId');

        if ($api_key === '' && $form_id > 0) {
            $raw = $this->forms->raw_config($form_id);
            $raw_integrations = isset($raw['options']['integrations']) && is_array($raw['options']['integrations'])
                ? $raw['options']['integrations']
                : [];
            $stored_key = isset($raw_integrations['mailchimp']['api_key']) ? (string) $raw_integrations['mailchimp']['api_key'] : '';
            if ($stored_key !== '') {
                $api_key = Secrets::decrypt($stored_key);
            }
        }

        if ($api_key === '') {
            return new WP_REST_Response([
                'lists' => [],
                'message' => __('Mailchimp API key is required.', 'formatrica'),
            ], 400);
        }

        $data_center = $this->extract_mailchimp_datacenter($api_key);
        if ($data_center === '') {
            return new WP_REST_Response([
                'lists' => [],
                'message' => __('Unable to determine Mailchimp data center from the API key.', 'formatrica'),
            ], 400);
        }

        $endpoint = sprintf(
            'https://%s.api.mailchimp.com/3.0/lists?fields=lists.id,lists.name,total_items&count=100',
            $data_center
        );

        $response = wp_remote_get($endpoint, [
            'headers' => [
                'Authorization' => 'Basic ' . base64_encode('formatrica:' . $api_key),
            ],
            'timeout' => 10,
            'redirection' => 3,
            'reject_unsafe_urls' => true,
            'limit_response_size' => 256 * 1024,
        ]);

        if (is_wp_error($response)) {
            return new WP_REST_Response([
                'lists' => [],
                'message' => $response->get_error_message(),
            ], 502);
        }

        $code = (int) wp_remote_retrieve_response_code($response);
        $body = wp_remote_retrieve_body($response);

        if ($code < 200 || $code >= 300) {
            return new WP_REST_Response([
                'lists' => [],
                /* translators: %d: HTTP status code */
                'message' => sprintf(__('Mailchimp API returned HTTP %d.', 'formatrica'), $code),
                'body' => $body,
            ], $code);
        }

        $decoded = json_decode($body, true);
        $lists = [];

        if (is_array($decoded) && isset($decoded['lists']) && is_array($decoded['lists'])) {
            foreach ($decoded['lists'] as $list) {
                if (!is_array($list)) {
                    continue;
                }

                $id = isset($list['id']) ? (string) $list['id'] : '';
                $name = isset($list['name']) ? (string) $list['name'] : '';

                if ($id === '' || $name === '') {
                    continue;
                }

                $lists[] = [
                    'id' => $id,
                    'name' => $name,
                ];
            }
        }

        return new WP_REST_Response([
            'lists' => $lists,
        ]);
    }

    private function extract_mailchimp_datacenter(string $api_key): string
    {
        if (strpos($api_key, '-') === false) {
            return '';
        }

        $parts = explode('-', $api_key);
        $data_center = strtolower(trim((string) end($parts)));

        if ($data_center === '') {
            return '';
        }

        $sanitised = preg_replace('/[^a-z0-9]/', '', $data_center);

        return is_string($sanitised) ? $sanitised : '';
    }
}
