<?php
/**
 * FluentCRM Integration Handler
 *
 * Handles all FluentCRM integration functionality including filters and actions.
 *
 * @package SureForms
 * @since 1.13.0
 */

namespace SRFM_Pro\Inc\Pro\Native_Integrations\Integrations\FluentCRM;

use SRFM_Pro\Inc\Traits\Get_Instance;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

/**
 * FluentCRM Integration Handler Class
 *
 * @since 1.13.0
 */
class FluentCRM_Integration {
	use Get_Instance;

	/**
	 * Constructor
	 *
	 * @since 1.13.0
	 */
	public function __construct() {
		$this->register_filters();
	}

	/**
	 * Get FluentCRM contact statuses
	 *
	 * @param array $statuses Empty array (default filter value).
	 * @return array Statuses formatted for select dropdown.
	 * @since 1.13.0
	 */
	public function get_contact_statuses( $statuses = [] ) {
		if ( ! $this->is_plugin_active() ) {
			return $statuses;
		}

		try {
			// Get the standard FluentCRM statuses.
			$fluentcrm_statuses = [
				'subscribed'   => __( 'Subscribed', 'sureforms-pro' ),
				'unsubscribed' => __( 'Unsubscribed', 'sureforms-pro' ),
				'pending'      => __( 'Pending', 'sureforms-pro' ),
				'bounced'      => __( 'Bounced', 'sureforms-pro' ),
				'complained'   => __( 'Complained', 'sureforms-pro' ),
			];

			$formatted_statuses = [];

			foreach ( $fluentcrm_statuses as $status_key => $status_label ) {
				$formatted_statuses[] = [
					'value' => $status_key,
					'label' => $status_label,
				];
			}

			return $formatted_statuses;

		} catch ( \Exception $e ) {
			return $statuses;
		}
	}

	/**
	 * Get FluentCRM tags
	 *
	 * @param array $tags Empty array (default filter value).
	 * @return array Tags formatted for select dropdown.
	 * @since 1.13.0
	 */
	public function get_tags( $tags = [] ) {
		if ( ! $this->is_plugin_active() || ! class_exists( 'FluentCrm\App\Models\Tag' ) ) {
			return $tags;
		}

		try {
			$tag_model = new \FluentCrm\App\Models\Tag();
			$all_tags  = $tag_model->get();

			$formatted_tags = [];

			if ( ! empty( $all_tags ) ) {
				foreach ( $all_tags as $tag ) {
					if ( ! empty( $tag->id ) ) {
						$formatted_tags[] = [
							'value' => $tag->id,
							'label' => $tag->title ?? 'Tag #' . $tag->id,
						];
					}
				}
			}

			return $formatted_tags;

		} catch ( \Exception $e ) {
			return $tags;
		}
	}

	/**
	 * Get FluentCRM lists
	 *
	 * @param array $lists Empty array (default filter value).
	 * @return array Lists formatted for select dropdown.
	 * @since 1.13.0
	 */
	public function get_lists( $lists = [] ) {
		if ( ! $this->is_plugin_active() || ! class_exists( 'FluentCrm\App\Models\Lists' ) ) {
			return $lists;
		}

		try {
			$list_model = new \FluentCrm\App\Models\Lists();
			$all_lists  = $list_model->get();

			$formatted_lists = [];

			if ( ! empty( $all_lists ) ) {
				foreach ( $all_lists as $list ) {
					if ( ! empty( $list->id ) ) {
						$formatted_lists[] = [
							'value' => $list->id,
							'label' => $list->title ?? 'List #' . $list->id,
						];
					}
				}
			}

			return $formatted_lists;

		} catch ( \Exception $e ) {
			return $lists;
		}
	}

	/**
	 * Get FluentCRM custom fields
	 *
	 * @param array $fields Empty array (default filter value).
	 * @return array Custom fields formatted for SureForms.
	 * @since 1.13.0
	 */
	public function get_custom_fields( $fields = [] ) {
		if ( ! $this->is_plugin_active() || ! function_exists( 'fluentcrm_get_custom_contact_fields' ) ) {
			return $fields;
		}

		try {
			$custom_fields_data = fluentcrm_get_custom_contact_fields();

			$formatted_fields = [];

			if ( is_array( $custom_fields_data ) ) {
				foreach ( $custom_fields_data as $field_key => $field ) {
					if ( ! is_array( $field ) || empty( $field['label'] ) ) {
						continue;
					}

					$field_type = $field['type'] ?? 'text';

					// Map FluentCRM field types to SureForms field types.
					$sureforms_type = $this->map_field_type( $field_type );

					$formatted_field = [
						'key'         => $field_key,
						'label'       => $field['label'],
						'type'        => $sureforms_type,
						'required'    => ! empty( $field['required'] ),
						'description' => $field['help'] ?? '',
					];

					// Add options for select fields.
					if ( in_array( $field_type, [ 'select-one', 'select-multi', 'radio', 'checkbox' ], true ) && ! empty( $field['options'] ) ) {
						$formatted_field['options'] = [];
						if ( is_array( $field['options'] ) ) {
							foreach ( $field['options'] as $option ) {
								if ( is_string( $option ) ) {
									$formatted_field['options'][] = [
										'label' => $option,
										'value' => $option,
									];
								}
							}
						}
					}

					$formatted_fields[] = $formatted_field;
				}
			}

			return $formatted_fields;

		} catch ( \Exception $e ) {
			return $fields;
		}
	}

	/**
	 * Extract custom fields from form data using FluentCRM field definitions
	 *
	 * @param array $data Form data.
	 * @return array Custom fields array.
	 * @since 1.13.0
	 */
	public static function extract_custom_fields( $data ) {
		$custom_fields = [];

		// Get available custom fields from FluentCRM using the same filter.
		$available_fields = apply_filters( 'srfm_fluentcrm_get_custom_fields', [] );

		if ( empty( $available_fields ) || ! is_array( $available_fields ) ) {
			return $custom_fields;
		}

		// Extract field keys from available fields.
		$field_keys = [];
		foreach ( $available_fields as $field ) {
			if ( is_array( $field ) && ! empty( $field['key'] ) ) {
				$field_keys[] = $field['key'];
			}
		}

		if ( empty( $field_keys ) ) {
			return $custom_fields;
		}

		// Extract custom field values from form data based on field keys.
		foreach ( $field_keys as $field_key ) {
			if ( isset( $data[ $field_key ] ) && '' !== $data[ $field_key ] ) {
				$custom_fields[ $field_key ] = sanitize_text_field( $data[ $field_key ] );
			}
		}

		return $custom_fields;
	}

	/**
	 * Process tags and return tag IDs with names
	 *
	 * @param mixed $tags Tags data from form.
	 * @param array $tag_names Reference to store tag names.
	 * @return array Array of tag IDs.
	 * @since 1.13.0
	 */
	public static function process_tags( $tags, &$tag_names ) {
		$tag_ids = [];

		if ( is_array( $tags ) ) {
			foreach ( $tags as $tag ) {
				// Handle object format with value/label (from form field selection).
				if ( is_array( $tag ) && isset( $tag['value'], $tag['label'] ) ) {
					$tag_ids[]   = intval( $tag['value'] );
					$tag_names[] = esc_html( $tag['label'] );
				} elseif ( is_numeric( $tag ) ) {
					// Handle simple array of IDs (from multi-select-async).
					$tag_id    = intval( $tag );
					$tag_ids[] = $tag_id;

					// Get tag name from FluentCRM if available.
					if ( class_exists( 'FluentCrm\App\Models\Tag' ) ) {
						$tag_obj = \FluentCrm\App\Models\Tag::find( $tag_id );
						if ( $tag_obj ) {
							$tag_names[] = esc_html( $tag_obj->title );
						}
					}
				} elseif ( is_string( $tag ) && is_numeric( $tag ) ) {
					// Handle string IDs.
					$tag_id    = intval( $tag );
					$tag_ids[] = $tag_id;

					// Get tag name from FluentCRM if available.
					if ( class_exists( 'FluentCrm\App\Models\Tag' ) ) {
						$tag_obj = \FluentCrm\App\Models\Tag::find( $tag_id );
						if ( $tag_obj ) {
							$tag_names[] = esc_html( $tag_obj->title );
						}
					}
				}
			}
		} elseif ( is_string( $tags ) ) {
			// Handle comma-separated tag IDs or names.
			$tags_arr = array_filter( array_map( 'trim', explode( ',', $tags ) ) );

			foreach ( $tags_arr as $tag ) {
				if ( is_numeric( $tag ) ) {
					// It's a tag ID.
					$tag_id    = intval( $tag );
					$tag_ids[] = $tag_id;

					// Get tag name from FluentCRM if available.
					if ( class_exists( 'FluentCrm\App\Models\Tag' ) ) {
						$tag_obj = \FluentCrm\App\Models\Tag::find( $tag_id );
						if ( $tag_obj ) {
							$tag_names[] = esc_html( $tag_obj->title );
						}
					}
				} else {
					// It's a tag name - find or create (only for Add Contact).
					if ( ! class_exists( 'FluentCrm\App\Models\Tag' ) ) {
						continue; // Skip if FluentCRM Tag model not available.
					}

					$existing_tag = \FluentCrm\App\Models\Tag::where( 'title', $tag )->orWhere( 'slug', sanitize_title( $tag ) )->first();

					if ( $existing_tag ) {
						$tag_ids[]   = $existing_tag->id;
						$tag_names[] = esc_html( $existing_tag->title );
					}
					// Note: Tag creation is handled only in Add Contact action.
				}
			}
		}

		return array_unique( array_filter( $tag_ids ) );
	}

	/**
	 * Process lists and return list IDs with names
	 *
	 * @param mixed $lists Lists data from form.
	 * @param array $list_names Reference to store list names.
	 * @return array Array of list IDs.
	 * @since 1.13.0
	 */
	public static function process_lists( $lists, &$list_names ) {
		$list_ids = [];

		if ( is_array( $lists ) ) {
			foreach ( $lists as $list ) {
				// Handle object format with value/label (from form field selection).
				if ( is_array( $list ) && isset( $list['value'], $list['label'] ) ) {
					$list_ids[]   = intval( $list['value'] );
					$list_names[] = esc_html( $list['label'] );
				} elseif ( is_numeric( $list ) ) {
					// Handle simple array of IDs (from multi-select-async).
					$list_id    = intval( $list );
					$list_ids[] = $list_id;

					// Get list name from FluentCRM if available.
					if ( class_exists( 'FluentCrm\App\Models\Lists' ) ) {
						$list_obj = \FluentCrm\App\Models\Lists::find( $list_id );
						if ( $list_obj ) {
							$list_names[] = esc_html( $list_obj->title );
						}
					}
				} elseif ( is_string( $list ) && is_numeric( $list ) ) {
					// Handle string IDs.
					$list_id    = intval( $list );
					$list_ids[] = $list_id;

					// Get list name from FluentCRM if available.
					if ( class_exists( 'FluentCrm\App\Models\Lists' ) ) {
						$list_obj = \FluentCrm\App\Models\Lists::find( $list_id );
						if ( $list_obj ) {
							$list_names[] = esc_html( $list_obj->title );
						}
					}
				}
			}
		} elseif ( is_string( $lists ) ) {
			// Handle comma-separated list IDs.
			$lists_arr = array_filter( array_map( 'trim', explode( ',', $lists ) ) );
			foreach ( $lists_arr as $list ) {
				if ( is_numeric( $list ) ) {
					$list_id    = intval( $list );
					$list_ids[] = $list_id;

					// Get list name from FluentCRM if available.
					if ( class_exists( 'FluentCrm\App\Models\Lists' ) ) {
						$list_obj = \FluentCrm\App\Models\Lists::find( $list_id );
						if ( $list_obj ) {
							$list_names[] = esc_html( $list_obj->title );
						}
					}
				}
			}
		}

		return array_unique( array_filter( $list_ids ) );
	}

	/**
	 * Map FluentCRM field types to SureForms field types
	 *
	 * @param string $fluentcrm_type FluentCRM field type.
	 * @return string SureForms field type.
	 * @since 1.13.0
	 */
	private function map_field_type( $fluentcrm_type ) {
		$type_mapping = [
			'text'         => 'text',
			'email'        => 'email',
			'number'       => 'number',
			'date'         => 'date',
			'date_time'    => 'datetime-local',
			'textarea'     => 'textarea',
			'select-one'   => 'select',
			'select-multi' => 'multi-select',
			'radio'        => 'radio',
			'checkbox'     => 'checkbox',
			'phone'        => 'tel',
			'url'          => 'url',
		];

		return $type_mapping[ $fluentcrm_type ] ?? 'text';
	}

	/**
	 * Check if FluentCRM plugin is active
	 *
	 * @return bool True if FluentCRM is active, false otherwise.
	 * @since 1.13.0
	 */
	private function is_plugin_active() {
		return defined( 'FLUENTCRM' );
	}

	/**
	 * Register WordPress filters for FluentCRM field discovery
	 *
	 * @since 1.13.0
	 * @return void
	 */
	private function register_filters() {
		if ( ! $this->is_plugin_active() ) {
			return;
		}

		// Register filters for dynamic fields.
		add_filter( 'srfm_fluentcrm_get_contact_statuses', [ $this, 'get_contact_statuses' ] );
		add_filter( 'srfm_fluentcrm_get_tags', [ $this, 'get_tags' ] );
		add_filter( 'srfm_fluentcrm_get_lists', [ $this, 'get_lists' ] );
		add_filter( 'srfm_fluentcrm_get_custom_fields', [ $this, 'get_custom_fields' ] );

		// Load action files (they will auto-register when loaded).
		$this->load_action_files();
	}

	/**
	 * Load action files - they auto-register their handlers when loaded
	 *
	 * @since 1.13.0
	 * @return void
	 */
	private function load_action_files() {
		$action_files = [
			__DIR__ . '/actions/add-contact.php',
			__DIR__ . '/actions/remove-contact.php',
		];

		foreach ( $action_files as $file ) {
			if ( file_exists( $file ) ) {
				require_once $file;
			}
		}
	}
}

// Initialize the class using the singleton pattern.
FluentCRM_Integration::get_instance();
