<?php
/**
 * Feed value object.
 *
 * @package RewindBrevoFormBridge
 */

namespace RewindBrevoFormBridge\Feeds;

defined( 'ABSPATH' ) || exit;

/**
 * Typed accessors over one rbfb_feeds row and its JSON config.
 *
 * @since 0.3.0
 */
class Feed {

	/**
	 * Row id (0 for an unsaved feed).
	 *
	 * @var int
	 */
	private int $id;

	/**
	 * Adapter slug.
	 *
	 * @var string
	 */
	private string $adapter;

	/**
	 * Form id.
	 *
	 * @var string
	 */
	private string $form_id;

	/**
	 * Feed title.
	 *
	 * @var string
	 */
	private string $title;

	/**
	 * 'active' | 'paused'.
	 *
	 * @var string
	 */
	private string $status;

	/**
	 * Decoded JSON config.
	 *
	 * @var array
	 */
	private array $config;

	/**
	 * Constructor.
	 *
	 * @since 0.3.0
	 * @param int    $id      Row id.
	 * @param string $adapter Adapter slug.
	 * @param string $form_id Form id.
	 * @param string $title   Title.
	 * @param string $status  Status.
	 * @param array  $config  Decoded config.
	 */
	public function __construct( int $id, string $adapter, string $form_id, string $title, string $status, array $config ) {
		$this->id      = $id;
		$this->adapter = $adapter;
		$this->form_id = $form_id;
		$this->title   = $title;
		$this->status  = $status;
		$this->config  = $config;
	}

	/**
	 * Build from a database row (stdClass or array).
	 *
	 * @since 0.3.0
	 * @param object|array $row The rbfb_feeds row.
	 * @return Feed
	 */
	public static function from_row( $row ): Feed {
		$row    = (array) $row;
		$config = json_decode( isset( $row['config'] ) ? (string) $row['config'] : '{}', true );

		return new self(
			isset( $row['id'] ) ? (int) $row['id'] : 0,
			isset( $row['adapter'] ) ? (string) $row['adapter'] : '',
			isset( $row['form_id'] ) ? (string) $row['form_id'] : '',
			isset( $row['title'] ) ? (string) $row['title'] : '',
			isset( $row['status'] ) ? (string) $row['status'] : 'active',
			is_array( $config ) ? $config : array()
		);
	}

	/**
	 * Row id.
	 *
	 * @since 0.3.0
	 * @return int
	 */
	public function id(): int {
		return $this->id;
	}

	/**
	 * Adapter slug.
	 *
	 * @since 0.3.0
	 * @return string
	 */
	public function adapter(): string {
		return $this->adapter;
	}

	/**
	 * Form id.
	 *
	 * @since 0.3.0
	 * @return string
	 */
	public function form_id(): string {
		return $this->form_id;
	}

	/**
	 * Title.
	 *
	 * @since 0.3.0
	 * @return string
	 */
	public function title(): string {
		return $this->title;
	}

	/**
	 * Status.
	 *
	 * @since 0.3.0
	 * @return string
	 */
	public function status(): string {
		return $this->status;
	}

	/**
	 * Whole config array.
	 *
	 * @since 0.3.0
	 * @return array
	 */
	public function config(): array {
		return $this->config;
	}

	/**
	 * Brevo list ids to subscribe to.
	 *
	 * @since 0.3.0
	 * @return int[]
	 */
	public function list_ids(): array {
		$ids = isset( $this->config['lists'] ) && is_array( $this->config['lists'] ) ? $this->config['lists'] : array();

		return array_values( array_filter( array_map( 'intval', $ids ) ) );
	}

	/**
	 * Field mappings.
	 *
	 * @since 0.3.0
	 * @return array [ ['field_key','attribute','brevo_type','required','date_format'], ... ]
	 */
	public function mappings(): array {
		$mappings = isset( $this->config['mappings'] ) && is_array( $this->config['mappings'] ) ? $this->config['mappings'] : array();
		$clean    = array();

		foreach ( $mappings as $mapping ) {
			if ( ! is_array( $mapping ) || empty( $mapping['field_key'] ) || empty( $mapping['attribute'] ) ) {
				continue;
			}

			$clean[] = array(
				'field_key'   => (string) $mapping['field_key'],
				'attribute'   => (string) $mapping['attribute'],
				'brevo_type'  => isset( $mapping['brevo_type'] ) ? (string) $mapping['brevo_type'] : 'text',
				'required'    => ! empty( $mapping['required'] ),
				'date_format' => isset( $mapping['date_format'] ) ? (string) $mapping['date_format'] : '',
			);
		}

		return $clean;
	}

	/**
	 * The field key that supplies the contact email.
	 *
	 * @since 0.3.0
	 * @return string
	 */
	public function email_field(): string {
		return isset( $this->config['email_field'] ) ? (string) $this->config['email_field'] : '';
	}

	/**
	 * Whether existing Brevo contacts are updated (maps to updateEnabled).
	 *
	 * @since 0.3.0
	 * @return bool
	 */
	public function update_existing(): bool {
		return ! array_key_exists( 'update_existing', $this->config ) || ! empty( $this->config['update_existing'] );
	}

	/**
	 * Consent checkbox field key, or null when the owner declared none.
	 *
	 * @since 0.3.0
	 * @return string|null
	 */
	public function consent_field(): ?string {
		$field = isset( $this->config['consent_field'] ) ? (string) $this->config['consent_field'] : '';

		return '' !== $field ? $field : null;
	}

	/**
	 * Whether consent is required before pushing.
	 *
	 * True whenever a consent field is set; false only when the owner
	 * explicitly ticked "no consent field required".
	 *
	 * @since 0.3.0
	 * @return bool
	 */
	public function consent_required(): bool {
		return null !== $this->consent_field();
	}

	/**
	 * Double opt-in config. Stubbed until Phase 6 — stored but unused.
	 *
	 * @since 0.3.0
	 * @return array ['enabled' => bool, 'template_id' => int, 'redirect_url' => string]
	 */
	public function doi(): array {
		$doi = isset( $this->config['doi'] ) && is_array( $this->config['doi'] ) ? $this->config['doi'] : array();

		return array(
			'enabled'      => ! empty( $doi['enabled'] ),
			'template_id'  => isset( $doi['template_id'] ) ? (int) $doi['template_id'] : 0,
			'redirect_url' => isset( $doi['redirect_url'] ) ? (string) $doi['redirect_url'] : '',
		);
	}
}
