<?php
/**
 * Truebe plan: reads the site's document allowance from truebe.io.
 *
 * The plugin does not define any allowance of its own. The allowance is set
 * by the truebe.io account service and delivered in the license verification
 * response, then cached in the 'truebe_doc_limit' option. Until the service
 * has supplied a value, the plugin imposes no limit.
 */

if ( ! defined( 'ABSPATH' ) ) { exit; }
if ( class_exists( 'Truebe_Plan' ) ) { return; }

class Truebe_Plan {

	const PLAN_FREE       = 'free';
	const PLAN_PRO        = 'pro';
	const PLAN_ENTERPRISE = 'enterprise';

	const UPGRADE_URL = 'https://www.truebe.io/connect';

	/** Option holding the allowance supplied by truebe.io. */
	const LIMIT_OPTION = 'truebe_doc_limit';

	/** source_doc values that are not real uploaded documents. */
	private static $non_doc_sources = array(
		'Added by you',
		'From a visitor question',
	);

	/** Current plan slug as reported by truebe.io. */
	public static function plan() {
		$plan  = (string) get_option( 'truebe_plan', self::PLAN_FREE );
		$valid = array( self::PLAN_FREE, self::PLAN_PRO, self::PLAN_ENTERPRISE );
		if ( ! in_array( $plan, $valid, true ) ) { $plan = self::PLAN_FREE; }
		return apply_filters( 'truebe_plan', $plan );
	}

	/** True on any paying plan. */
	public static function is_paid() {
		return self::PLAN_FREE !== self::plan();
	}

	/**
	 * Document allowance supplied by the truebe.io account service.
	 * 0 means no limit, which is also the state before the service has replied.
	 */
	public static function doc_limit() {
		$limit = get_option( self::LIMIT_OPTION, null );
		if ( null === $limit || '' === $limit ) { return 0; }
		return (int) apply_filters( 'truebe_doc_limit', max( 0, (int) $limit ) );
	}

	/** True once truebe.io has supplied an allowance for this site. */
	public static function has_limit() {
		return self::doc_limit() > 0;
	}

	/** Number of distinct uploaded documents in the Fact Library. Manual and visitor-question seeds do not count. */
		public static function doc_count() {
		global $wpdb;
		$table = $wpdb->prefix . 'truebe_seeds';
	// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- custom plugin table; table name is $wpdb->prefix plus a fixed string, and both values are placeholder-prepared.
		$count = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT COUNT(DISTINCT source_doc) FROM {$table} WHERE source_doc IS NOT NULL AND source_doc != '' AND source_doc NOT IN (%s, %s)",
				self::$non_doc_sources[0],
				self::$non_doc_sources[1]
			)
		);
	// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
		return (int) $count;
	}

/** True if the site may upload one more document. */
	public static function can_upload_doc() {
		if ( class_exists( 'Truebe_License' ) && ! Truebe_License::is_valid() ) { return false; }
		if ( ! self::has_limit() ) { return true; }
		return self::doc_count() < self::doc_limit();
	}

	/** Documents remaining. -1 means no limit has been set. */
	public static function docs_remaining() {
		if ( ! self::has_limit() ) { return -1; }
		return max( 0, self::doc_limit() - self::doc_count() );
	}

	/** Message shown when the account's document allowance is reached. */
	public static function limit_message() {
		if ( ! self::has_limit() ) { return ''; }
		if ( self::is_paid() ) {
			return sprintf(
				/* translators: %d: document allowance on the current account */
				__( 'Your Truebe account includes %d documents. Add more at truebe.io.', 'truebe-fact-based-ai-chatbot' ),
				self::doc_limit()
			);
		}
		return sprintf(
			/* translators: %d: document allowance on the current account */
			__( 'Your Truebe account includes %d documents. Upgrade at truebe.io for more.', 'truebe-fact-based-ai-chatbot' ),
			self::doc_limit()
		);
	}
}