<?php

namespace GriffinForms\Includes\Integrations\Mailchimp;

use WP_Error;

class Client
{
    public const API_VERSION = '3.0';

    public function resolveDataCenter(string $api_key): string
    {
        $api_key = trim($api_key);
        if ($api_key === '' || strpos($api_key, '-') === false) {
            return '';
        }

        $parts = explode('-', $api_key);
        $suffix = strtolower((string) end($parts));
        $suffix = preg_replace('/[^a-z0-9]/', '', $suffix);

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

    public function ping(string $api_key)
    {
        return $this->request($api_key, 'GET', '/ping');
    }

    public function getRoot(string $api_key)
    {
        return $this->request($api_key, 'GET', '/');
    }

    public function getAudiences(string $api_key, int $count = 100)
    {
        $count = max(1, min(1000, $count));

        return $this->request($api_key, 'GET', '/lists', [
            'query' => [
                'count' => $count,
                'sort_field' => 'date_created',
                'sort_dir' => 'DESC',
            ],
        ]);
    }

    public function getMember(string $api_key, string $audience_id, string $subscriber_hash)
    {
        return $this->request(
            $api_key,
            'GET',
            sprintf('/lists/%s/members/%s', rawurlencode($audience_id), rawurlencode($subscriber_hash))
        );
    }

    public function upsertMember(string $api_key, string $audience_id, string $subscriber_hash, array $payload)
    {
        return $this->request(
            $api_key,
            'PUT',
            sprintf('/lists/%s/members/%s', rawurlencode($audience_id), rawurlencode($subscriber_hash)),
            [
                'json' => $payload,
            ]
        );
    }

    public function updateMember(string $api_key, string $audience_id, string $subscriber_hash, array $payload)
    {
        return $this->request(
            $api_key,
            'PATCH',
            sprintf('/lists/%s/members/%s', rawurlencode($audience_id), rawurlencode($subscriber_hash)),
            [
                'json' => $payload,
            ]
        );
    }

    public function updateMemberTags(string $api_key, string $audience_id, string $subscriber_hash, array $tags)
    {
        $normalized = [];
        foreach ($tags as $tag) {
            $name = sanitize_text_field((string) $tag);
            if ($name === '') {
                continue;
            }

            $normalized[] = [
                'name' => $name,
                'status' => 'active',
            ];
        }

        return $this->request(
            $api_key,
            'POST',
            sprintf('/lists/%s/members/%s/tags', rawurlencode($audience_id), rawurlencode($subscriber_hash)),
            [
                'json' => [
                    'tags' => $normalized,
                ],
            ]
        );
    }

    public function normalizeAudiences(array $payload): array
    {
        $lists = $payload['lists'] ?? [];
        if (!is_array($lists)) {
            return [];
        }

        $normalized = [];
        foreach ($lists as $list) {
            if (!is_array($list)) {
                continue;
            }

            $id = sanitize_text_field((string) ($list['id'] ?? ''));
            $name = sanitize_text_field((string) ($list['name'] ?? ''));
            if ($id === '' || $name === '') {
                continue;
            }

            $normalized[] = [
                'id' => $id,
                'name' => $name,
                'member_count' => isset($list['stats']['member_count']) ? (int) $list['stats']['member_count'] : 0,
                'web_id' => isset($list['web_id']) ? (int) $list['web_id'] : 0,
            ];
        }

        return $normalized;
    }

    public function request(string $api_key, string $method, string $path, array $args = [])
    {
        $data_center = $this->resolveDataCenter($api_key);
        if ($data_center === '') {
            return new WP_Error(
                'mailchimp_invalid_api_key_format',
                __('Mailchimp API key is missing its datacenter suffix.', 'griffinforms-form-builder')
            );
        }

        $url = 'https://' . $data_center . '.api.mailchimp.com/' . self::API_VERSION . $path;
        if (!empty($args['query']) && is_array($args['query'])) {
            $url = add_query_arg(array_map('rawurlencode', $args['query']), $url);
        }

        $request_args = [
            'method' => strtoupper($method),
            'timeout' => isset($args['timeout']) ? (int) $args['timeout'] : 20,
            'headers' => [
                'Authorization' => 'Basic ' . base64_encode('griffinforms:' . $api_key),
                'Accept' => 'application/json',
            ],
        ];

        if (isset($args['body'])) {
            $request_args['body'] = $args['body'];
        }

        if (!empty($args['json']) && is_array($args['json'])) {
            $request_args['headers']['Content-Type'] = 'application/json';
            $request_args['body'] = wp_json_encode($args['json']);
        }

        $response = wp_remote_request($url, $request_args);
        if (is_wp_error($response)) {
            return $response;
        }

        $code = (int) wp_remote_retrieve_response_code($response);
        $raw_body = (string) wp_remote_retrieve_body($response);
        $decoded = [];
        if ($raw_body !== '') {
            $maybe_decoded = json_decode($raw_body, true);
            if (is_array($maybe_decoded)) {
                $decoded = $maybe_decoded;
            }
        }

        if ($code < 200 || $code >= 300) {
            $detail = sanitize_text_field((string) ($decoded['detail'] ?? $decoded['title'] ?? 'Mailchimp request failed.'));
            return new WP_Error(
                'mailchimp_api_error',
                $detail,
                [
                    'status' => $code,
                    'body' => $decoded,
                ]
            );
        }

        return [
            'status' => $code,
            'body' => $decoded,
            'raw_body' => $raw_body,
            'data_center' => $data_center,
        ];
    }
}
