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

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

use SRFM_Pro\Inc\Traits\Get_Instance;

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

/**
 * LatePoint Integration Handler Class
 *
 * @since 1.13.0
 */
class LatePoint_Integration {
	use Get_Instance;

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

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

		// Check if LatePoint custom fields controller exists.
		if ( ! class_exists( 'OsCustomFieldsController' ) ) {
			return $fields;
		}

		try {
			global $wpdb;

			// Get customer custom fields from LatePoint settings (following SureTriggers approach).
			$cache_key          = 'srfm_latepoint_customer_fields';
			$custom_fields_data = wp_cache_get( $cache_key );

			if ( false === $custom_fields_data ) {
				$customer_fields = $wpdb->get_row( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- There is no other way to get this data.
					$wpdb->prepare(
						"SELECT * FROM {$wpdb->prefix}latepoint_settings WHERE name = %s",
						'custom_fields_for_customer'
					)
				);

				if ( ! empty( $customer_fields ) && ! empty( $customer_fields->value ) ) {
					$custom_fields_data = json_decode( $customer_fields->value, true );
				} else {
					$custom_fields_data = [];
				}

				// Cache for 5 minutes.
				wp_cache_set( $cache_key, $custom_fields_data, '', 300 );
			}

			$formatted_fields = [];

			if ( is_array( $custom_fields_data ) ) {
				foreach ( $custom_fields_data as $field ) {
					if ( ! is_array( $field ) || empty( $field['id'] ) ) {
						continue;
					}

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

					$formatted_field = [
						'key'         => $field['id'],
						'label'       => $field['label'] ?? ucwords( str_replace( [ '_', '-' ], ' ', $field['id'] ) ),
						'type'        => $field_type,
						'required'    => ! empty( $field['required'] ),
						'description' => $field['placeholder'] ?? '',
					];

					// Add options for select fields.
					if ( 'select' === $field_type && ! 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,
									];
								} elseif ( is_array( $option ) && isset( $option['label'], $option['value'] ) ) {
									$formatted_field['options'][] = [
										'label' => $option['label'],
										'value' => $option['value'],
									];
								}
							}
						}
					}

					$formatted_fields[] = $formatted_field;
				}
			}

			return $formatted_fields;

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

	/**
	 * Get LatePoint services
	 *
	 * @param array $services Empty array (default filter value).
	 * @return array Services formatted for select dropdown.
	 * @since 1.13.0
	 */
	public function get_services( $services = [] ) {
		if ( ! $this->is_plugin_active() || ! class_exists( 'OsServiceModel' ) ) {
			return $services;
		}

		try {
			$service_model = new \OsServiceModel();
			$all_services  = $service_model->get_results_as_models();

			$formatted_services = [];

			if ( ! empty( $all_services ) ) {
				foreach ( $all_services as $service ) {
					if ( ! empty( $service->id ) ) {
						$formatted_services[] = [
							'value' => $service->id,
							'label' => $service->name ?? 'Service #' . $service->id,
						];
					}
				}
			}

			return $formatted_services;

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

	/**
	 * Get LatePoint agents by service
	 *
	 * @param array $agents Empty array (default filter value).
	 * @param array $dependencies Field dependencies including service_id.
	 * @return array Agents formatted for select dropdown.
	 * @since 1.13.0
	 */
	public function get_agents_by_service( $agents = [], $dependencies = [] ) {
		if ( ! $this->is_plugin_active() || ! class_exists( 'OsAgentModel' ) ) {
			return $agents;
		}

		// Get service_id from dependencies.
		$service_id = null;
		if ( ! empty( $dependencies['service_id'] ) ) {
			$service_id = intval( $dependencies['service_id'] );
		}

		try {
			$agent_model = new \OsAgentModel();

			// If service_id is provided, get agents connected to that service.
			if ( $service_id ) {
				// Check if agent-service connection exists.
				if ( class_exists( 'OsAgentServiceModel' ) ) {
					global $wpdb;
					$agent_service_table = $wpdb->prefix . 'latepoint_agent_services';

					// Try to get from cache first.
					$cache_key           = 'srfm_latepoint_agents_service_' . $service_id;
					$connected_agent_ids = wp_cache_get( $cache_key );

					if ( false === $connected_agent_ids ) {
						// Get agents connected to the service.
						$connected_agent_ids = $wpdb->get_col( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
							$wpdb->prepare(
								"SELECT agent_id FROM {$agent_service_table} WHERE service_id = %d", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
								$service_id
							)
						);

						// Cache for 5 minutes.
						wp_cache_set( $cache_key, $connected_agent_ids, '', HOUR_IN_SECONDS );
					}

					if ( ! empty( $connected_agent_ids ) ) {
						$agent_ids_string = implode( ',', array_map( 'intval', $connected_agent_ids ) );
						$all_agents       = $agent_model->where( [ 'id' => $agent_ids_string ] )->get_results_as_models();
					} else {
						$all_agents = [];
					}
				} else {
					// Fallback: get all agents if connection table doesn't exist.
					$all_agents = $agent_model->get_results_as_models();
				}
			} else {
				// No service specified, get all agents.
				$all_agents = $agent_model->get_results_as_models();
			}

			$formatted_agents = [];

			if ( ! empty( $all_agents ) ) {
				foreach ( $all_agents as $agent ) {
					if ( ! empty( $agent->id ) ) {
						$display_name = '';

						// Try to build display name from first + last name.
						$first_name = $agent->first_name ?? '';
						$last_name  = $agent->last_name ?? '';

						if ( $first_name || $last_name ) {
							$display_name = trim( $first_name . ' ' . $last_name );
						}

						// Fallback to email or ID.
						if ( empty( $display_name ) ) {
							$display_name = $agent->email ?? 'Agent #' . $agent->id;
						}

						$formatted_agents[] = [
							'value' => $agent->id,
							'label' => $display_name,
						];
					}
				}
			}

			return $formatted_agents;

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

	/**
	 * Get LatePoint booking statuses
	 *
	 * @param array $statuses Empty array (default filter value).
	 * @return array Statuses formatted for select dropdown.
	 * @since 1.13.0
	 */
	public function get_statuses( $statuses = [] ) {
		if ( ! $this->is_plugin_active() || ! class_exists( 'OsBookingHelper' ) ) {
			return $statuses;
		}

		try {
			// Get statuses from LatePoint using their helper method.
			$latepoint_statuses = \OsBookingHelper::get_statuses_list();

			$formatted_statuses = [];

			if ( ! empty( $latepoint_statuses ) ) {
				foreach ( $latepoint_statuses as $status_key => $status_label ) {
					$formatted_statuses[] = [
						'value' => $status_key,
						'label' => $status_label,
					];
				}
			}

			return $formatted_statuses;

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

	/**
	 * Get LatePoint customers
	 *
	 * @param array $customers Empty array (default filter value).
	 * @return array Customers formatted for select dropdown.
	 * @since 1.13.0
	 */
	public function get_customers( $customers = [] ) {
		if ( ! $this->is_plugin_active() || ! class_exists( 'OsCustomerHelper' ) ) {
			return $customers;
		}

		try {
			// Get customers from LatePoint using their helper method.
			$latepoint_customers = \OsCustomerHelper::get_customers_for_select();

			// The LatePoint function already returns the correct format with 'value' and 'label' keys.
			// We just need to rename 'value' to 'id' and 'label' to 'name' for consistency.
			$formatted_customers = [];

			if ( ! empty( $latepoint_customers ) ) {
				foreach ( $latepoint_customers as $customer_option ) {
					$formatted_customers[] = [
						'value' => $customer_option['value'],
						'label' => $customer_option['label'],
					];
				}
			}

			return $formatted_customers;

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

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

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

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

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

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

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

		// Fallback: Check for nested customer_fields structure.
		if ( empty( $custom_fields ) && ! empty( $data['customer_fields'] ) && is_array( $data['customer_fields'] ) ) {
			foreach ( $data['customer_fields'] as $field ) {
				if ( is_array( $field ) && ! empty( $field ) ) {
					foreach ( $field as $key => $value ) {
						if ( in_array( $key, $field_ids, true ) && '' !== $value ) {
							$custom_fields[ $key ] = sanitize_text_field( $value );
						}
					}
				}
			}
		}

		return $custom_fields;
	}

	/**
	 * Get LatePoint bookings
	 *
	 * @param array $bookings Empty array (default filter value).
	 * @return array Bookings formatted for select dropdown.
	 * @since 1.13.0
	 */
	public function get_bookings( $bookings = [] ) {
		if ( ! $this->is_plugin_active() || ! class_exists( 'OsBookingHelper' ) ) {
			return $bookings;
		}

		try {
			// Get bookings from LatePoint using their helper method.
			$latepoint_bookings = \OsBookingHelper::get_bookings_for_select();

			// The LatePoint function already returns the correct format with 'value' and 'label' keys.
			$formatted_bookings = [];

			if ( ! empty( $latepoint_bookings ) ) {
				foreach ( $latepoint_bookings as $booking_option ) {
					$formatted_bookings[] = [
						'value' => $booking_option['value'],
						'label' => $booking_option['label'],
					];
				}
			}

			return $formatted_bookings;

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

	/**
	 * Get LatePoint bundles
	 *
	 * @param array $bundles Empty array (default filter value).
	 * @return array Bundles formatted for select dropdown.
	 * @since 1.13.0
	 */
	public function get_bundles( $bundles = [] ) {
		if ( ! $this->is_plugin_active() || ! class_exists( 'OsBundleModel' ) ) {
			return $bundles;
		}

		try {
			$bundle_model = new \OsBundleModel();
			$all_bundles  = $bundle_model->get_results_as_models();

			$formatted_bundles = [];

			if ( ! empty( $all_bundles ) ) {
				foreach ( $all_bundles as $bundle ) {
					if ( ! empty( $bundle->id ) ) {
						$formatted_bundles[] = [
							'value' => $bundle->id,
							'label' => $bundle->name ?? 'Bundle #' . $bundle->id,
						];
					}
				}
			}

			return $formatted_bundles;

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

	/**
	 * Get LatePoint order statuses
	 *
	 * @param array $statuses Empty array (default filter value).
	 * @return array Order statuses formatted for select dropdown.
	 * @since 1.13.0
	 */
	public function get_order_statuses( $statuses = [] ) {
		if ( ! $this->is_plugin_active() || ! class_exists( 'OsOrdersHelper' ) ) {
			return $statuses;
		}

		try {
			$order_statuses     = \OsOrdersHelper::get_order_statuses_list();
			$formatted_statuses = [];

			if ( ! empty( $order_statuses ) ) {
				foreach ( $order_statuses as $key => $status ) {
					$formatted_statuses[] = [
						'value' => $key,
						'label' => $status,
					];
				}
			}

			return $formatted_statuses;

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

	/**
	 * Get LatePoint fulfillment statuses
	 *
	 * @param array $statuses Empty array (default filter value).
	 * @return array Fulfillment statuses formatted for select dropdown.
	 * @since 1.13.0
	 */
	public function get_fulfillment_statuses( $statuses = [] ) {
		if ( ! $this->is_plugin_active() || ! class_exists( 'OsOrdersHelper' ) ) {
			return $statuses;
		}

		try {
			$fulfillment_statuses = \OsOrdersHelper::get_fulfillment_statuses_list();
			$formatted_statuses   = [];

			if ( ! empty( $fulfillment_statuses ) ) {
				foreach ( $fulfillment_statuses as $key => $status ) {
					$formatted_statuses[] = [
						'value' => $key,
						'label' => $status,
					];
				}
			}

			return $formatted_statuses;

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

	/**
	 * Get LatePoint payment statuses
	 *
	 * @param array $statuses Empty array (default filter value).
	 * @return array Payment statuses formatted for select dropdown.
	 * @since 1.13.0
	 */
	public function get_payment_statuses( $statuses = [] ) {
		if ( ! $this->is_plugin_active() || ! class_exists( 'OsOrdersHelper' ) ) {
			return $statuses;
		}

		try {
			$payment_statuses   = \OsOrdersHelper::get_order_payment_statuses_list();
			$formatted_statuses = [];

			if ( ! empty( $payment_statuses ) ) {
				foreach ( $payment_statuses as $key => $status ) {
					$formatted_statuses[] = [
						'value' => $key,
						'label' => $status,
					];
				}
			}

			return $formatted_statuses;

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

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

	/**
	 * Register WordPress filters for LatePoint 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_latepoint_get_customer_fields', [ $this, 'get_customer_custom_fields' ] );
		add_filter( 'srfm_latepoint_get_services', [ $this, 'get_services' ] );
		add_filter( 'srfm_latepoint_get_agents_by_service', [ $this, 'get_agents_by_service' ] );
		add_filter( 'srfm_latepoint_get_statuses', [ $this, 'get_statuses' ] );
		add_filter( 'srfm_latepoint_get_customers', [ $this, 'get_customers' ] );
		add_filter( 'srfm_latepoint_get_bookings', [ $this, 'get_bookings' ] );
		add_filter( 'srfm_latepoint_get_bundles', [ $this, 'get_bundles' ] );
		add_filter( 'srfm_latepoint_get_order_statuses', [ $this, 'get_order_statuses' ] );
		add_filter( 'srfm_latepoint_get_fulfillment_statuses', [ $this, 'get_fulfillment_statuses' ] );
		add_filter( 'srfm_latepoint_get_payment_statuses', [ $this, 'get_payment_statuses' ] );

		// 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/create-customer.php',
			__DIR__ . '/actions/create-coupon.php',
			__DIR__ . '/actions/update-coupon.php',
			__DIR__ . '/actions/create-booking.php',
			__DIR__ . '/actions/create-agent.php',
			__DIR__ . '/actions/create-order.php',
			__DIR__ . '/actions/update-booking.php',
		];

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

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