<?php
	
	namespace Main\Controllers\Credit;
	
	use Exception;
	use Main\Libs\Payment\Order;
	use Main\Libs\Payment\Product;
	use Main\Core\Controller;
	use Main\Services\PaymentGatewayService;
	use Main\Services\SeoService;
	
	class PackageController extends Controller
	{
		protected string $route_type = 'credits';
		
		public function __construct()
		{
			if (modules('credit')->settings('creditPackageStatus') == 0) {
				redirect(url('credits.charge.index'));
			}
		}
		
		public function index()
		{
			SeoService::set('credits.packages.index');
			
      $products = db()->query("SELECT * FROM CreditPackages ORDER BY price ASC");
      $products = array_map(function ($product) {
				$product["discounted"] = $product["discountedPrice"] != 0 && ($product["discountExpiryDate"] > datetime() || $product["discountExpiryDate"] == '1000-01-01 00:00:00');
				$product["discountPercent"] = $product["discounted"] ? round((($product["price"]-$product["discountedPrice"])*100)/($product["price"])) : 0;
				$product["image"] = "/assets/core/images/store/products/" . $product["imageID"].'.'.$product["imageType"];
				
				return $product;
      }, $products->fetchAll());

			return $this->view('credits.packages.index', compact('products'));
		}
		
		public function show($id)
		{
      $product = db()->prepare("SELECT * FROM CreditPackages WHERE id = ?");
      $product->execute(array($id));
      $product = $product->fetch();

      if (!$product) abort_404();
			
			SeoService::set('credits.packages.show', [
				'package_name' => $product['name'],
			]);
			
			$product["discounted"] = ($product["discountedPrice"] != 0 && ($product["discountExpiryDate"] > datetime() || $product["discountExpiryDate"] == '1000-01-01 00:00:00'));
			$product["discountPercent"] = $product["discounted"] ? round((($product["price"]-$product["discountedPrice"])*100)/($product["price"])) :  0;
			
			$product["total"] = $product["discounted"] ? $product["discountedPrice"] : $product["price"];
			$product["subtotal"] = $product["price"];
			$product["discount"] = $product["discounted"] ? $product["price"] - $product["discountedPrice"] : 0;
			$product["tax"] = 0;
			if (modules('store')->settings('tax') > 0 && modules('store')->settings('isCreditRequiredOnPurchase') == 1) {
				$product["tax"] = ($product["total"]) * (modules('store')->settings('tax') / 100);
			}
			$product["total"] += $product["tax"];
			$product["image"] = "/assets/core/images/store/products/" . $product["imageID"].'.'.$product["imageType"];
			
			$paymentGateways = db()->prepare("SELECT * FROM PaymentGateways WHERE status = ? ORDER BY `order` ASC, title ASC");
			$paymentGateways->execute(array(1));
			$paymentGateways = $paymentGateways->fetchAll();
			
			if (request()->isAjax() || request()->isFormatAccepted('json')) {
				response()->json([
					'status' => true,
					'html' => template()->render('modals/credit-package', compact('product', 'paymentGateways'))
				]);
			}
			
			return $this->view('credits.packages.show', compact('product', 'paymentGateways'));
		}
		
		public function buy($id)
		{
			validate([
				"paymentGatewayID" => "required"
			]);
			
			if (auth()->user()->email() == "your@email.com") {
				return back()->flash('error', t__('To buy credits, you need to update your email.'));
			}
			
			if (modules('credit')->settings('showTermsCheckbox') == 1 && !isset($_POST["terms"])) {
				return back()->flash('error', t__('You must accept the terms and conditions!'));
			}
			
			$product = db()->prepare("SELECT * FROM CreditPackages WHERE id = ?");
			$product->execute(array($id));
			$product = $product->fetch();
			
			if (!$product) abort_404();
			
			if ($product["stock"] == 0) {
				return back()->flash('error', t__('Out of stock!'));
			}
			
			$paymentGateway = db()->prepare("SELECT * FROM PaymentGateways WHERE slug = ? AND status = ?");
			$paymentGateway->execute([input("paymentGatewayID"), 1]);
			$paymentGateway = $paymentGateway->fetch();
			if (!$paymentGateway) return back();
			
			$discountedPriceStatus = ($product["discountedPrice"] != 0 && ($product["discountExpiryDate"] > date("Y-m-d H:i:s") || $product["discountExpiryDate"] == '1000-01-01 00:00:00'));
			$subtotal = $discountedPriceStatus ? $product["discountedPrice"] : $product["price"];
			$tax = 0;
			if (modules('store')->settings('tax') > 0 && modules('store')->settings('isCreditRequiredOnPurchase') == 1) {
				$tax = ($subtotal) * (modules('store')->settings('tax') / 100);
			}
			$total = $subtotal + $tax;
			
			$gatewayFee = 0;
			if ($paymentGateway["feeStatus"] == 1) {
				$gatewayFee = $total * ($paymentGateway["transactionFee"] / 100);
				if ($paymentGateway["fixedFee"] > 0) {
					$gatewayFee += $paymentGateway["fixedFee"];
				}
				
				$total += $gatewayFee;
			}
			
			$createOrder = db()->prepare("INSERT INTO Orders (accountID, coupon, total, discount, subtotal, tax, gatewayFee, paymentID, paymentAPI, status, type, credit, earnings, creationDate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
			$createOrder->execute(array(
				auth()->user()->id(),
				null,
				$total,
				0,
				$subtotal,
				$tax,
				$gatewayFee,
				"",
				$paymentGateway["slug"],
				0,
				3,
				0,
				$total,
				datetime()
			));
			$orderID = db()->lastInsertId();
			
			$insertOrderCreditPackage = db()->prepare("INSERT INTO OrderCreditPackages (orderID, packageID) VALUES (?, ?)");
			$insertOrderCreditPackage->execute(array($orderID, $product["id"]));
			
			$customer = PaymentGatewayService::getCustomer();
			
			// Order object
			$products = [
				new Product($product["name"], $total, 1)
			];
			$order = new Order(
				$orderID,
				"credit",
				$total,
				$subtotal,
				$tax,
				$gatewayFee,
				0,
				0,
				null,
				$products
			);
			
			try {
				$payment = PaymentGatewayService::init($paymentGateway["slug"], $paymentGateway["currency"], $paymentGateway["config"]);
				$payment->setCustomer($customer);
				$payment->setOrder($order);
				$payment->pay();
			} catch (Exception $e) {
				if (settings('debugModeStatus') == 1) {
					return $e->getMessage();
				} else {
					return $this->view('payment.error');
				}
			}
		}
	}