<?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 MailerLite related API calls.
 * Handles fetching subscriber fields for dynamic field mapping.
 */
final class MailerLiteController
{
    private const API_BASE = 'https://connect.mailerlite.com/api';

    /**
     * Standard built-in MailerLite subscriber field keys → labels.
     * These always exist on every subscriber; keys are sent inside the `fields` object.
     */
    private const STANDARD_FIELDS = [
        'name'      => 'First Name',
        'last_name' => 'Last Name',
        'company'   => 'Company',
        'country'   => 'Country',
        'city'      => 'City',
        'state'     => 'State',
        'z_i_p'     => 'ZIP Code',
        'phone'     => 'Phone',
    ];

    /**
     * Fetch custom fields from the MailerLite API.
     *
     * Returns an array of ['key' => string, 'name' => string] entries,
     * or a Response error on failure.
     */
    private function fetchCustomFields(string $token): array|Response
    {
        $url      = self::API_BASE . '/fields';
        $response = wp_remote_get($url, [
            'headers' => [
                'Accept'        => 'application/json',
                'Authorization' => 'Bearer ' . $token,
            ],
            'timeout' => 30,
        ]);

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

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

        if ($statusCode < 200 || $statusCode >= 300) {
            return Response::error('MailerLite API error: ' . ($body['message'] ?? 'Unknown error'));
        }

        return $body['data'] ?? [];
    }

    /**
     * Get subscriber fields for Create field mapping.
     *
     * Returns email (required) + standard subscriber fields + custom fields.
     * Used by the Create Subscriber action.
     */
    public function fields(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);
        }

        $customFields = $this->fetchCustomFields($token);
        if ($customFields instanceof Response) {
            return $customFields;
        }

        $columns = [];

        // Email is required at the top level of the API request body
        $columns[] = [
            'value'    => 'email',
            'label'    => 'Email',
            'required' => true,
        ];

        // Standard built-in subscriber fields (sent inside `fields` object)
        foreach (self::STANDARD_FIELDS as $key => $label) {
            $columns[] = [
                'value' => $key,
                'label' => $label,
            ];
        }

        // Custom fields created by the user (also sent inside `fields` object)
        foreach ($customFields as $field) {
            $key  = $field['key'] ?? '';
            $name = $field['name'] ?? $key;

            if (empty($key)) {
                continue;
            }

            $columns[] = [
                'value' => $key,
                'label' => $name . ' (custom)',
            ];
        }

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

    /**
     * Get subscriber fields for Update field mapping.
     *
     * Returns standard subscriber fields + custom fields (no email —
     * the subscriber is already identified by subscriber_id).
     * Used by the Update Subscriber action.
     */
    public function updateFields(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);
        }

        $customFields = $this->fetchCustomFields($token);
        if ($customFields instanceof Response) {
            return $customFields;
        }

        $columns = [];

        // Standard built-in subscriber fields
        foreach (self::STANDARD_FIELDS as $key => $label) {
            $columns[] = [
                'value' => $key,
                'label' => $label,
            ];
        }

        // Custom fields
        foreach ($customFields as $field) {
            $key  = $field['key'] ?? '';
            $name = $field['name'] ?? $key;

            if (empty($key)) {
                continue;
            }

            $columns[] = [
                'value' => $key,
                'label' => $name . ' (custom)',
            ];
        }

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