<?php


namespace Elex\MultiVendor\Model;

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

use Elex\MultiVendor\Model\SiteSettings;
use Elex\MultiVendor\Model\Store;

class AdminPayment {

	public static function get_commission( $vendor_amount ) {
		$site_settings = SiteSettings::load();
		$commission    = 0;
		
		if ( ! empty( $vendor_amount ) ) {
			
			if ( 'percent' === $site_settings->get( 'commission_type_of_sale' ) ) {
				$commission = (float) $vendor_amount * ( (float) $site_settings->get( 'commission_for_each_sale' ) / 100 );
			} else {
				$commission = $site_settings->get( 'commission_for_each_sale' );
			}
		}
	
		/**
		* Fire an filter hook to get commision amount
		*
		* @since 2.0.0
		* @param $commission
		*/
		return apply_filters( 'elex_mv_admin_commission', $commission );
	}

	public static function vendor_settlement_history( $history_data ) {
		/**
		* Function apply filterto filter history data
		*
		* @since 2.0.0
		* @param $history_data
		*/
		$query = self::apply_filters( $history_data );
		$query->offset( isset( $history_data['start'] ) ? $history_data['start'] : 0 );
		$query->limit( isset( $history_data['length'] ) ? $history_data['length'] : 10 );
		$data = $query->get();
		/**
		* Fire an filter hook to get vendor settlement history
		*
		* @since 2.0.0
		* @param $data
		*/
		return apply_filters( 'elex_mv_vendors_settlement_history', $data );
	}
	/**
	 * Function to filters the history settlement data 
	 * 
	 * @since 1.0.0
	 * @param $history_data
	 */
	public static function apply_filters( $history_data = array() ) {
		$query = wpFluent()->table( 'elex_mv_payment_settlement_history' );

		if ( isset( $history_data['vendor_id'] ) && is_array( $history_data['vendor_id'] ) && in_array( 'all', $history_data['vendor_id'] ) ) {
			$query = $query;
		} elseif ( isset( $history_data['vendor_id'] ) && ! empty( $history_data['vendor_id'] ) ) {
		$query->whereIn( 'vendor_id', is_array( $history_data['vendor_id'] ) ? ( ! in_array( 'all', $history_data['vendor_id'] ) ? $history_data['vendor_id'] : '' ) : array( $history_data['vendor_id'] ) );  
		}
		if ( isset( $history_data['export_from_date'] ) && isset( $history_data['export_to_date'] ) ) {
			$query->whereBetween( 'settlement_date', $history_data['export_from_date'] , $history_data['export_to_date'] );
		}
		if ( isset( $history_data['settlement_mode'] ) && 'all' !== $history_data['settlement_mode'] ) {
			$query->where( 'settlement_mode', $history_data['settlement_mode'] );
		}
		if ( isset( $history_data['search_value'] ) && ! empty( $history_data['search_value'] ) ) {
			$query->where(
				function ( $query ) use ( $history_data ) {
				$query->where( 'settlement_mode', 'like', '%' . $history_data['search_value'] . '%' );
				$query->orwhere( 'transaction_id', 'like', '%' . $history_data['search_value'] . '%' );
				$query->orwhere( 'settlement_date', 'like', '%' . $history_data['search_value'] . '%' );
				}
			);
		}
		$query->orderBy( 'created_at', 'DESC' );
		return $query;
	}

	public static function get_commission_type() {
		$site_settings   = SiteSettings::load();
		$commission_type = $site_settings->get( 'commission_type_of_sale' ); 
		return $commission_type;
	}

	public static function get_commission_amount() {
		$site_settings     = SiteSettings::load();
		$commission_amount = $site_settings->get( 'commission_for_each_sale' );
		return $commission_amount;
	}

	public static function get_settlement_date( $store_id ) {
		$last_settlement_date = strtotime( get_post_meta( $store_id, 'elex_mv_last_settlement_date', true ) );
		$site_settings        = SiteSettings::load();
		$next_settlement_date = $site_settings->get( 'elex_mv_date_of_month_pay_settle' );
		$currentDate          = new \DateTime( '@' . $last_settlement_date );
		// Calculate the next month's date with the same day as user input
		$nextMonthDate = $currentDate->modify( 'first day of next month' )->setDate( $currentDate->format( 'Y' ), $currentDate->format( 'm' ), $next_settlement_date );
		// Display the result
		$settlement_date = $nextMonthDate->format( 'Y-m-d' );
		return $settlement_date; 
	}

	public static function get_settlement_status( $vendor_id ) {
		$site_settings        = SiteSettings::load();
		$next_settlement_date = $site_settings->get( 'elex_mv_date_of_month_pay_settle' );
		$currentDate          = new \DateTime( 'today' );
		// Calculate the next month's date with the same day as user input
		$nextMonthDate = $currentDate->modify( 'first day of next month' )->setDate( $currentDate->format( 'Y' ), $currentDate->format( 'm' ), $next_settlement_date );
		// Display the result
		$settlement_date   = $nextMonthDate->format( 'Y-m-d' );
		$settlement_status = 'Unsettled';
			$your_date     = new \DateTime( 'today' );
			$your_date     = strtotime( $your_date->format( 'Y-m-d' ) );
		if ( $your_date > $settlement_date ) {
			$settlement_status = 'Overdue';
		} else {
			$settlement_status = 'Unsettled';
		}
		
		return $settlement_status;  
	}

	public static function vendor_payments( $filters ) {
		
		$filters['search_columns'] = array(
			'user_login',
			'display_name',
			'user_email',
		);
		$vendors                   = Store::get_stores( $filters );
		/**
		* Fire an filter hook to get vendor payment data
		*
		* @since 2.0.0
		* @param $vendors
		*/
		return apply_filters( 'elex_mv_vendors_payment', $vendors );
	}

	public function payment_total_count( $filters ) {
		$query = wpFluent()->table( 'posts' );
		$query->where( 'posts.post_status' , 'publish' );
		$query->where( 'posts.post_type' , 'elex_vendor' );
		if ( isset( $filters['s'] ) && ! empty( $filters['s'] ) ) {
			$query->where( 'post_title', 'like', '%' . $filters['s'] . '%' );
		}
	
		$query->orderBy( 'posts.ID', 'DESC' );
		return $query->count();
	}

	public static function get_vendor_earning( $user_id ) {
		global $wpdb;
		$site_settings = SiteSettings::load();
		$order_status  = $site_settings->get( 'elex_mv_order_status_radios' );
		$buffer_time   = $site_settings->get( 'buffer_time' );
		$start_date    = get_option( 'elex_mv_installation_date' );
		$currentDate   = new \DateTime( 'today' );
		// Subtract the specified number of days from the current date
		$previousDate              = $currentDate->modify( '-' . $buffer_time . ' days' );
		$end_date                  = $previousDate->format( 'Y-m-d' );
		$order_status_placeholders = implode( ',', array_fill( 0, count( $order_status ), '%s' ) );
		// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		$sql = "SELECT SUM(oid.meta_value) as total_vendor_earning FROM {$wpdb->prefix}wc_orders as oi JOIN {$wpdb->prefix}wc_orders_meta as oim ON oim.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid ON oid.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid_status ON oid_status.order_id = oi.id WHERE oid.meta_key = 'elex_mv_vendor_earning' AND oi.status IN ($order_status_placeholders) AND DATE(oi.date_created_gmt) BETWEEN %s AND %s AND oim.meta_key = 'elex_mv_store_id' AND oim.meta_value = %d AND oid_status.meta_key = 'elex_mv_settlement_status' AND oid_status.meta_value = 'false'";
		// Execute the query and fetch the result
		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$results        = $wpdb->get_results( $wpdb->prepare( $sql, array_merge( $order_status, array( $start_date, $end_date, $user_id ) ) ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
		$vendor_earning = ! empty( $results[0]->total_vendor_earning ) ? $results[0]->total_vendor_earning : 0;

		// partial refund total
		$sql_refund = "SELECT SUM(oid.meta_value) as total_partial_refund FROM {$wpdb->prefix}wc_orders as oi JOIN {$wpdb->prefix}wc_orders_meta as oim ON oim.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid ON oid.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid_status ON oid_status.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid_settle ON oid_settle.order_id = oi.id WHERE oid.meta_key = 'elex_mv_item_partial_refund_amount' AND DATE(oi.date_created_gmt) BETWEEN %s AND %s AND oim.meta_key = 'elex_mv_store_id' AND oim.meta_value = %d AND oid_status.meta_key = 'elex_mv_item_partial_refund' AND oid_status.meta_value = 'true' AND oid_settle.meta_key = 'elex_mv_refund_settlement_status' AND oid_settle.meta_value = 'false'";
		// Execute the query and fetch the result
		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$results        = $wpdb->get_results( $wpdb->prepare( $sql_refund, $start_date, $end_date, $user_id ) );
		$partial_refund = ! empty( $results[0]->total_partial_refund ) ? $results[0]->total_partial_refund : 0;
		$vendor_earning = $vendor_earning - $partial_refund;
		// full refund total
		// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		$sql_full_refund = "SELECT SUM(oid.meta_value) as total_full_refund FROM {$wpdb->prefix}wc_orders as oi JOIN {$wpdb->prefix}wc_orders_meta as oim ON oim.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid ON oid.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid_status ON oid_status.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid_settle ON oid_settle.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid_order_status ON oid_order_status.order_id = oi.id WHERE oid.meta_key = 'elex_mv_item_full_refund_amount' AND oid_order_status.meta_key = 'elex_mv_order_old_status' AND oid_order_status.meta_value IN ($order_status_placeholders) AND DATE(oi.date_created_gmt) BETWEEN %s AND %s AND oim.meta_key = 'elex_mv_store_id' AND oim.meta_value = %d AND oid_status.meta_key = 'elex_mv_item_full_refund' AND oid_status.meta_value = 'true' AND oid_settle.meta_key = 'elex_mv_refund_settlement_status' AND oid_settle.meta_value = 'false'";
		// Execute the query and fetch the result
		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$results        = $wpdb->get_results( $wpdb->prepare( $sql_full_refund, array_merge( $order_status, array( $start_date, $end_date, $user_id ) ) ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
		$full_refund    = ! empty( $results[0]->total_full_refund ) ? $results[0]->total_full_refund : 0;
		$vendor_earning = $vendor_earning - $full_refund;
		

		/**
		* Fire an filter hook to get vendor earning
		*
		* @since 2.0.0
		* @param $vendor_earning
		*/
		$vendor_earning = apply_filters( 'elex_mv_vendors_earning', $vendor_earning );
		return $vendor_earning ;
	}

	
	public static function get_admin_earning( $user_id ) {
		global $wpdb;
		$site_settings = SiteSettings::load();
		$order_status  = $site_settings->get( 'elex_mv_order_status_radios' );
		$buffer_time   = $site_settings->get( 'buffer_time' );
		$start_date    = get_option( 'elex_mv_installation_date' );
		$currentDate   = new \DateTime( 'today' );
		// Subtract the specified number of days from the current date
		$previousDate              = $currentDate->modify( '-' . $buffer_time . ' days' );
		$end_date                  = $previousDate->format( 'Y-m-d' );
		$order_status_placeholders = implode( ',', array_fill( 0, count( $order_status ), '%s' ) );
		// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		$sql_admin_earning = "SELECT SUM(oid.meta_value) as total_admin_earning FROM {$wpdb->prefix}wc_orders as oi JOIN {$wpdb->prefix}wc_orders_meta as oim ON oim.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid ON oid.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid_status ON oid_status.order_id = oi.id WHERE oid.meta_key = 'elex_mv_admin_earning' AND oi.status IN ($order_status_placeholders) AND DATE(oi.date_created_gmt) BETWEEN %s AND %s AND oim.meta_key = 'elex_mv_store_id' AND oim.meta_value = %d AND oid_status.meta_key = 'elex_mv_settlement_status' AND oid_status.meta_value = 'false'";
		// Execute the query and fetch the result
		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$results       = $wpdb->get_results( $wpdb->prepare( $sql_admin_earning, array_merge( $order_status, array( $start_date, $end_date, $user_id ) ) ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
		$admin_earning = ! empty( $results[0]->total_admin_earning ) ? $results[0]->total_admin_earning : 0;
			/**
		 * Fire an filter hook to get vendor earning
		 *
		 * @since 2.0.0
		 * @param $vendor_earning
		 */
		$admin_earning = apply_filters( 'elex_mv_vendors_earning', $admin_earning );
		return $admin_earning ;
	}

	public static function update_vendor_amount_after_settlement( $settlement_data ) {
		global $wpdb;
		if ( ! empty( $settlement_data['vendor_id'] ) && ! empty( $settlement_data['settlement_amount'] ) ) {
			$site_settings = SiteSettings::load();
			$order_status  = $site_settings->get( 'elex_mv_order_status_radios' );
			$buffer_time   = $site_settings->get( 'buffer_time' );
			$start_date    = get_option( 'elex_mv_installation_date' );
			$currentDate   = new \DateTime( 'today' );
			// Subtract the specified number of days from the current date
			$previousDate              = $currentDate->modify( '-' . $buffer_time . ' days' );
			$end_date                  = $previousDate->format( 'Y-m-d' );
			$user_id                   = $settlement_data['vendor_id'];
			$order_status_placeholders = implode( ',', array_fill( 0, count( $order_status ), '%s' ) );
			// vendor amount settlement status set to true on settlement
			$vendor_earning = self::get_vendor_earning( $settlement_data['vendor_id'] );
			// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
			$sql_settlement = "SELECT oi.id FROM {$wpdb->prefix}wc_orders as oi JOIN {$wpdb->prefix}wc_orders_meta as oim ON oim.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid ON oid.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid_status ON oid_status.order_id = oi.id WHERE oid.meta_key = 'elex_mv_vendor_earning' AND oi.status IN ($order_status_placeholders) AND DATE(oi.date_created_gmt) BETWEEN %s AND %s AND oim.meta_key = 'elex_mv_store_id' AND oim.meta_value = %d AND oid_status.meta_key = 'elex_mv_settlement_status' AND oid_status.meta_value = 'false'";
			// Execute the query and get order ids
			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			$order_ids = $wpdb->get_col( $wpdb->prepare( $sql_settlement, array_merge( $order_status, array( $start_date, $end_date, $user_id ) ) ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
			// Update order_ids settled status
			if ( ! empty( $order_ids ) ) {
				$id_placeholders = implode( ',', array_fill( 0, count( $order_ids ), '%d' ) );
				// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				$sql_update = "UPDATE {$wpdb->prefix}wc_orders_meta SET meta_value = 'true' WHERE order_id IN ($id_placeholders) AND meta_key = 'elex_mv_settlement_status'";
				// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
				$wpdb->query( $wpdb->prepare( $sql_update, ...$order_ids ) );
			}

			// partial refund settlement status set to true on settlement
			$sql = "SELECT oi.id FROM {$wpdb->prefix}wc_orders as oi JOIN {$wpdb->prefix}wc_orders_meta as oim ON oim.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid ON oid.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid_status ON oid_status.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid_settle ON oid_settle.order_id = oi.id WHERE oid.meta_key = 'elex_mv_item_partial_refund_amount' AND DATE(oi.date_created_gmt) BETWEEN %s AND %s AND oim.meta_key = 'elex_mv_store_id' AND oim.meta_value = %d AND oid_status.meta_key = 'elex_mv_item_partial_refund' AND oid_status.meta_value = 'true' AND oid_settle.meta_key = 'elex_mv_refund_settlement_status' AND oid_settle.meta_value = 'false'";
			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			$order_ids = $wpdb->get_col( $wpdb->prepare( $sql, $start_date, $end_date, $user_id ) );
			if ( ! empty( $order_ids ) ) {
				$id_placeholders = implode( ',', array_fill( 0, count( $order_ids ), '%d' ) );
				// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				$sql_update = "UPDATE {$wpdb->prefix}wc_orders_meta SET meta_value = 'true' WHERE order_id IN ($id_placeholders) AND meta_key = 'elex_mv_refund_settlement_status'";
				// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
				$wpdb->query( $wpdb->prepare( $sql_update, ...$order_ids ) );
			}

			// Full refund settlement status set to true
			$sql = "SELECT oi.id FROM {$wpdb->prefix}wc_orders as oi JOIN {$wpdb->prefix}wc_orders_meta as oim ON oim.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid ON oid.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid_status ON oid_status.order_id = oi.id JOIN {$wpdb->prefix}wc_orders_meta as oid_settle ON oid_settle.order_id = oi.id WHERE oid.meta_key = 'elex_mv_item_full_refund_amount' AND DATE(oi.date_created_gmt) BETWEEN %s AND %s AND oim.meta_key = 'elex_mv_store_id' AND oim.meta_value = %d AND oid_status.meta_key = 'elex_mv_item_full_refund' AND oid_status.meta_value = 'true' AND oid_settle.meta_key = 'elex_mv_refund_settlement_status' AND oid_settle.meta_value = 'false'";
			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			$order_ids = $wpdb->get_col( $wpdb->prepare( $sql, $start_date, $end_date, $user_id ) );
			if ( ! empty( $order_ids ) ) {
				$id_placeholders = implode( ',', array_fill( 0, count( $order_ids ), '%d' ) );
				// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
				$sql_update = "UPDATE {$wpdb->prefix}wc_orders_meta SET meta_value = 'true' WHERE order_id IN ($id_placeholders) AND meta_key = 'elex_mv_refund_settlement_status'";
				// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
				$wpdb->query( $wpdb->prepare( $sql_update, ...$order_ids ) );
			}
			
			$remaining_amount = (float) $vendor_earning - (float) sanitize_text_field( $settlement_data['settlement_amount'] );

			update_post_meta( $settlement_data['vendor_id'], 'elex_mv_vendor_earning', $remaining_amount );

			update_post_meta( $settlement_data['vendor_id'], 'elex_mv_vendor_total_sales', 0 );

			update_post_meta( $settlement_data['vendor_id'], 'elex_mv_vendor_total_earning', 0 );

			update_post_meta( $settlement_data['vendor_id'], 'elex_mv_vendor_last_settlement_refund', 0 );

			update_post_meta( $settlement_data['vendor_id'], 'elex_mv_admin_earning', 0 );
		}
	}

	public static function update_last_settlement_date( $settlement_data ) {

		if ( ! empty( $settlement_data['vendor_id'] ) && ! empty( $settlement_data['settlement_date'] ) ) {
			update_post_meta( $settlement_data['vendor_id'], 'elex_mv_last_settlement_date', $settlement_data['settlement_date'] );
		}
	}

	public static function insert_settlement_history_data( $settlement_data, $table_name ) {   
		global $wpdb;
		$site_settings = SiteSettings::load();
			$wpdb->insert(
				$table_name,
				array(
					'vendor_id'         => $settlement_data['vendor_id'],
					'vendor_amount'     => $settlement_data['settlement_amount'],
					'commission_type'   => $site_settings->get( 'commission_type_of_sale' ),
					'commission_amount' => $settlement_data['commission_amount'],
					'settlement_date'   => $settlement_data['settlement_date'],
					'settlement_mode'   => $settlement_data['settlement_mode'],
					'transaction_id'    => ! empty( $settlement_data['transaction_id'] ) ? $settlement_data['transaction_id'] : '-',
					'note'              => ! empty( $settlement_data['note'] ) ? $settlement_data['note'] : '-',
					'created_at'        => current_time( 'Y-m-d H:i:s' ),
				)
			);
	}
}
