<?php

namespace EasyLinkAutomations\HTTP\Controllers\Actions;

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

use EasyLinkAutomations\HTTP\Request\Request;
use EasyLinkAutomations\HTTP\Response;
use EasyLinkAutomations\Models\Connection;

/**
 * Controller for Mailchimp related API calls.
 * Handles fetching audience lists for dynamic field loading.
 */
final class MailchimpController
{
    private const METADATA_URL = 'https://login.mailchimp.com/oauth2/metadata';

    /**
     * Get list of audience lists accessible by the connection.
     */
    public function lists(Request $request): Response
    {
        $connectionId = (int) $request->get('connection_id');

        if (!$connectionId) {
            return Response::error('Connection ID is required', 400);
        }

        $token = Connection::getAccessToken($connectionId);
        if (empty($token)) {
            return Response::error('Invalid connection or token expired', 401);
        }

        $apiBase = $this->getApiBase($token);
        if (!$apiBase) {
            return Response::error('Failed to determine Mailchimp API datacenter');
        }

        $url = $apiBase . '/lists?' . http_build_query([
            'fields' => 'lists.id,lists.name,lists.stats.member_count',
            'count'  => 100,
        ]);

        $response = wp_remote_get($url, [
            'headers' => [
                'Authorization' => 'Bearer ' . $token,
            ],
            'timeout' => 30,
        ]);

        if (is_wp_error($response)) {
            return Response::error('Failed to fetch lists: ' . $response->get_error_message());
        }

        $statusCode = wp_remote_retrieve_response_code($response);
        $body = json_decode(wp_remote_retrieve_body($response), true);

        if ($statusCode !== 200) {
            $errorMsg = $body['detail'] ?? $body['title'] ?? 'Unknown error';
            return Response::error('Mailchimp API error: ' . $errorMsg, $statusCode);
        }

        $lists = [];
        foreach ($body['lists'] ?? [] as $list) {
            $memberCount = $list['stats']['member_count'] ?? 0;
            $lists[] = [
                'value' => $list['id'],
                'label' => $list['name'] . ' (' . $memberCount . ' members)',
            ];
        }

        return Response::success(['lists' => $lists]);
    }

    /**
     * Get merge fields for a specific audience list.
     */
    public function mergeFields(Request $request): Response
    {
        $connectionId = (int) $request->get('connection_id');
        $listId       = $request->get('list_id');

        if (!$connectionId) {
            return Response::error('Connection ID is required', 400);
        }

        if (empty($listId)) {
            return Response::error('List ID is required', 400);
        }

        $token = Connection::getAccessToken($connectionId);
        if (empty($token)) {
            return Response::error('Invalid connection or token expired', 401);
        }

        $apiBase = $this->getApiBase($token);
        if (!$apiBase) {
            return Response::error('Failed to determine Mailchimp API datacenter');
        }

        $url = $apiBase . '/lists/' . $listId . '/merge-fields?' . http_build_query([
            'fields' => 'merge_fields.tag,merge_fields.name,merge_fields.type,merge_fields.required',
            'count'  => 100,
        ]);

        $response = wp_remote_get($url, [
            'headers' => [
                'Authorization' => 'Bearer ' . $token,
            ],
            'timeout' => 30,
        ]);

        if (is_wp_error($response)) {
            return Response::error('Failed to fetch merge fields: ' . $response->get_error_message());
        }

        $statusCode = wp_remote_retrieve_response_code($response);
        $body       = json_decode(wp_remote_retrieve_body($response), true);

        if ($statusCode !== 200) {
            $errorMsg = $body['detail'] ?? $body['title'] ?? 'Unknown error';
            return Response::error('Mailchimp API error: ' . $errorMsg, $statusCode);
        }

        // Email address as the first required field
        $columns = [
            [
                'value'    => 'email_address',
                'label'    => 'Email Address',
                'required' => true,
            ],
        ];

        foreach ($body['merge_fields'] ?? [] as $field) {
            $columns[] = [
                'value' => $field['tag'],
                'label' => $field['name'] . ' (' . $field['tag'] . ')',
            ];
        }

        return Response::success(['columns' => $columns]);
    }

    /**
     * Get campaigns for the send campaign remote select.
     */
    public function campaigns(Request $request): Response
    {
        $connectionId = (int) $request->get('connection_id');

        if (!$connectionId) {
            return Response::error('Connection ID is required', 400);
        }

        $token = Connection::getAccessToken($connectionId);
        if (empty($token)) {
            return Response::error('Invalid connection or token expired', 401);
        }

        $apiBase = $this->getApiBase($token);
        if (!$apiBase) {
            return Response::error('Failed to determine Mailchimp API datacenter');
        }

        $url = $apiBase . '/campaigns?' . http_build_query([
            'fields' => 'campaigns.id,campaigns.status,campaigns.settings.title',
            'count'  => 100,
        ]);

        $response = wp_remote_get($url, [
            'headers' => [
                'Authorization' => 'Bearer ' . $token,
            ],
            'timeout' => 30,
        ]);

        if (is_wp_error($response)) {
            return Response::error('Failed to fetch campaigns: ' . $response->get_error_message());
        }

        $statusCode = wp_remote_retrieve_response_code($response);
        $body       = json_decode(wp_remote_retrieve_body($response), true);

        if ($statusCode !== 200) {
            $errorMsg = $body['detail'] ?? $body['title'] ?? 'Unknown error';
            return Response::error('Mailchimp API error: ' . $errorMsg, $statusCode);
        }

        $campaigns = [];
        foreach ($body['campaigns'] ?? [] as $campaign) {
            $title = $campaign['settings']['title'] ?? $campaign['id'];
            $status = $campaign['status'] ?? '';

            $campaigns[] = [
                'value' => $campaign['id'],
                'label' => $status ? $title . ' (' . $status . ')' : $title,
            ];
        }

        return Response::success(['campaigns' => $campaigns]);
    }

    /**
     * Get the Mailchimp API base URL by querying the metadata endpoint.
     */
    private function getApiBase(string $token): ?string
    {
        $response = wp_remote_get(self::METADATA_URL, [
            'headers' => ['Authorization' => 'OAuth ' . $token],
            'timeout' => 15,
        ]);

        if (is_wp_error($response)) {
            return null;
        }

        $body = json_decode(wp_remote_retrieve_body($response), true);

        if (!empty($body['api_endpoint'])) {
            return rtrim($body['api_endpoint'], '/') . '/3.0';
        }

        return !empty($body['dc'])
            ? 'https://' . $body['dc'] . '.api.mailchimp.com/3.0'
            : null;
    }
}
