<?php 

// session_start();

require_once("../../../config.php");
require_once("../../../app/functions.php");
require_once("../../../app/table-functions.php");
// require_once("../../../app/includes/phpmailer/class.phpmailer.php");
spl_autoload_register(function($class_name) {
	$file = "../../../app/classes/class-".$class_name.".php";
	if (file_exists($file)) {
		include $file;
	}
});

require_once("../plugins.php");
$plugins = new plugins();
$plugins->load();

$session = Session::getInstance();

if ($_SERVER["REQUEST_METHOD"] == "POST") :

	if(isset($_POST['action'])){
		$response = array();
		$args = $_POST;
		unset($args['action']);
		$user = new user;
		$post = new post;
		$support = new support(['software_engineer', 'super_admin']);

		switch ($_POST['action']) {
			case 'bank_deposit':
				$files = get_library_files("pop-".$args['in_ref'], $args['user_id']);
				$response['files'] = $files;
				if(!$files['count']) {
					$response['msg'] = 'You did not attach any file. Please add some attachments before you submit.';
					$response['error'] = 1;					
				} else {
					$args['type'] = 'credit';
					$args['status'] = 'submitted';
					$args['mode'] = pm_get_account_id($args['bank_used']);
					$args = apply_filters("pm_post_credit_args", $args);
					do_action("pm_post_credit_validation", $args);
					if($existing = db_post_unique(["type" => "credit", "in_ref" => $args['in_ref'], "user_id" => $args['user_id'], "mode" => $args['mode'], 'status' => ["confirmed", "submitted"]])) {
						$response['error'] = 1;
						$response['msg'] = 'You have already submitted this payment before.';
					} else {
						$id = $post->add_post($args);
						if($id) {
							$invoice = new pm_invoice($args['user_id']);
							$invoice->set_invoice_by_number($args['in_ref']);
							pm_bank_deposit($args['amount'], $invoice->description(), $args['bank_used'], $id . " : " . $args['in_ref'], 'pending');
							$response['error'] = 0;
							$response['msg'] = 'You have successfully submitted your payment of '.toMoney($args['amount']).' for review and confirmation.';
							$info = get_fullname($args['user_id'])." submitted ".get_gender_pronouns($args['user_id'])[1]." payment of ".toMoney($args['amount']).". Tellers/Payment evidences attached are to be manually verified and confirmed because the individual paid through the bank. <br>Thank you.";
							$support = new support;
							$support->attachments = $files;
							$support->action = get_option('home_url')."confirm-payments";
							$support->inform_admins($info, "BANK DEPOSIT #".$args['in_ref'], "super_admin", "admin_tech", "super_admin_tech", "software_engineer");
						}
					}
					
				}
				echo json_encode($response);
				exit();
				break;

			case 'add_payment':
				$args['type'] = 'credit';
				$args['status'] = 'confirmed';
				$args['confirmed_by'] = get_fullname($session->id);
				$args['confirmed_on'] = time();
				$invoice = new pm_invoice;
				$invoice->get_invoice_by_number($args['in_ref']);
				$type = "normal";
				switch ($args['mode']) {
					case 'Cash Payment':
					case 'Others':
						// do nothing
						break;
					
					default:
						// get bank
						$post = new post;
						$meta = $post->get_post_meta($args['mode']);
						$narration = $invoice->description();
						if($meta) {
							$type = "to_bank";
							$args['mode'] = pm_get_account_id($meta);
						}
						break;
				}
				$response = pm_process_add_payment($args, $invoice);
				if($type === 'to_bank' && isset($response['credit_id'])) {
					$ref = $response['credit_id']." : ".$args['in_ref'];
					pm_bank_deposit($args['amount'], $narration, $meta['id'], $ref, 'approved');
				}
				echo json_encode($response);
				exit();
				break;

			case "credit_user_get_user":
				$response = $user->get_user_meta($args['selector']);
				echo json_encode($response);
				exit();
				break;

			case "credit_user":
				if($args['user_id'] == $session->id) {
					$response['error'] = 1;
					$response['msg'] = "Sorry, you cannot credit your own account. Let another admin perform this action.";
					echo json_encode($response);
					exit();
				}
				$ref = pm_generate_random_reference();

				if(current_user_can("approve_direct_credit")) {
					$status = "approved";
				} else $status = "pending";

				$exp = pm_register_direct_credit($args['amount'], $args['narration'], $args['user_id'], $ref, $status);
				if($exp) {
					if(current_user_can("confirm_payments")) {
						$status = "confirmed";
					} else $status = "pending";
					$credit = pm_credit_wallet($args['user_id'], $args['amount'], $args['narration'], $ref, $status);
					if($credit) {
						$response['error'] = 0;
						$response['msg'] = "User has been credited successfully.";
						if($status == 'pending') {
							$response['msg'] .= " Note that this credit has not been approved and will not give value until it has been authorized.";
							$info = "A new credit posted by an admin requires your authorization. Please login to the portal to oblige";
							$support->inform_admins($info);
						}
					} else {
						$response['error'] = 1;
						$response['msg'] = "Something went wrong and user could not be credited. Please check if this payment reference has been recorded before.";
					}
				} else {
					$response['error'] = 1;
					$response['msg'] = "Something went wrong.";
				}
				echo json_encode($response);
				exit();
				break;

			case "debit_user":
				if($args['user_id'] == $session->id) {
					$response['error'] = 1;
					$response['msg'] = "Sorry, you cannot debit your own account. Let another admin perform this action.";
					echo json_encode($response);
					exit();
				}
				$ref = pm_generate_random_reference();

				if(current_user_can("approve_direct_debit")) {
					$status = "approved";
				} else $status = "pending";

				$exp = pm_register_direct_debit($args['amount'], $args['narration'], $args['user_id'], $ref, $status);
				if($exp) {
					if(current_user_can("confirm_payments")) {
						$status = "confirmed";
					} else $status = "pending";
					$debit = pm_debit_wallet($args['user_id'], $args['amount'], $args['narration'], $ref, $status);
					if($debit) {
						$response['error'] = 0;
						$response['msg'] = "User has been debited successfully.";
						if($status == 'pending') {
							$response['msg'] .= " Note that this debit has not been approved and will not be effected until it has been authorized.";
							$info = "A new debit posted by an admin requires your authorization. Please login to the portal to oblige";
							$support->inform_admins($info);
						}
					} else {
						$response['error'] = 1;
						$response['msg'] = "Something went wrong and user could not be debited. Please check if this payment reference has been recorded before.";
					}
				} else {
					$response['error'] = 1;
					$response['msg'] = "Something went wrong.";
				}
				echo json_encode($response);
				exit();
				break;

			case 'get_wallet_balance':
				$response = toMoney(pm_get_user_wallet_bal($session->id));
				echo json_encode($response);
				exit();
				break;

			case 'request_payout':
				
				
				if($args['amount'] == 0) {
					$response['error'] = 1;
					$response['msg'] = "You cannot request for ".toMoney(0);
					echo json_encode($response);
					exit();
				}
				if($args['amount'] < ($option = get_option("min_payout_request"))) {
					$response['error'] = 1;
					$response['msg'] = "You cannot request an amount less than ".toMoney($option);
					echo json_encode($response);
					exit();
				}
				$option = get_option("max_payout_request");
				if($args['amount'] > $option && $option != 0) {
					$response['error'] = 1;
					$response['msg'] = "You cannot request an amount greater than ".toMoney($option);
					echo json_encode($response);
					exit();
				}
				$wallet_bal = pm_get_user_wallet_bal($session->id);
				if($wallet_bal < ($args['amount'] + get_option("min_wallet_balance"))) {
					$response['error'] = 1;
					$response['msg'] = "Sorry, Your payout request was not successful due to insufficient funds.";
					echo json_encode($response);
					exit();
				}
				$ref = pm_generate_random_reference();
				$narration = "Payout request on ".date(_DATE_FORMAT_, time());
				$deb = pm_debit_wallet($session->id, $args['amount'], $narration, $ref);
				if($deb) {
					$res = pm_request_payout($session->id, $args['amount'], $ref, $args['account']);
					if($res) {
						$response['error'] = 0;
						$response['msg'] = "Your payout request was successfully submitted and awaiting approval.";
					} else {
						$response['error'] = 1;
						$response['msg'] = "Your payout request was not successful. Please try again later.";
					}
				} else {
					$response['error'] = 1;
					$response['msg'] = "Your payout request was not successful, we are unable to debit your ewallet. Please try again later.";
				}
				
				echo json_encode($response);
				exit();
				break;

			case "post_new_expense":
				if($args['amount'] <= 0) {
					$response['error'] = 1;
					$response['msg'] = "Sorry, the value for amount cannot be zero.";
					echo json_encode($response);
					exit();
				}
				$ref = pm_generate_random_reference();
				if(current_user_can("approve_expense")) {
					$status = 'approved';
				} else $status = 'pending';
				switch ($args['source_of_fund']) {
					case 'Cash From Ledger':
						// do nothing
						break;
					
					default:
						// get bank
						$meta = $post->get_post_meta($args['source_of_fund']);
						if($meta) {
							$args['source_of_fund'] = pm_get_account_id($meta);
							pm_bank_withdrawal($args['amount'], $args['narration'], $meta['id'], $ref, $status);
						}
						break;
				}
				$res = pm_post_expense($args['amount'], $args['narration'], $args['beneficiary'], $ref, $status);
				if($res) {
					$response['error'] = 0;
					$response['msg'] = "Done.";
				} else {
					$response['error'] = 1;
					$response['msg'] = "Sorry, You are unable to post this expense now. Please try again later.";
				}
				echo json_encode($response);
				exit();
				break;

			case "create_invoice":
				if(!isset($args['items'])) {
					$response['error'] = 1;
					$response['msg'] = "You must add at least one item to the invoice.";
					echo json_encode($response);
					exit();
				}
				if(function_exists("get_bulk_receivers")) {
					$receivers = get_bulk_receivers($args['receivers']);
				} else {
					$response['error'] = 1;
					$response['msg'] = "This module depends on messaging module. Please contact the developer.";
					echo json_encode($response);
					exit();
				}
				if(_count($receivers) < 1) {
					$response['error'] = 1;
					$response['msg'] = "The receivers group(s) you selected are/is empty.";
					echo json_encode($response);
					exit();
				}
				$due_date = strtotime($args['due_date']);
				$items = array();
				foreach ($args['items']['description'] as $key => $value) {
					$items[$key]['narration'] = $args['items']['description'][$key];
					$items[$key]['amount'] = $args['items']['unit_price'][$key];
					$items[$key]['quantity'] = $args['items']['qty'][$key];
					$items[$key]['feeid'] = -1;
					$items[$key]['ref'] = false;
				}
				foreach ($receivers as $receiver_meta) {
					set_time_limit(200);
					pm_new_invoice($receiver_meta['id'], $items, $due_date);
				}
				$response['error'] = 0;
				$response['msg'] = "You have successfully created the invoice.";
				echo json_encode($response);
				exit();
				break;

			case "edit_invoice":
				if(!isset($args['items'])) {
					$response['error'] = 1;
					$response['msg'] = "You must add at least one item to the invoice.";
					echo json_encode($response);
					exit();
				}
				$invoice = new pm_invoice();
				$invoice->get_invoice_by_id($args['id']);
				$invoice->due_date = strtotime($args['due_date']);
				$old_items = $invoice->items;
				$invoice->items = array();
				foreach ($args['items']['description'] as $key => $value) {
					$ref = ($args['items']['ref'][$key] == "") ? false : $args['items']['ref'][$key];
					$item = [
						'ref' => $ref,
						'unit_price' => $args['items']['unit_price'][$key],
						'description' => $args['items']['description'][$key],
						'qty' => $args['items']['qty'][$key],
						'success_method' => $args['items']['success_method'][$key],
						'error_method' => $args['items']['error_method'][$key],
					];
					if(isset($old_items[$ref]) && is_array($old_items[$ref])) {
						$item = array_merge($old_items[$ref], $item);
					} else {
						$item['fee_id'] = $ref;
					}
					$invoice->add_item(
						$item['unit_price'], 
						$item['description'], 
						$item['fee_id'],
						$item['qty'], 
						$item['ref'],
						$item['success_method'], 
						$item['error_method'],
						true
					);
				}
				$invoice->save();
				$response['error'] = 0;
				$response['msg'] = "You have successfully updated the invoice.";
				echo json_encode($response);
				exit();
				break;

			case 'pm_reject_payment':
				$invoice = new pm_invoice($args['user_id']);
				$invoice->set_invoice_by_number($args['in_ref']);

				$payment_meta = $post->get_post_meta($args['id']);

				if($payment_meta['status'] === "confirmed") {
					$response['error'] = 1;
					$response['msg'] = 'Sorry, this payment has already been confirmed by '.get_fullname($payment_meta['confirmed_by']);
					echo json_encode($response);
					exit();
				}

				if($payment_meta['status'] === "rejected") {
					$response['error'] = 1;
					$response['msg'] = "This payment was already rejected by ".get_fullname($payment_meta['rejected_by']).". Reason: ".$payment_meta["reason"];
					echo json_encode($response);
					exit();
				}

				if($args['user_id'] == $session->id) {
					$response['error'] = 1;
					$response['msg'] = 'Sorry, you cannot reject your own payment. Please ask another admin to perform the action.';
					echo json_encode($response);
					exit();
				}
				$update = $post->update_post_meta($args['id'], ["status" => "rejected", "reason" => $args["reason"], "rejected_by" => $session->id, 'rejected_on' => time()]);
				if($update) {
					if(function_exists($invoice->invoice->error_method)) {
						$error_method = $invoice->invoice->error_method;
						$res = $error_method($args);
						if($res) {
							
							$home_url = get_option("home_url");
							$user_meta = get_user_meta($args['user_id']);
							$info = "Your payment ref #".$args['in_ref']." of ".toMoney($invoice->total(true))." was rejected by the admin. Reason: \"".$args['reason']."\" You can <a href=\"".$home_url."support-ticket\">open a support ticket</a> to dispute this decision.";
							inform_user($user_meta, $info, "PAYMENT REJECTED", $home_url."support-ticket", EMAIL, SMS, NOTIFICATION);
							$info = "The admin in this mention, rejected the payment of ".toMoney($invoice->total(true))." by ".get_fullname($args['user_id'])." on ".date(_DATE_FORMAT_, $invoice->invoice->date_created)." Reason: \"".$args['reason']."\"";
							admin_log($info);
							$info = get_fullname($session->id)." rejected a payment ref #".$args['in_ref']." of ".toMoney($invoice->total(true))." by ".get_fullname($user_meta)." Reason: \"".$args['reason']."\"";
							inform_admins($info, "PAYMENT REJECTED", $home_url."invoice?id=".$invoice->invoice->id, "super_admin", "admin", "admin_tech", "super_admin_tech");
							$response['error'] = 0;
							$response['msg'] = 'You have successfully rejected this payment. Thank you.';
						} else {
							if($error_method == NULL || $error_method == "") {
								$info = "The admin in this mention, rejected the payment of ".toMoney($invoice->total(true))." by ".get_fullname($args['user_id'])." on ".date(_DATE_FORMAT_, $invoice->invoice->date_created)." Reason: \"".$args['reason']."\"";
								admin_log($info);
								$info = get_fullname($session->id)." rejected a payment ref #".$args['in_ref']." of ".toMoney($invoice->total(true))." by ".get_fullname($user_meta)." Reason: \"".$args['reason']."\"";
								inform_admins($info, "PAYMENT REJECTED", $home_url."invoice?id=".$invoice->invoice->id, "super_admin", "admin", "admin_tech", "super_admin_tech");
								$response['error'] = 0;
								$response['msg'] = 'You have successfully rejected this payment. Thank you.';
							} else {
								$post->update_post_meta($args['id'], ["status" => "submitted"]);
								$response['error'] = 1;
								$response['msg'] = 'Sorry, the system failed to give value to the payer, Please contact the software developer.';
							}
						}
					} else {
						if($invoice->invoice->error_method == NULL || $invoice->invoice->error_method == "") {
							$info = "The admin in this mention, rejected the payment by ".get_fullname($args['user_id'])." Reason: \"".$args['reason']."\"";
							admin_log($info);
							$info = get_fullname($session->id)." rejected a payment ref #".$args['in_ref']." of ".toMoney($invoice->total(true))." by ".get_fullname($user_meta)." Reason: \"".$args['reason']."\"";
							inform_admins($info, "PAYMENT REJECTED", $home_url."invoice?id=".$invoice->invoice->id, "super_admin", "admin", "admin_tech", "super_admin_tech");
							$response['error'] = 0;
							$response['msg'] = 'You have successfully rejected this payment. Thank you.';
						} else {
							$post->update_post_meta($args['id'], ["status" => "submitted"]);
							$response['error'] = 1;
							$response['msg'] = 'Sorry, there is no function <strong>'.$invoice->invoice->error_method.'</strong> in place to regularlize the system, Please contact the software developer.';
						}
					}
				}
				echo json_encode($response);
				exit();
				break;

			case "add_account":
				$login = $user->user_login($session->id, $args['password']);
				unset($args['password']);
				if($login == 0) {
					$response['msg'] = "Sorry, you entered a wrong password.";
					$response['error'] = 1;
				} else if ($login == -1) {
					$response['msg'] = "Sorry, you cannot perform this action.";
					$response['error'] = 1;
				} else if ($login == 1) {
					$args['type'] = "pm_account";
					$args['user_id'] = $session->id;
					$args['status'] = "pending";
					$res = $post->add_post($args);
					if($res) {
						unset($args['user_id']);
						unset($args['type']);
						unset($args['status']);
						$subject = "REQUEST TO ADD ACCOUNT";
						$action = get_option("home_url")."pm-account?action=".base64_encode("pm_add_account_confirm")."&id=".base64_encode($res);
						$info = "<p>There is a request to add an account details to your profile. Click the link below to confirm or highlight and copy the link (if not clickable)</p>";
						$info .= "<a href=\"".$action."\">".$action."</a><br/>";
						$info .= "<h3>DETAILS</h3>";
						$info .= "<dl>";
						foreach ($args as $key => $value) {
							$info .= "<dt>".$key."</dt>";
							$info .= "<dd>".$value."</dd>";
						}
						$info .= "</dl><br/>";
						$info .= "<p>If you did not initiate this request, please <strong>DO NOT CLICK</strong> on the link above. You may consider changing your password.</p>";
						inform_user($session->id, $info, $subject, $action, EMAIL);
						$response['msg'] = "We sent you a mail to this effect. Please check your mail to complete this process.";
						$response['error'] = 0;
					} else {
						$response['msg'] = "Failed";
						$response['error'] = 1;
					}
				} else {
					$response['msg'] = "Failed";
					$response['error'] = 1;
				}
				echo json_encode($response);
				exit();
				break;

			case "getInflowOutflow":
				$response = get_inflow_outflow_chartdata();
				echo json_encode($response);
				exit();
				break;

			case "getLedgerBalance":
				$response = get_ledger_balance_chartdata();
				echo json_encode($response);
				exit();
				break;

			case "add_bank":
				if(db_post_unique(['type' => 'pm_bank_account', 'account_number' => $args['account_number'], 'bank_name' => $args['bank_name']])) {
					$response['error'] = 1;
					$response['msg'] = "Account already exist";
					echo json_encode($response);
					exit();
				}
				$args['type'] = "pm_bank_account";
				$args['status'] = 'active';
				$bank_id = $post->add_post($args);
				if($bank_id) {
					$response['error'] = 0;
					$response['msg'] = "Done";
				} else {
					$response['error'] = 1;
					$response['msg'] = "Something went wrong";
				}
				remove_record("pm_bank_accounts_option");
				echo json_encode($response);
				exit();
				break;

			case "edit_bank":
				if($existing = db_post_unique(['type' => 'pm_bank_account', 'account_number' => $args['account_number'], 'bank_name' => $args['bank_name']])) {
					if($existing['id'] != $args['id']) {
						$response['error'] = 1;
						$response['msg'] = "Account already exist";
						echo json_encode($response);
						exit();
					}
				}
				$post->update_post_meta($args['id'], $args);
				$response['error'] = 0;
				$response['msg'] = "Done";
				remove_record("pm_bank_accounts_option");
				echo json_encode($response);
				exit();
				break;

			case "add_discount":
				$invoice = new pm_invoice($args['user_id']);
				$invoice->set_invoice_by_number($args['in_ref']);
				$ref = trim(($args['ref'] ?? "")) == "" ? false : ($args['ref'] ?? false);
				if($invoice->apply_discount($args['discount'], $args['narration'], $ref, $args['mode'])) {
					$response['msg'] = "Done";
					$response['error'] = 0;
				} else {
					$response['msg'] = "Failed";
					$response['error'] = 1;
				}
				echo json_encode($response);
				exit();
				break;

			default:
				$response['error'] = 1;
				$response['msg'] = 'You have not created a module to process this form submission';
				echo json_encode($response);
				break;
		}
		// json_encode($response);
	}

endif;