<?php

if ( ! BWFAN_PRO_Common::is_lite_3_0() && ! class_exists( 'BWFAN_Conversions' ) ) {

	class BWFAN_Conversions {
		private static $ins = null;

		public static function get_instance() {
			if ( null === self::$ins ) {
				self::$ins = new self();
			}

			return self::$ins;
		}

		public function __construct() {
			add_action( 'woocommerce_order_refunded', array( $this, 'remove_conversion' ) );
			add_action( 'woocommerce_order_status_cancelled', array( $this, 'remove_conversion' ) );
			add_action( 'before_delete_post', array( $this, 'remove_conversion_on_deletion' ), 10, 2 );
			add_filter( 'bwfan_get_global_settings', array( $this, 'modify_conversion_def_value_global' ), 10, 1 );
			add_action( 'bwfan_external_event_settings', array( $this, 'bwfan_event_global_tracking_enable' ) );

			add_action( 'bwf_normalize_contact_meta_after_save', array( $this, 'process_order_for_conversion' ), 5, 3 );
		}

		/**
		 * Helper function
		 *
		 * Runs on bwf_normalize_contact_meta_after_save
		 *
		 * @param $bwf_contact WooFunnels_Contact
		 * @param $order_id
		 * @param $order WC_Order
		 */
		public function process_order_for_conversion( $bwf_contact, $order_id, $order ) {
			/** Don't process orders for conversion during the WC Import (Indexing) */
			if ( true === WooFunnels_DB_Updater::$indexing ) {
				return;
			}

			/** If renewal order, don't mark conversion */
			if ( function_exists( 'wcs_order_contains_renewal' ) && wcs_order_contains_renewal( $order ) ) {
				return;
			}

			/** Check if the Conversion already exists: */
			$existing_conversion = BWFAN_Model_Conversions::get_specific_rows( 'wcid', absint( $order_id ) );
			if ( ! empty( $existing_conversion ) ) {
				return;
			}

			$order_id = absint( $order_id );
			if ( ! $order instanceof WC_Order ) {
				$order = wc_get_order( absint( $order_id ) );
			}

			if ( ! $order instanceof WC_Order || 'shop_order' !== $order->get_type() ) {
				return;
			}

			$contact_id = $bwf_contact->get_id();
			if ( empty( $contact_id ) ) {
				return;
			}

			/** checking if there is any used $coupons of autonami generated */
			$coupons = $order->get_coupon_codes();
			if ( is_array( $coupons ) && count( $coupons ) > 0 ) {
				$is_conversion = $this->check_coupon_for_conversion( $contact_id, $order_id, $order, $coupons );
				if ( true === $is_conversion ) {
					/** Found used coupon created by automation or broadcast */
					return;
				}
			}

			global $wpdb;
			$global_settings             = BWFAN_Common::get_global_settings();
			$email_order_conversion_days = $global_settings['bwfan_order_tracking_conversion'];
			$email_order_strtotime       = $email_order_conversion_days * DAY_IN_SECONDS;
			$order_creation_date         = $order->get_date_created();
			$order_from                  = ( strtotime( $order_creation_date ) - $email_order_strtotime );
			$order_from                  = date( 'Y-m-d', $order_from );
			$order_to                    = date( 'Y-m-d', strtotime( $order_creation_date ) );

			/** Get automation ids in which don't need to mark conversion */
			$skip_aids = BWFAN_PRO_Common::get_skip_conversion_automations();
			$skip_aids = implode( ', ', $skip_aids );

			/** If empty then use single quotes to avoid the sql error */
			if ( empty( $skip_aids ) ) {
				$skip_aids = "''";
			}

			$email_open = '(`mode` = 1 && `open` > 0)';
			if ( false === apply_filters( 'bwfan_conversion_on_email_open', true ) ) {
				$email_open = '(`mode` = 1 && `click` > 0)';
			}

			/**
			 * Fetching conversations where email opened or sms clicked of automation or broadcast within given date range
			 */
			$query   = $wpdb->prepare( "SELECT `ID`, `cid`, `oid`, `type` FROM `{$wpdb->prefix}bwfan_engagement_tracking` WHERE DATE(`created_at`) >= %s AND DATE(`created_at`) <= %s AND ($email_open OR ((`mode` = 2 || `mode` = 3) && `click` > 0)) AND `hash_code` != '' AND `cid` = %d AND `oid` > 0 AND `type` IN (1,2) AND ( `oid` NOT IN ($skip_aids) ) ORDER BY `updated_at` DESC LIMIT 0,1", $order_from, $order_to, $contact_id );
			$results = $wpdb->get_results( $query, ARRAY_A );

			/** No conversations found */
			if ( ! is_array( $results ) || 0 === count( $results ) ) {
				return;
			}

			foreach ( $results as $conversation_data ) {
				$this->add_new( $order_id, $conversation_data['ID'], $contact_id, $conversation_data['oid'], $conversation_data['type'] );
			}
		}

		/**
		 * @param int $order_id
		 * @param int $conversation_id
		 * @param int $contact_id
		 * @param int $source_id
		 * @param int $source_type
		 *
		 * @return false|int
		 */
		public function add_new( $order_id, $conversation_id, $contact_id, $source_id, $source_type = 1 ) {
			if ( ! class_exists( 'WooCommerce' ) ) {
				return false;
			}

			if ( ! absint( $order_id ) > 0 || ! absint( $conversation_id ) > 0 || ! absint( $contact_id ) > 0 || ! absint( $source_id ) > 0 ) {
				return false;
			}

			/** checking if conversion enable for automation event */
			if ( 1 === absint( $source_type ) ) {
				$is_conversion_enable = self::is_automation_conversion_track( $source_id );

				if ( ! $is_conversion_enable ) {
					return false;
				}
			}

			$order = wc_get_order( absint( $order_id ) );
			if ( ! $order instanceof WC_Order || in_array( $order->get_status(), array( 'failed', 'pending', 'cancelled', 'refunded' ) ) ) {
				return false;
			}

			$order_base_total = $order->get_meta( '_bwfan_order_total_base' );
			$order_total      = ! empty( $order_base_total ) ? $order_base_total : $order->get_total();
			/** @todo order base total needs to calculate and add like we did in abandonment */
			$order_date = $order->get_date_paid();
			$order_date = ! $order_date instanceof WC_DateTime ? $order->get_date_created() : $order_date;
			if ( ! $order_date instanceof WC_DateTime ) {
				$order_date = current_time( 'mysql', 1 );
			} else {
				$order_date->setTimezone( new DateTimeZone( 'UTC' ) );
				$order_date = $order_date->format( 'Y-m-d H:i:s' );
			}
			$data = array(
				'wcid'    => absint( $order_id ),
				'cid'     => absint( $contact_id ),
				'trackid' => absint( $conversation_id ),
				'oid'     => absint( $source_id ),
				'otype'   => absint( $source_type ),
				'wctotal' => $order_total,
				'date'    => $order_date
			);

			BWFAN_Model_Conversions::insert( $data );

			return BWFAN_Model_Conversions::insert_id();
		}

		/** checking if settings is on in automations
		 *
		 * @param $automation_id
		 *
		 * @return bool
		 */
		public static function is_automation_conversion_track( $automation_id ) {
			$automation_meta       = BWFAN_Core()->automations->get_automation_data_meta( $automation_id );
			$automation_event_data = isset( $automation_meta['event_meta'] ) && ! empty( $automation_meta['event_meta'] ) ? $automation_meta['event_meta'] : array();

			/** if automation version 2 then create conversion */
			if ( isset( $automation_meta['v'] ) && 2 === absint( $automation_meta['v'] ) ) {
				return true;
			}

			/** when email_open_click not set don't create conversations */
			if ( ! isset( $automation_event_data['conversion_track'] ) || 1 !== absint( $automation_event_data['conversion_track'] ) ) {
				return false;
			}

			return true;
		}

		/**
		 * @param int $order_id
		 */
		public function remove_conversion( $order_id ) {
			if ( empty( $order_id ) ) {
				return;
			}
			$conversions = BWFAN_Model_Conversions::get_specific_rows( 'wcid', $order_id );
			if ( empty( $conversions ) ) {
				return;
			}

			foreach ( $conversions as $conversion ) {
				BWFAN_Model_Conversions::delete( $conversion['ID'] );
			}
		}

		public function modify_conversion_def_value_global( $settings ) {
			if ( ! isset( $settings['bwfan_order_tracking_conversion'] ) || empty( $settings['bwfan_order_tracking_conversion'] ) ) {
				$settings['bwfan_order_tracking_conversion'] = 15;
			}

			return $settings;
		}

		/**
		 * check coupon for conversions
		 *
		 * @param $contact_id
		 * @param $order_id
		 * @param $order
		 * @param $coupons
		 *
		 * @return bool
		 */
		public function check_coupon_for_conversion( $contact_id, $order_id, $order, $coupons ) {
			$order_email = $order->get_billing_email();
			$order_phone = $order->get_billing_phone();

			if ( ! is_array( $coupons ) || 0 === count( $coupons ) ) {
				return false;
			}

			foreach ( $coupons as $coupon ) {
				$coupon_id            = wc_get_coupon_id_by_code( $coupon );
				$coupon_automation_id = absint( get_post_meta( $coupon_id, '_bwfan_automation_id', true ) );
				/** checking if coupon created with automation */
				if ( $coupon_automation_id > 0 ) {
					/** @todo should check tracking id by automation id, if not then any tracking id */
					$track_id = $this->get_tracking_id( $order_email, $order_phone );
					$this->add_new( $order_id, $track_id, $contact_id, $coupon_automation_id, 1 );

					return true;
				}

				/** checking if coupon created using broadcast */
				$coupon_broadcast_id = absint( get_post_meta( $coupon_id, '_bwfan_broadcast_id', true ) );
				if ( $coupon_broadcast_id > 0 ) {
					$track_id = $this->get_tracking_id( $order_email, $order_phone );
					$this->add_new( $order_id, $track_id, $contact_id, $coupon_broadcast_id, 2 );

					return true;
				}
			}

			return false;
		}

		public function bwfan_event_global_tracking_enable() {
			?>
            <div class="bwfan-events-email-tracking bwfan-col-sm-12 bwfan-p-0 bwfan-mt-15">
                <#
                conversion_tracking = '';
                if(_.has(bwfan_automation_ui_data_detail.trigger.event_meta, 'conversion_track') ){
                conversion_tracking = 'checked' ;
                }
                #>
                <label class="bwfan-label-title">Conversion Tracking</label>
                <div class="bwfan_email_tracking bwfan-mb-15">
                    <label for="bwfan_email_open">
                        <input type="checkbox" name="event_meta[conversion_track]" id="bwfan_conversion_track" value="1" {{conversion_tracking}}/>
						<?php
						esc_html_e( 'Track Conversions', 'wp-marketing-automations-pro' );
						?>
                    </label>
                </div>
            </div>
			<?php
		}

		/**
		 * Get track id using email, phone and automation id
		 *
		 * @param $order_email
		 * @param $order_phone
		 *
		 * @return int|mixed
		 */
		public static function get_tracking_id( $order_email, $order_phone ) {
			global $wpdb;
			$track_query   = "select ID,oid,type from {$wpdb->prefix}bwfan_engagement_tracking where ((mode=1 && open>0) OR (mode=2 && click>0)) and hash_code !='' and send_to IN ('" . $order_email . "','" . $order_phone . "') order by created_at desc limit 0,1 ";
			$track_results = $wpdb->get_results( $track_query, ARRAY_A );
			$track_id      = ! empty( $track_results[0]['ID'] ) ? $track_results[0]['ID'] : 0;

			return $track_id;
		}

		/**
		 * Delete conversion on deletion of order
		 *
		 * @param $order_id
		 * @param $post
		 */
		public function remove_conversion_on_deletion( $order_id, $post ) {
			if ( empty( $order_id ) ) {
				return;
			}

			if ( 'shop_order' !== $post->post_type ) {
				return;
			}

			global $wpdb;

			$query = $wpdb->prepare( "DELETE FROM {table_name} WHERE `wcid` = %d", $order_id );
			BWFAN_Model_Conversions::query( $query );
		}
	}

	BWFAN_Core::register( 'conversions', 'BWFAN_Conversions' );
}