<?php
/**
 * Adapter registry: the single entry point for the capture layer.
 *
 * @package Leadite
 */

namespace Leadite\Capture;

use Leadite\Config;
use Leadite\Storage\Lead;
use Leadite\Storage\LeadsRepository;
use Leadite\Support\FieldMapper;

defined( 'ABSPATH' ) || exit;

class AdapterRegistry {

	/** @var SourceAdapter[] */
	protected $adapters = array();

	/**
	 * Build the default adapter set, allow extension via filter,
	 * then register the ones that are available + enabled.
	 */
	public function boot() {
		$adapters = array(
			new Cf7Adapter(),
			new ElementorAdapter(),
			new WpformsAdapter(),
			new NinjaFormsAdapter(),
			new GravityFormsAdapter(),
			new FluentFormsAdapter(),
		);

		/**
		 * Allow third parties to add adapters without touching core.
		 *
		 * @param SourceAdapter[] $adapters Adapters.
		 */
		$adapters = apply_filters( 'Leadite/adapters', $adapters );

		$enabled = (array) Config::get( 'enabled_sources', array( 'cf7', 'elementor' ) );

		foreach ( $adapters as $adapter ) {
			if ( ! $adapter instanceof SourceAdapter ) {
				continue;
			}
			if ( ! in_array( $adapter->slug(), $enabled, true ) ) {
				continue;
			}
			if ( ! $adapter->is_available() ) {
				continue;
			}
			$this->adapters[ $adapter->slug() ] = $adapter;
			$adapter->register();
		}
	}

	/**
	 * Registered adapters (slug => adapter).
	 *
	 * @return SourceAdapter[]
	 */
	public function adapters() {
		return $this->adapters;
	}

	/**
	 * Normalize, enrich and persist a Lead. Adapters call this.
	 *
	 * @param Lead $lead Lead built by an adapter.
	 * @return int Stored submission ID (0 = skipped/duplicate/failure).
	 */
	public static function store( Lead $lead ) {
		FieldMapper::attach_request_meta( $lead );
		FieldMapper::apply_canonical( $lead );

		/**
		 * Last chance to mutate a lead before it is saved
		 * (spam scoring, field filtering, etc.).
		 *
		 * @param Lead $lead Lead.
		 */
		$lead = apply_filters( 'Leadite/pre_store_lead', $lead );

		return LeadsRepository::insert( $lead );
	}
}