<?php

namespace AcademyProCourseBundle\Integration;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use Academy\Traits\Earning;

class Woocommerce {
	use Earning;

	public static function init() {
		$self = new self();
		/**
		 * After create new order
		 */
		add_action( 'woocommerce_new_order', array( $self, 'create_course_order_from_admin' ), 10, 3 );
		add_action( 'woocommerce_new_order_item', array( $self, 'create_course_order_from_customer' ), 10, 3 );

		/**
		 * Order Status Hook
		 *
		 * Remove course from active courses if an order is cancelled or refunded
		 */
		add_action( 'woocommerce_order_status_changed', array( $self, 'enrolled_courses_status_change' ), 10, 3 );

		// save meta value
		add_action( 'rest_after_insert_academy_courses', array( $self, 'update_product_meta' ), 10, 1 );

		// remove course product from shop page
		if ( \Academy\Helper::get_settings( 'hide_course_product_from_shop_page' ) ) {
			add_action( 'woocommerce_product_query', array( $self, 'remove_course_product_from_shop' ) );
		}

        // phpcs:ignore Squiz.PHP.CommentedOutCode.Found
		/**
		 * Add Earning Data
		 */
		if ( \Academy\Helper::get_addon_active_status( 'multi_instructor' ) ) {
			add_action( 'woocommerce_new_order_item', array( $self, 'save_earning_data' ), 10, 3 );
			add_action( 'woocommerce_order_status_changed', array( $self, 'save_earning_data_status_change' ), 10, 3 );
		}
	}

	public function create_course_order_from_admin( $order_id ) {
		if ( ! is_admin() ) {
			return;
		}

		$order = wc_get_order( $order_id );

		if ( ! $order ) {
			return;
		}

		$customer_id = $order->get_customer_id();
		if ( ! $customer_id ) {
			$customer_id = $this->create_user_by_order_details( $order );
		}
		foreach ( $order->get_items() as $item ) {
			$product_id = $item->get_product_id();
			$has_course_bundle = \AcademyProCourseBundle\Helper::product_belongs_with_course_bundle( $product_id );
			if ( $has_course_bundle ) {
				$bundle_course_id = $has_course_bundle->post_id;
				$course_attach_product_id = $has_course_bundle->meta_value;
				if ( $bundle_course_id && $course_attach_product_id ) {
					$bundle_course_items = get_post_meta( $bundle_course_id, 'academy_course_bundle_courses_ids', true );
					if ( is_array( $bundle_course_items ) && count( $bundle_course_items ) ) {
						foreach ( $bundle_course_items as $bundle_course_item ) {
							if ( isset( $bundle_course_item['value'] ) ) {
								\Academy\Helper::do_enroll( (int) $bundle_course_item['value'], $customer_id, $order_id );
							}
						}
					}
				}
			}
		}
	}

	public static function create_user_by_order_details( $order ) {
		// Create a new user
		$billing_address = $order->get_address( 'billing' );

		$password = wp_generate_password();
		$email = $billing_address['email'];
		$username = strstr( $email, '@', true ); // Generate a unique username

		$user_id = wp_create_user( $username, $password, $email );
		// Send the new user notification email
		wp_new_user_notification( $user_id, null, 'both' );
		// Log in the user
		$user = get_user_by( 'id', $user_id );
		if ( $user ) {
			wp_set_current_user( $user_id, $user->user_login );
			wp_set_auth_cookie( $user_id );
		}

		// Set the created user ID as the customer ID in the order object
		$order->set_customer_id( $user_id );
		$order->save();
		return $user_id;
	}

	public function create_course_order_from_customer( $item_id, $item, $order_id ) {
		if ( is_admin() ) {
			return;
		}

		$item = new \WC_Order_Item_Product( $item );
		$product_id = $item->get_product_id();
		$has_course_bundle = \AcademyProCourseBundle\Helper::product_belongs_with_course_bundle( $product_id );
		if ( $has_course_bundle ) {
			$order = wc_get_order( $order_id );
			if ( ! $order ) {
				return;
			}
			$customer_id = $order->get_customer_id();
			if ( ! $customer_id ) {
				$customer_id = $this->create_user_by_order_details( $order );
			}
			$bundle_course_id = $has_course_bundle->post_id;
			$course_attach_product_id = $has_course_bundle->meta_value;
			if ( $bundle_course_id && $course_attach_product_id ) {
				$bundle_course_items = get_post_meta( $bundle_course_id, 'academy_course_bundle_courses_ids', true );
				if ( is_array( $bundle_course_items ) && count( $bundle_course_items ) ) {
					foreach ( $bundle_course_items as $bundle_course_item ) {
						if ( isset( $bundle_course_item['value'] ) ) {
							\Academy\Helper::do_enroll( (int) $bundle_course_item['value'], $customer_id, $order_id );
						}
					}
				}
			}
		}//end if
	}

	public function enrolled_courses_status_change( $order_id, $status_from, $status_to ) {
		if ( ! \Academy\Helper::is_academy_order( $order_id ) ) {
			return;
		}
		global $wpdb;
		$course_enrolled_by_order = \Academy\Helper::get_course_enrolled_ids_by_order_id( $order_id );
		if ( $course_enrolled_by_order && is_array( $course_enrolled_by_order ) && count( $course_enrolled_by_order ) ) {
			foreach ( $course_enrolled_by_order as $enrolled_info ) {
				if ( ! is_admin() && self::is_order_will_be_automatically_completed( $order_id ) ) {
					$status_to = 'completed';
					self::order_mark_as_completed( $order_id );
				}
				// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
				$wpdb->update( $wpdb->posts, array( 'post_status' => $status_to ), array( 'ID' => $enrolled_info['enrolled_id'] ) );
				if ( 'completed' === $status_to ) {
					$enrolled_user_id = get_post_field( 'post_author', $enrolled_info['enrolled_id'] );
					do_action( 'academy/course/after_enroll', $enrolled_info['course_id'], $enrolled_info['enrolled_id'], $enrolled_user_id );
				}
			}
		}
	}

	public static function is_order_will_be_automatically_completed( $order_id ) {
		$enable_woo_order_auto_complete = (bool) \Academy\Helper::get_settings( 'woo_order_auto_complete' );

		if ( $enable_woo_order_auto_complete ) {
			return true;
		}
		return false;
	}

	public static function order_mark_as_completed( $order_id ) {
		$order_instance = wc_get_order( $order_id );
		if ( is_object( $order_instance ) ) {
			return $order_instance->update_status( 'completed' );
		}
		return false;
	}

	public function update_product_meta( $post ) {
		$product_id = (int) get_post_meta( $post->ID, 'academy_course_bundle_product_id', true );
		if ( $product_id ) {
			update_post_meta( $product_id, '_virtual', 'yes' );
			update_post_meta( $product_id, '_academy_product', 'yes' );
		}
	}

	public function remove_course_product_from_shop( $wp_query ) {
		$wp_query->set(
			'meta_query',
			array(
				array(
					'key' => '_academy_product',
					'compare' => 'NOT EXISTS',
				),
			)
		);
		return $wp_query;
	}

	public function save_earning_data( $item_id, $item, $order_id ) {
		$is_enabled_earning = (bool) \Academy\Helper::get_settings( 'is_enabled_earning' );
		if ( ! \Academy\Helper::get_addon_active_status( 'multi_instructor' ) || ! $is_enabled_earning ) {
			return;
		}

		$item = new \WC_Order_Item_Product( $item );
		$product_id = $item->get_product_id();
		$course_bundle = \AcademyProCourseBundle\Helper::product_belongs_with_bundle( $product_id );

		if ( $course_bundle ) {
			$course_bundle_id = $course_bundle->post_id;
			$user_id = \Academy\Helper::get_user_id_from_course_id( $course_bundle_id );
			$order_status = \Academy\Helper::get_order_status_by_id( $order_id );
			$bundle_course_items = get_post_meta( $course_bundle_id, 'academy_course_bundle_courses_ids', true );

			/**
			 * 1. get bundle product id
			 * 2. get bundle products within the array
			 * 3. get discount {amount summation of all products-bundle product}
			 * 4. calculate weight on the bundle
			 * 5. calculate discount for each product
			 * 6. get discounted product price
			 * 7. finally calculate earning by, (course price-fee) * commission from the settings
			 */

			// calculate discount
			$bundle_product_id = (int) get_post_meta( $course_bundle_id, 'academy_course_bundle_product_id', true );
			$bundle_product = wc_get_product( $bundle_product_id );
			$bundle_regular_price = $bundle_product->get_regular_price();
			$bundle_sale_price = $bundle_product->get_sale_price();
			$discount = $bundle_regular_price - $bundle_sale_price;
			$discount = max( $discount, 0 );
			$monetize_engine = \Academy\Helper::monetization_engine();
			if ( is_array( $bundle_course_items ) && count( $bundle_course_items ) ) {
				foreach ( $bundle_course_items as $bundle_course_item ) {
					$course_id = (int) $bundle_course_item['value'];
					$course_product_id = (int) get_post_meta( $course_id, 'academy_course_product_id', true );
					if ( ! $course_product_id ) {
						continue;
					}

					$instructor_id = \Academy\Helper::get_user_id_from_course_id( $course_id );
					$course_regular_price = wc_get_product( $course_product_id )->get_regular_price();
					// calculate discount for each product using weight
					$course_discount = ( $course_regular_price / $bundle_regular_price ) * $discount;
					$regular_price = $course_regular_price - $course_discount;

					if ( self::is_exists_user_earning_by_order( $course_bundle_id, $order_id, $user_id ) ) {
						return;
					}

					$total_price = $regular_price;
					$fees_deduct_data = array();
					$is_enabled_fee_deduction = (bool) \Academy\Helper::get_settings( 'is_enabled_fee_deduction' );
					$course_price_grand_total = $total_price;
					if ( $is_enabled_fee_deduction ) {
						$fees_name = \Academy\Helper::get_settings( 'fee_deduction_name' );
						$fees_amount = \Academy\Helper::get_settings( 'fee_deduction_amount' );
						$fees_type = \Academy\Helper::get_settings( 'fee_deduction_type' );

						if ( $fees_amount > 0 ) {
							if ( 'percent' === $fees_type ) {
								$fees_amount = ( $total_price * $fees_amount ) / 100;
							}
							$course_price_grand_total = $total_price - $fees_amount;
						}

						$fees_deduct_data = array(
							'deduct_fees_amount' => $fees_amount,
							'deduct_fees_name' => $fees_name,
							'deduct_fees_type' => $fees_type,
						);
					}

					$instructor_rate = \Academy\Helper::get_settings( 'instructor_commission_percentage' );
					$admin_rate = \Academy\Helper::get_settings( 'admin_commission_percentage' );

					$instructor_amount = 0;
					if ( $instructor_rate > 0 ) {
						$instructor_amount = ( $course_price_grand_total * $instructor_rate ) / 100;
					}

					$admin_amount = 0;
					if ( $admin_rate > 0 ) {
						$admin_amount = ( $course_price_grand_total * $admin_rate ) / 100;
					}

					$commission_type = 'percent';

					$earning_data = array(
						'user_id' => $instructor_id,
						'course_id' => $course_id,
						'order_id' => $order_id,
						'order_status' => $order_status,
						'course_price_total' => $total_price,
						'course_price_grand_total' => $course_price_grand_total,
						'instructor_amount' => $instructor_amount,
						'instructor_rate' => $instructor_rate,
						'admin_amount' => $admin_amount,
						'admin_rate' => $admin_rate,
						'commission_type' => $commission_type,
						'process_by'    => $monetize_engine,
					);
					$data = apply_filters( 'academy/instructor/insert_earning_args', array_merge( $earning_data, $fees_deduct_data ) );
					self::insert_earning( $data );
				}//end foreach
			}//end if
		}//end if
	}

	public function save_earning_data_status_change( $order_id, $status_from, $status_to ) {
		if ( ! get_post_meta( $order_id, 'is_academy_order_for_course', true ) ) {
			return;
		}

		if ( ! is_admin() && self::is_order_will_be_automatically_completed( $order_id ) ) {
			$status_to = 'completed';
			self::order_mark_as_completed( $order_id );
		}

		if ( count( self::get_earning_by_order_id( $order_id ) ) ) {
			self::update_earning_status_by_order_id( $order_id, $status_to );
		}
	}
}
