<?php
/**
 * File Path: includes/api/esp/class-mbs-esp-campaignmonitor.php
 * Campaign Monitor ESP Adapter -- My Book Showroom
 * Sprint F-026: Email Channel Integration.
 * @package My_Book_Showroom
 * @since   1.1.0
 */
if ( ! defined( 'ABSPATH' ) ) { exit; }

class MBS_ESP_CampaignMonitor extends MBS_ESP_Adapter_Base { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- mbs_/MBS_ prefix is correct; scanner not configured with plugin prefix
	protected const BASE_URL = 'https://api.createsend.com/api/v3.3/';
	private string $api_key;
	/** @var string|null Cached client ID (fetched once per request). */
	private ?string $client_id = null;
	public function __construct( string $api_key ) { $this->api_key = $api_key; }
	public function connect(): bool {
		$r = $this->get( 'clients.json' );
		return ! is_wp_error( $r ) && 200 === (int) wp_remote_retrieve_response_code( $r );
	}
	public function get_lists(): array {
		$client_id = $this->get_client_id();
		if ( '' === $client_id ) { return array(); }
		$r = $this->get( 'clients/' . rawurlencode( $client_id ) . '/lists.json' );
		if ( is_wp_error( $r ) ) { return array(); }
		$b = json_decode( wp_remote_retrieve_body( $r ), true );
		if ( ! is_array( $b ) ) { return array(); }
		$out = array();
		foreach ( $b as $lst ) { $out[] = array( 'id' => (string) $lst['ListID'], 'name' => (string) $lst['Name'] ); }
		return $out;
	}
	public function subscribe( string $email, string $name, string $list_id, bool $double_optin ): bool {
		$payload = array( 'EmailAddress' => $email, 'Name' => $name, 'Resubscribe' => true );
		if ( $double_optin ) { $payload['ConsentToTrack'] = 'yes'; }
		$endpoint = 'subscribers/' . rawurlencode( $list_id ) . '.json';
		$r = $this->post( $endpoint, $payload );
		if ( is_wp_error( $r ) ) { return false; }
		return (int) wp_remote_retrieve_response_code( $r ) >= 200 && (int) wp_remote_retrieve_response_code( $r ) < 300;
	}
	public function tag_contact( string $email, array $tags, string $list_id ): bool {
		// Campaign Monitor uses custom fields as tags.
		if ( empty( $tags ) ) { return true; }
		$custom_fields = array();
		$field_keys = array( 'mbs_tag_book', 'mbs_tag_series', 'mbs_tag_genre' );
		foreach ( array_values( $tags ) as $idx => $tag ) {
			$key = $field_keys[ $idx ] ?? ( 'mbs_tag_' . $idx );
			$custom_fields[] = array( 'Key' => $key, 'Value' => (string) $tag );
		}
		$endpoint = 'subscribers/' . rawurlencode( $list_id ) . '.json';
		$r = $this->post( $endpoint, array( 'EmailAddress' => $email, 'CustomFields' => $custom_fields, 'Resubscribe' => false ) );
		return ! is_wp_error( $r ) && (int) wp_remote_retrieve_response_code( $r ) >= 200 && (int) wp_remote_retrieve_response_code( $r ) < 300;
	}
	public function supports_tags(): bool { return true; }
	public function create_campaign( string $subject, string $body_html, string $list_id ): ?string {
		$client_id = $this->get_client_id();
		if ( '' === $client_id ) { return null; }
		$from_name  = mbs_get_setting( 'email', 'from_name', '' );
		if ( empty( $from_name ) ) {
			$from_name = get_bloginfo( 'name' );
		}
		$reply_to   = mbs_get_setting( 'email', 'reply_to', '' );
		if ( empty( $reply_to ) ) {
			$reply_to = get_option( 'admin_email', '' );
		}
		$payload = array(
			'Subject'     => $subject,
			'Name'        => $subject,
			'FromName'    => $from_name,
			'FromEmail'   => $reply_to,
			'ReplyTo'     => $reply_to,
			'HtmlUrl'     => '',
			'TextUrl'     => '',
			'ListIDs'     => array( $list_id ),
		);
		$endpoint = 'campaigns/' . rawurlencode( $client_id ) . '.json';
		$r = $this->post( $endpoint, $payload, self::TIMEOUT_CAMPAIGN );
		if ( is_wp_error( $r ) ) { return null; }
		if ( (int) wp_remote_retrieve_response_code( $r ) < 200 || (int) wp_remote_retrieve_response_code( $r ) >= 300 ) { return null; }
		$b = json_decode( wp_remote_retrieve_body( $r ), true );
		return isset( $b ) ? (string) $b : null;
	}
	public function send_campaign( string $campaign_id ): bool {
		$endpoint = 'campaigns/' . rawurlencode( $campaign_id ) . '/send.json';
		$r = $this->post( $endpoint, array( 'ConfirmationEmail' => '', 'SendDate' => 'Immediately' ), self::TIMEOUT_CAMPAIGN );
		return ! is_wp_error( $r ) && (int) wp_remote_retrieve_response_code( $r ) >= 200 && (int) wp_remote_retrieve_response_code( $r ) < 300;
	}
	public function supports_campaigns(): bool { return true; }
	/** Fetch and cache the first client ID (campaigns require it). */
	private function get_client_id(): string {
		if ( null !== $this->client_id ) { return $this->client_id; }
		// Try transient first (1-hour cache).
		$cached = get_transient( 'mbs_esp_cm_client_id_' . get_current_blog_id() );
		if ( false !== $cached ) { $this->client_id = (string) $cached; return $this->client_id; }
		$r = $this->get( 'clients.json' );
		if ( is_wp_error( $r ) ) { $this->client_id = ''; return ''; }
		$b = json_decode( wp_remote_retrieve_body( $r ), true );
		$cid = $b[0]['ClientID'] ?? '';
		$this->client_id = (string) $cid;
		if ( '' !== $this->client_id ) { set_transient( 'mbs_esp_cm_client_id_' . get_current_blog_id(), $this->client_id, HOUR_IN_SECONDS ); }
		return $this->client_id;
	}
	protected function auth_headers(): array { return array( 'Authorization' => 'Basic ' . base64_encode( $this->api_key . ':x' ) ); }
}
