<?php
session_start();
$session_user_ent_id = $_SESSION["user_ent_id"] ?? "";

// ob_clean(); // clear previous output
// header('Content-Type: application/json; charset=utf-8');
// error_reporting(0); // temporarily suppress warnings while testing

require_once '../vendor/autoload.php';
require_once "../models/Operations.php";

use Dotenv\Dotenv;

$dotenv = Dotenv::createImmutable(__DIR__ . "/../");
$dotenv->load();

$stripeSecretKey = $_ENV['STRIPE_SECRET_KEY'];

\Stripe\Stripe::setApiKey($stripeSecretKey);

$stripe = new \Stripe\StripeClient($stripeSecretKey);

// Build dynamic URLs (e.g., for local and production environments)
$appURL = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http");
$appURL .= "://{$_SERVER['HTTP_HOST']}";

switch ($_GET["case"]) {

	// Create new Stripe Product and Price
	case 'createNewStripeProductPrice':

		// Sanitize and validate input data
		$plan_name  = isset($_POST["plan_name"]) ? funCheckInput($_POST["plan_name"]) : '';
		$plan_description = isset($_POST["plan_description"]) ? funCheckInput($_POST["plan_description"]) : '';
		$plan_price = isset($_POST["plan_price"]) ? funCheckInput($_POST["plan_price"]) : '';
		$plan_recurring = isset($_POST["plan_recurring"]) ? funCheckInput($_POST["plan_recurring"]) : '';
		$plan_interval = isset($_POST["plan_interval"]) ? funCheckInput($_POST["plan_interval"]) : '';
		$plan_interval_count = isset($_POST["plan_interval_count"]) ? funCheckInput($_POST["plan_interval_count"]) : '';
		$plan_features = isset($_POST["plan_features"]) ? funCheckInput($_POST["plan_features"]) : '';

		$errors = [];

		// ✅ Validate product name
		if (empty($plan_name)) {
			$errors[] = 'Product name is required.';
		} elseif (strlen($plan_name) > 250) {
			$errors[] = 'Product name must be 250 characters or less.';
		}

		// ✅ Validate product description
		if (empty($plan_description)) {
			$plan_description = "Access to all {$plan_name} features, updated monthly.";
		} elseif (strlen($plan_description) > 500) {
			$errors[] = 'Product description must be 500 characters or less.';
		}

		$plan_price = $plan_price * 100;

		// ✅ Validate plan_price
		if ($plan_price === '' || !is_numeric($plan_price)) {
			$errors[] = 'Price must be a numeric value (in cents).';
		} elseif ($plan_price <= 0) {
			$errors[] = 'Price must be greater than zero.';
		} elseif ($plan_price > 99999999) {
			$errors[] = 'Price exceeds maximum allowed amount.';
		}

		// ✅ Validate required fields
		if (!empty($errors)) {

			$result = [
				'success' => false,
				'error' => $errors
			];

			// Return JSON response
			header('Content-Type: application/json');
			http_response_code($result['success'] ? 200 : 400);
			echo json_encode($result);

			exit();
		}

		try {

			// ✅ Create Product
			$product = $stripe->products->create([
				'name'        => $plan_name,
				'active'      => true,
				'description' => $plan_description,
				'metadata'    => [
					'app_source' => 'evosyspos',
					'created_by' => 'api_script',
				],
			]);

			// ✅ Create Price linked to Product
			$priceData = [
				'product'     => $product->id,
				'unit_amount' => intval($plan_price), // amount in cents
				'currency'    => 'usd',
			];

			// ✅ Only add recurring if it's enabled
			if ($plan_recurring === 'Yes') {
				if (empty($plan_interval) || !in_array($plan_interval, ['day', 'week', 'month', 'year'])) {
					$plan_interval = 'month'; // default to month
				}
				if (empty($plan_interval_count) || !is_numeric($plan_interval_count) || $plan_interval_count <= 0) {
					$plan_interval_count = 1; // default to 1
				}

				$priceData['recurring'] = [
					'interval'       => $plan_interval, // e.g. 'month', 'year', 'day', 'week'
					'interval_count' => intval($plan_interval_count), // e.g. 1
				];
			} else {
				$plan_interval = 'none';
				$plan_interval_count = 1;
			}

			$price = $stripe->prices->create($priceData);

			$plan_price = $plan_price / 100; // convert cents to dollars for DB storage

			$sql = "INSERT INTO tb_stripe_plans (plan_product_id, plan_product_price_id,plan_name, plan_price, plan_recurring, plan_interval, plan_interval_count, plan_description, plan_features) VALUES ('$product->id','$price->id','$plan_name','$plan_price','$plan_recurring','$plan_interval','$plan_interval_count','$plan_description','$plan_features');";

			// exit($sql);
			$answer = executeQueryPDOApi($sql, "Saved", "PLANS");

			if ($answer['status'] == 'success') {
				// Successfully saved to database
				$message = "Product and price created successfully and saved to database.";
			} else {
				// Handle database save error if necessary
				$message = "Product and price created successfully but failed to save to database.";
			}

			$response = [
				'success' => true,
				'message' => $message,
				'data'    => [
					'product' => [
						'id'          => $product->id,
						'name'        => $product->name,
						'description' => $product->description,
					],
					'price' => [
						'id'        => $price->id,
						'amount'    => $price->unit_amount,
						'currency'  => $price->currency,
						'interval'  => $price->recurring->interval ?? "",
						'interval_count'  => $price->recurring->interval_count ?? "",
						'type'      => $price->type,
					],
				],
			];

			// ✅ Structured success response
			header('Content-Type: application/json');
			http_response_code(200);
			echo json_encode($response);
		} catch (Exception $e) {
			http_response_code(500);
			echo json_encode([
				'success' => false,
				'error'   => 'Error creating product or price: ' . $e->getMessage(),
			]);
		}

		break;


	// Create Stripe Checkout Session
	case 'createCheckoutStripeSession':

		// Sanitize and validate input data
		$product_price_id  = $_GET["product_price_id"];
		$client_reference_id  = $_GET["client_reference_id"];
		$client_reference_email  = $_GET["client_reference_email"];
		$client_reference_name  = $_GET["client_reference_name"];
		$pos_quantity  = $_GET["pos_quantity"];

		$result = [];
		$errors = [];

		// Validate price
		if (empty($product_price_id) || !is_string($product_price_id)) {
			$errors[] = 'Product Price ID is required';
		}

		// Validate client_reference_id
		if (empty($client_reference_id) || !is_string($client_reference_id)) {
			$errors[] = 'Client reference ID is required';
		}

		// Validate client_reference_email
		if (empty($client_reference_email) || !is_string($client_reference_email)) {
			$errors[] = 'Client reference email is required';
		}

		// ✅ Validate required fields
		if (!empty($errors)) {

			$result = [
				'success' => false,
				'error' => $errors
			];

			// Return JSON response
			header('Content-Type: application/json');
			http_response_code($result['success'] ? 200 : 400);
			echo json_encode($result);

			exit;
		}

		// $newCustomer = $stripe->customers->create([
		// 	'email' => $client_reference_email,
		// 	'name'  => $client_reference_name,
		// 	'metadata' => [
		// 		'enterprise_id' => $client_reference_id,
		// 		'app_source' => 'evosyspos',
		// 	],
		// ]);

		$resCheckout = $stripe->checkout->sessions->create([
			'mode' => 'subscription',
			'line_items' => [[
				'price' => $product_price_id,
				'quantity' => $pos_quantity,
			]],
			// 'customer' => $newCustomer->id, // REQUIRED for Accounts v2 if using test mode
			// Reference to identify which enterprise initiated the checkout
			'client_reference_id' => (string) $client_reference_id,
			// Metadata for webhook tracking
			'subscription_data' => [
				'metadata' => [
					'enterprise_id' => $client_reference_id,
					'app_source' => 'evosyspos',
					//'trial_period_days' => 7, // Optional trial period
				],
			],
			'metadata' => [
				'enterprise_id' => $client_reference_id,
				'app_source' => 'evosyspos', // you can add more info here
			],
			// Success and cancel URLs (session ID auto-injected)
			'success_url' => $appURL . '/stripe/success.php?session_id={CHECKOUT_SESSION_ID}',
			'cancel_url' => $appURL . '/stripe/cancel.php?session_id={CHECKOUT_SESSION_ID}',
			// (Optional) Automatic tax collection (useful if you sell internationally)
			'automatic_tax' => ['enabled' => true],   // 'if_required' for pure guest (no Customer object created)
			// (Optional) Promotion codes if you plan to offer discounts
			'allow_promotion_codes' => true,
		]);

		$result = [
			'success' => true,
			'data' => [
				'mode' => $resCheckout->mode,
				'client_reference_id' => $resCheckout->client_reference_id,
				'enterprise_id' => $resCheckout->metadata->enterprise_id,
				'session_id' => $resCheckout->id,
				'checkout_url' => $resCheckout->url,
				'checkout_session' => $resCheckout,

			],
			'message' => 'Product and price created successfully'
		];

		// echo json_encode($resProductPrice);

		// Return JSON response
		header('Content-Type: application/json');
		http_response_code($result['success'] ? 200 : 400);
		echo json_encode($result);
		break;

	// List stripe product prices
	case 'productPriceListing':
		$sql = "SELECT *,DATE_FORMAT(plan_created_at, '%d-%b-%Y %H:%i:%s') AS plan_created_at_formatted FROM tb_stripe_plans;";
		// exit($sql);
		$rows = executePDOFetchAllAPI($sql);
		echo json_encode($rows);
		break;


	// List stripe subscriptions
	case 'subscriptionListing':

		$status = isset($_GET["status"]) ? funCheckInput($_GET["status"]) : "";

		$whereStatus = "";
		if (!empty($status)) $whereStatus = "WHERE s.subscription_status = '$status'";

		$sql = "SELECT s.*,
		s.subs_enterprise_id,
		e.ent_name,
		c.customer_email,
		c.customer_name,
		DATE_FORMAT(subs_created_at, '%d-%b-%Y %H:%i:%s') AS subs_created_at_formatted
		FROM tb_stripe_subscriptions s
		LEFT JOIN tb_enterprises e
		ON e.ent_id = s.subs_enterprise_id
		LEFT JOIN tb_stripe_customers c
		ON c.customer_id = s.subs_customer_id
		$whereStatus;";
		// exit($sql);
		$rows = executePDOFetchAllAPI($sql);
		echo json_encode($rows);
		break;


	// List stripe invoices
	case 'invoiceListing':

		// Sanitize and validate input data
		$ent_id  = isset($_GET["ent_id"]) ? funCheckInput($_GET["ent_id"]) : '';
		$fromDate = isset($_GET["fromDate"]) ? funCheckInput($_GET["fromDate"]) : "";
		$toDate = isset($_GET["toDate"]) ? funCheckInput($_GET["toDate"]) : "";
		$status  = isset($_GET["status"]) ? funCheckInput($_GET["status"]) : '';

		$whereDate = "";
		if (!empty($fromDate) && !empty($toDate)) {
			$whereDate = "WHERE DATE_FORMAT(inv_date, '%Y-%m-%d') BETWEEN '$fromDate' AND '$toDate'";
		}

		$whereEntId = "";
		if (!empty($ent_id) && $ent_id != "All") $whereEntId = "AND inv_enterprise_id = '$ent_id'";

		$whereStatus = "";
		if (!empty($status) && $status != "All") $whereStatus = "AND inv_status = '$status'";

		$sql = "SELECT *,
		(select ent_name FROM tb_enterprises WHERE ent_id = inv_enterprise_id) AS enterprise_name,
		DATE_FORMAT(inv_date, '%d-%b-%Y %H:%i:%s') AS inv_date_formatted,
		DATE_FORMAT(inv_created_at, '%d-%b-%Y %H:%i:%s') AS inv_created_at_formatted
		FROM tb_stripe_invoices
		$whereDate $whereEntId $whereStatus;";

		// exit($sql);

		$rows = executePDOFetchAllAPI($sql);
		echo json_encode($rows);
		break;


	// List stripe customers
	case 'customerListing':
		$sql = "SELECT *,(select ent_name FROM tb_enterprises WHERE ent_id = customer_enterprise_id) AS enterprise_name,DATE_FORMAT(customer_created_at, '%d-%b-%Y %H:%i:%s') AS customer_created_at_formatted FROM tb_stripe_customers;";
		// exit($sql);
		$rows = executePDOFetchAllAPI($sql);
		echo json_encode($rows);
		break;


	// List stripe customers
	case 'createCustomerPortalSession':

		$customerId = $_GET['stripe_customer_id'];

		if ($customerId == "") {
			$response = [
				"status" => "warning",
				"message" => "Missing parameter: stripe_customer_id",
			];
			echo json_encode($response);
			exit();
		}

		$session = $stripe->billingPortal->sessions->create([
			'customer' => $customerId,
			'return_url' => $appURL . '/billing',
		]);

		echo json_encode([
			'url' => $session->url
		]);

		break;


	// List stripe customers
	case 'getStripeCustomerSubscriptionData':

		$customerId = $_GET['stripe_customer_id'];
		$subscriptionId = $_GET['stripe_subscription_id'];

		if (empty($customerId)) {
			$response = [
				"status" => "warning",
				"message" => "Missing parameter: stripe_customer_id",
			];
			echo json_encode($response);
			exit();
		}

		if (empty($subscriptionId)) {
			$response = [
				"status" => "warning",
				"message" => "Missing parameter: stripe_subscription_id",
			];
			echo json_encode($response);
			exit();
		}

		// Subscription
		$subscription = $stripe->subscriptions->retrieve($subscriptionId);

		$customer = $stripe->customers->retrieve($customerId);

		// Invoices
		$invoices = $stripe->invoices->all([
			'customer' => $customerId,
			// 'created'  => [
			// 	'gte' => strtotime(date('Y-01-01')),
			// 	'lte' => time(),
			// ],
		]);

		$subscriptionId = $subscription->id ?? null;
		$subStatus = $subscription->status ?? null;

		if (!empty($session_user_ent_id)) {
			// Update subscription status in your database here

			$entInfo = getEnterpriseData($session_user_ent_id);

			if ($entInfo['subscription_status'] !== $subStatus) {

				$sqlUpdateSubStatus = "UPDATE tb_stripe_subscriptions SET subscription_status = '{$subStatus}' WHERE subs_subscription_id = '{$subscriptionId}';";
				executeQueryPDOApi($sqlUpdateSubStatus, "Updated", "SUBSCRIPTIONS");

				$sqlUpdateEntSubStatus = "UPDATE tb_enterprises SET ent_stripe_subscription_status = '{$subStatus}' WHERE ent_stripe_subscription_id='{$subscriptionId}';";
				executeQueryPDOApi($sqlUpdateEntSubStatus, "Updated", "ENTERPRISES");
			}
		}

		$subscriptionItem = $subscription->items->data[0] ?? null;
		$items = $subscriptionItem->price ?? null;
		$product_id = $items->product ?? null;

		// Product
		$product = $stripe->products->retrieve($product_id);
		$product_name = $product->name ?? null;

		$subsData = [
			'customer' => [
				'name'  => $customer->name ?? null,
				'email' => $customer->email ?? null,
			],
			'subscription' => $subscription ? [
				'plan' => $items->nickname ?? $items->id,
				'product_name' => $product_name ?? null,
				'quantity' => $subscriptionItem->quantity,
				'unit_amount' => $items->unit_amount ? $items->unit_amount / 100 : null,
				'currency' => $items->currency ?? null,
				'interval_count' => $items->recurring->interval_count ?? null,
				'interval' => $items->recurring->interval ?? null,
				'previous_billing' => date('F d, Y', $subscriptionItem->current_period_start),
				'next_billing' => date('F d, Y', $subscriptionItem->current_period_end),
				'status' => $subscription->status,
				// 'subscription' => $subscription,
				// 'invoices' => $invoices->data ?? [],
			] : null,
			'invoices' => array_map(static fn($invoice) => [
				'date' => date('M d, Y H:i:s', $invoice->created),
				'amount' => $invoice->amount_paid > 0
					? $invoice->amount_paid / 100
					: ($invoice->amount_due !== null ? $invoice->amount_due / 100 : null),
				'currency' => $invoice->currency,
				'status' => $invoice->status,
				'hosted_invoice_url' => $invoice->hosted_invoice_url,
			], $invoices->data ?? []),
		];

		echo json_encode($subsData);

		break;
}
