<?php
/**
 * File Path: includes/api/esp/class-mbs-esp-moosend.php
 * Moosend 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_Moosend 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.moosend.com/v3/';
	private string $api_key;
	public function __construct( string $api_key ) { $this->api_key = $api_key; }
	protected function endpoint_url( string $endpoint ): string {
		return static::BASE_URL . $endpoint . ( strpos( $endpoint, '?' ) !== false ? '&' : '?' ) . 'apikey=' . rawurlencode( $this->api_key );
	}
	protected function auth_headers(): array { return array(); }
	public function connect(): bool {
		$r = $this->get( 'lists.json' );
		return ! is_wp_error( $r ) && 200 === (int) wp_remote_retrieve_response_code( $r );
	}
	public function get_lists(): array {
		$r = $this->get( 'lists.json' );
		if ( is_wp_error( $r ) ) { return array(); }
		$b = json_decode( wp_remote_retrieve_body( $r ), true );
		if ( empty( $b['Context']['MailingLists'] ) ) { return array(); }
		$out = array();
		foreach ( $b['Context']['MailingLists'] as $lst ) { $out[] = array( 'id' => (string) $lst['ID'], 'name' => (string) $lst['Name'] ); }
		return $out;
	}
	public function subscribe( string $email, string $name, string $list_id, bool $double_optin ): bool {
		$parts   = explode( ' ', $name, 2 );
		$payload = array(
			'Email'     => $email,
			'Name'      => $name,
			'HasExternalDoubleOptIn' => $double_optin,
		);
		$endpoint = 'subscribers/' . rawurlencode( $list_id ) . '/subscribe.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 {
		// Moosend uses custom fields as tags (same pattern as Campaign Monitor).
		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( 'Name' => $key, 'Value' => (string) $tag );
		}
		$payload  = array( 'Email' => $email, 'CustomFields' => $custom_fields );
		$endpoint = 'subscribers/' . rawurlencode( $list_id ) . '/update.json';
		$r = $this->post( $endpoint, $payload );
		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 {
		$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(
			'Name'           => $subject,
			'Subject'        => $subject,
			'SenderEmail'    => $reply_to,
			'ReplyToEmail'   => $reply_to,
			'MailingList'    => $list_id,
			'HTMLContent'    => $body_html,
			'PlainContent'   => wp_strip_all_tags( $body_html ),
		);
		$r = $this->post( 'campaigns/create.json', $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['Context']['CampaignID'] ) ? (string) $b['Context']['CampaignID'] : null;
	}
	public function send_campaign( string $campaign_id ): bool {
		$endpoint = 'campaigns/' . rawurlencode( $campaign_id ) . '/send/immediate.json';
		$r = $this->post( $endpoint, array(), 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; }
}
