<?php
/**
 * @license GPL-2.0-or-later
 * @link    https://wordpress.org/plugins/pressio-crm
 */
namespace PressioCRM\Integrations;

defined( 'ABSPATH' ) || exit;

use PressioCRM\Models\ContactModel;
use PressioCRM\Models\ActivityModel;
use PressioCRM\Models\IntegrationModel;

class WpformsIntegration {

	public function slug(): string {
		return 'wpforms';
	}

	public function register(): void {
		// Fires after WPForms successfully processes a submission.
		// Params: array $fields, array $entry, array $form_data, int $entry_id
		add_action( 'wpforms_process_complete', [ $this, 'handle_submission' ], 10, 4 );
	}

	// -------------------------------------------------------------------------
	// Handle submission
	// -------------------------------------------------------------------------

	public function handle_submission( array $fields, array $entry, array $form_data, int $entry_id ): void {
		$form_id = (string) ( $form_data['id'] ?? 0 );
		if ( ! $form_id ) {
			return;
		}

		$mapping = IntegrationModel::get_for_object( 'wpforms', $form_id );

		if ( ! $mapping || ! $mapping->is_active ) {
			return;
		}

		$config = json_decode( $mapping->config ?? '{}', true );
		if ( ! is_array( $config ) || empty( $config ) ) {
			return;
		}

		// Build contact data. Config stores field IDs as strings.
		$contact_data  = [ 'source' => 'wpforms' ];
		$string_fields = [ 'email', 'first_name', 'last_name', 'phone', 'company' ];

		foreach ( $string_fields as $field ) {
			if ( empty( $config[ $field ] ) ) {
				continue;
			}

			$field_id = (int) $config[ $field ];
			$value    = $fields[ $field_id ]['value'] ?? '';

			if ( is_array( $value ) ) {
				$value = implode( ', ', $value );
			}

			$value = trim( (string) $value );

			if ( '' === $value ) {
				continue;
			}

			$contact_data[ $field ] = 'email' === $field
				? sanitize_email( $value )
				: sanitize_text_field( $value );
		}

		// Email is required.
		if ( empty( $contact_data['email'] ) ) {
			return;
		}

		$existing = ContactModel::find_by_email( $contact_data['email'] );
		$is_new   = false;

		if ( $existing ) {
			// Only fill in fields that are currently empty on the existing contact.
			$update_data = [];
			foreach ( $contact_data as $key => $value ) {
				if ( 'source' === $key || 'email' === $key ) {
					continue;
				}
				if ( '' !== $value && empty( $existing->{$key} ) ) {
					$update_data[ $key ] = $value;
				}
			}

			if ( ! empty( $update_data ) ) {
				$existing->update( $update_data );
			}

			$contact_id = (int) $existing->id;
		} else {
			$contact    = ContactModel::create( $contact_data );
			$contact_id = (int) $contact->id;
			$is_new     = true;
		}

		// New contacts: ContactModel::create() already fires contact_created_from_form.
		// Returning contacts: log the repeat submission as an activity.
		if ( ! $is_new ) {
			$form_title = sanitize_text_field( $form_data['settings']['form_title'] ?? '' );

			ActivityModel::log( [
				'contact_id' => $contact_id,
				'type'       => 'contact_created_from_form',
				'title'      => sprintf(
					/* translators: %s: WPForms form title */
					__( 'Submitted form: %s', 'pressio-crm' ),
					$form_title
				),
				'meta'       => [
					'source'    => 'wpforms',
					'form_name' => $form_title,
					'form_id'   => $form_id,
				],
			] );
		}

		do_action( 'pressio_crm_contact_created_from_form', $contact_id, 'wpforms', $fields );
	}
}
