<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }
if ( class_exists( 'Truebe_Admin_Upload' ) ) { return; }

class Truebe_Admin_Upload {

	const MENU_SLUG = 'truebe-upload';
	const ACTION    = 'truebe_upload_document';

	public static function init() {
		add_action( 'admin_menu', array( __CLASS__, 'register_page' ), 20 );
		add_action( 'admin_post_' . self::ACTION, array( __CLASS__, 'handle_post' ) );
		add_action( 'wp_ajax_' . self::ACTION, array( __CLASS__, 'handle_post' ) );
		add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_assets' ) );
		add_action( 'wp_ajax_truebe_job_status', array( __CLASS__, 'ajax_status' ) );
		add_action( 'wp_ajax_truebe_process', array( __CLASS__, 'ajax_process' ) );
		add_action( 'truebe_run_job', array( 'Truebe_Documents', 'run_job' ) );
	}

	public static function ajax_status() {
		if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( 'forbidden', 403 ); }
		check_ajax_referer( self::ACTION );
		$job = isset( $_GET['job'] ) ? sanitize_text_field( wp_unslash( $_GET['job'] ) ) : '';
		if ( '' === $job || ! class_exists( 'Truebe_Documents' ) ) { wp_send_json_error( 'bad_request', 400 ); }
		wp_send_json_success( Truebe_Documents::get_status( $job ) );
	}

	public static function ajax_process() {
		if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( 'forbidden', 403 ); }
		check_ajax_referer( self::ACTION );
		$job = isset( $_POST['job'] ) ? sanitize_text_field( wp_unslash( $_POST['job'] ) ) : '';
		if ( '' === $job || ! class_exists( 'Truebe_Documents' ) ) { wp_send_json_error( 'bad_request', 400 ); }
		wp_schedule_single_event( time(), 'truebe_run_job', array( $job ) );
		spawn_cron();
		wp_send_json_success();
	}

	public static function register_page() {
		add_submenu_page( 'truebe', __( 'Upload Documents', 'truebe-fact-based-ai-chatbot' ), __( 'Upload Documents', 'truebe-fact-based-ai-chatbot' ), 'manage_options', self::MENU_SLUG, array( __CLASS__, 'render' ) );
	}

	public static function enqueue_assets( $hook ) {
		if ( false === strpos( (string) $hook, self::MENU_SLUG ) ) { return; }
		wp_enqueue_style( 'truebe-admin', plugins_url( '../assets/admin.css', __FILE__ ), array(), (string) filemtime( plugin_dir_path( __FILE__ ) . '../assets/admin.css' ) );
		wp_enqueue_script( 'truebe-upload', plugins_url( '../assets/upload.js', __FILE__ ), array(), (string) filemtime( plugin_dir_path( __FILE__ ) . '../assets/upload.js' ), true );
		wp_localize_script(
			'truebe-upload',
			'truebeUpload',
			array(
				'ajax'               => esc_url_raw( admin_url( 'admin-ajax.php' ) ),
				'nonce'              => wp_create_nonce( self::ACTION ),
				'upgradeUrl'         => esc_url_raw( class_exists( 'Truebe_Plan' ) ? Truebe_Plan::UPGRADE_URL : 'https://www.truebe.io/pricing' ),
				'docsRemaining'      => class_exists( 'Truebe_Plan' ) ? Truebe_Plan::docs_remaining() : -1,
				'limitAlert'         => class_exists( 'Truebe_Plan' ) ? Truebe_Plan::limit_message() : '',
				/* translators: %d: uploads remaining on plan */
				'overLimitAlert'     => __( 'You have %d document uploads left on your plan.', 'truebe-fact-based-ai-chatbot' ),
				'overLimitLink'      => __( 'Upgrade to $49/mo', 'truebe-fact-based-ai-chatbot' ),
				'overLimitTail'      => __( 'for 25 documents.', 'truebe-fact-based-ai-chatbot' ),
				/* translators: %s: document file name */
				'labelBuildingFrom'  => __( 'Building answers from %s', 'truebe-fact-based-ai-chatbot' ),
				'labelBuildingMatch' => __( 'Building answers from your document', 'truebe-fact-based-ai-chatbot' ),
				'labelUpload'        => __( 'Confirm and upload', 'truebe-fact-based-ai-chatbot' ),
				'labelUploading'     => __( 'Uploading...', 'truebe-fact-based-ai-chatbot' ),
				'labelStart'         => __( 'Uploading your document', 'truebe-fact-based-ai-chatbot' ),
				'badTypeAlert'       => __( 'Truebe only accepts PDF and Word (.docx) documents.', 'truebe-fact-based-ai-chatbot' ),
				'statusQueued'       => __( 'Waiting', 'truebe-fact-based-ai-chatbot' ),
				'statusWorking'      => __( 'Building answers', 'truebe-fact-based-ai-chatbot' ),
				'statusDone'         => __( 'Done', 'truebe-fact-based-ai-chatbot' ),
				'statusFailed'       => __( 'Failed', 'truebe-fact-based-ai-chatbot' ),
				'statusSkipped'      => __( 'Not uploaded', 'truebe-fact-based-ai-chatbot' ),
				'answersBuiltFrom'   => __( 'answers built from', 'truebe-fact-based-ai-chatbot' ),
				'reviewApprove'      => __( 'Review and approve them next.', 'truebe-fact-based-ai-chatbot' ),
				'builtFrom'          => __( 'Built from', 'truebe-fact-based-ai-chatbot' ),
				'reviewApproveYours' => __( 'Review and approve your answers next.', 'truebe-fact-based-ai-chatbot' ),
				/* translators: 1: number of documents processed, 2: total number of documents */
				'summaryDone'        => __( '%1$s of %2$s documents processed.', 'truebe-fact-based-ai-chatbot' ),
				'titleReady'         => __( 'Your answers are ready', 'truebe-fact-based-ai-chatbot' ),
				'titleNone'          => __( 'No documents were processed', 'truebe-fact-based-ai-chatbot' ),
				'uploadFailed'       => __( 'Upload failed', 'truebe-fact-based-ai-chatbot' ),
			)
		);
	}

	public static function allowed_mimes() {
		return array(
			'pdf'  => 'application/pdf',
			'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
		);
	}

	public static function max_upload_bytes() {
		$max = (int) wp_max_upload_size();
		return ( $max > 0 ) ? $max : 20971520;
	}

	/**
	 * Read a single upload field from $_FILES, sanitizing at the point of access.
	 *
	 * @param string $key Field name in $_FILES.
	 * @return array Sanitized entry, or an empty array if the upload is unusable.
	 *               Called only after check_admin_referer() verifies the request origin.
	 */
		public static function read_upload( $key ) {
		// phpcs:ignore WordPress.Security.NonceVerification.Missing -- origin verified by check_admin_referer() in the calling handler before this method runs.
		if ( ! isset( $_FILES[ $key ] ) || ! is_array( $_FILES[ $key ] ) ) {
			return array();
		}

		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.NonceVerification.Missing -- each field is individually unslashed and sanitized below; origin verified by check_admin_referer() in the caller.
		$upload = $_FILES[ $key ];

		$error = isset( $upload['error'] ) ? absint( $upload['error'] ) : UPLOAD_ERR_NO_FILE;
		$size  = isset( $upload['size'] ) ? absint( $upload['size'] ) : 0;
		$name  = isset( $upload['name'] ) ? sanitize_file_name( wp_unslash( $upload['name'] ) ) : '';
		$tmp   = isset( $upload['tmp_name'] ) ? sanitize_text_field( wp_unslash( $upload['tmp_name'] ) ) : '';

		if ( UPLOAD_ERR_OK !== $error ) {
			return array( 'name' => $name, 'type' => '', 'tmp_name' => '', 'error' => $error, 'size' => $size );
		}

		if ( '' === $name || '' === $tmp || ! is_uploaded_file( $tmp ) ) {
			return array();
		}

		if ( $size < 1 || $size > self::max_upload_bytes() ) {
			return array( 'name' => $name, 'type' => '', 'tmp_name' => '', 'error' => UPLOAD_ERR_FORM_SIZE, 'size' => $size );
		}

		$checked = wp_check_filetype( $name, self::allowed_mimes() );
		if ( empty( $checked['ext'] ) || empty( $checked['type'] ) ) {
			return array();
		}

		return array(
			'name'     => $name,
			'type'     => $checked['type'],
			'tmp_name' => $tmp,
			'error'    => UPLOAD_ERR_OK,
			'size'     => $size,
		);
	}

	public static function handle_post() {
		if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( array( 'message' => __( 'Not allowed.', 'truebe-fact-based-ai-chatbot' ) ), 403 ); }
		check_admin_referer( self::ACTION );
		if ( ! self::keys_ready() ) { wp_send_json_error( array( 'message' => __( 'Complete setup in Settings before uploading.', 'truebe-fact-based-ai-chatbot' ) ) ); }
		// phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce verified by check_admin_referer( self::ACTION ) above.
		$attested = isset( $_POST['truebe_public_attested'] ) ? sanitize_text_field( wp_unslash( $_POST['truebe_public_attested'] ) ) : '';
		$atts     = array( 'public_attested' => ( '1' === $attested ) );
		$file     = self::read_upload( 'truebe_document' );
		if ( empty( $file ) ) {
			wp_send_json_error( array( 'message' => __( 'Truebe only accepts PDF and Word (.docx) documents.', 'truebe-fact-based-ai-chatbot' ), 'code' => 'bad_file' ) );
		}
		$result = class_exists( 'Truebe_Documents' ) ? Truebe_Documents::handle_upload( $file, $atts ) : array( 'ok' => false, 'message' => __( 'Document handling is unavailable.', 'truebe-fact-based-ai-chatbot' ) );
		if ( empty( $result['ok'] ) ) {
			wp_send_json_error( array(
				'message' => isset( $result['message'] ) ? $result['message'] : __( 'Upload failed.', 'truebe-fact-based-ai-chatbot' ),
				'code'    => isset( $result['code'] ) ? $result['code'] : '',
			) );
		}
		wp_send_json_success( array( 'job_id' => isset( $result['job_id'] ) ? $result['job_id'] : '' ) );
	}

	public static function keys_ready() {
		if ( ! class_exists( 'Truebe_Setup' ) ) { return false; }
		if ( '' !== Truebe_Setup::get_secret( 'truebe_ai_key' ) ) { return true; }
		return ( null !== Truebe_Setup::detect_wp_ai_provider() );
	}

	public static function render() {
		if ( ! current_user_can( 'manage_options' ) ) { return; }

		if ( ! self::keys_ready() ) {
			?>
			<div class="wrap truebe-settings">
				<h1><?php esc_html_e( 'Upload Documents', 'truebe-fact-based-ai-chatbot' ); ?></h1>
				<div class="truebe-card truebe-gate">
					<p class="truebe-gate-lead"><?php esc_html_e( 'Set up your keys first.', 'truebe-fact-based-ai-chatbot' ); ?></p>
					<p class="truebe-gate-sub"><?php esc_html_e( 'Truebe needs a working AI provider key and an active Truebe account before you can upload documents.', 'truebe-fact-based-ai-chatbot' ); ?></p>
					<a class="truebe-btn truebe-save" href="<?php echo esc_url( admin_url( 'admin.php?page=truebe' ) ); ?>"><?php esc_html_e( 'Go to setup', 'truebe-fact-based-ai-chatbot' ); ?></a>
				</div>
			</div>
			<?php
			return;
		}

		$post   = esc_url( admin_url( 'admin-post.php' ) );
		$review = esc_url( admin_url( 'admin.php?page=truebe-review' ) );
		?>
		<div class="wrap truebe-settings">
			<h1><?php esc_html_e( 'Upload Documents', 'truebe-fact-based-ai-chatbot' ); ?></h1>
			<div class="truebe-progress" id="truebe-progress" style="display:none;margin:0 0 18px;">
				<div class="truebe-progress-label" id="truebe-progress-label"></div>
				<div class="truebe-progress-track"><div class="truebe-progress-fill" id="truebe-progress-fill"></div></div>
			</div>

			<div class="truebe-success" id="truebe-success" style="display:none;">
				<div class="truebe-success-check" aria-hidden="true">&#10003;</div>
				<div class="truebe-success-title" id="truebe-success-title"><?php esc_html_e( 'Your answers are ready', 'truebe-fact-based-ai-chatbot' ); ?></div>
				<div class="truebe-success-sub" id="truebe-success-sub"></div>
				<div class="truebe-success-actions">
					<button type="button" class="truebe-btn truebe-btn-ghost" id="truebe-another"><?php esc_html_e( 'Upload more documents', 'truebe-fact-based-ai-chatbot' ); ?></button>
					<a class="truebe-btn" id="truebe-review-row" href="<?php echo esc_url( $review ); ?>"><?php esc_html_e( 'Review in Fact Library', 'truebe-fact-based-ai-chatbot' ); ?> &rarr;</a>
				</div>
			</div>

			<form method="post" action="<?php echo esc_url( $post ); ?>" enctype="multipart/form-data" id="truebe-upload-form">
				<?php wp_nonce_field( self::ACTION ); ?>
				<input type="hidden" name="action" value="<?php echo esc_attr( self::ACTION ); ?>">
				<input type="hidden" name="truebe_public_attested" value="1">

				<div class="truebe-card" id="truebe-card">
					<div class="truebe-drop" id="truebe-drop">
						<div class="truebe-drop-alert" id="truebe-drop-alert" style="display:none;margin:0 auto 14px;max-width:480px;padding:10px 16px;border-radius:8px;background:#e8f1fc;color:#1d4ed8;text-align:center;"></div>
						<div class="truebe-drop-icon dashicons dashicons-media-document" id="truebe-drop-icon"></div>
						<div class="truebe-drop-title" id="truebe-drop-title"><?php esc_html_e( 'Drop your documents here', 'truebe-fact-based-ai-chatbot' ); ?></div>
						<button type="button" class="truebe-btn truebe-btn-outline" id="truebe-choose"><?php esc_html_e( 'Choose files', 'truebe-fact-based-ai-chatbot' ); ?> &rarr;</button>
						<ul class="truebe-file-list" id="truebe-file-list"></ul>
						<input type="file" name="truebe_document" id="truebe_document" accept=".pdf,.docx,application/pdf,application/vnd.openxmlformats-officedocument.wordprocessingml.document" multiple style="display:none;" />
					</div>

					<div class="truebe-upload-action" id="truebe-upload-action" style="display:none;">
						<button type="submit" class="truebe-btn truebe-save" id="truebe-submit"><?php esc_html_e( 'Confirm and upload', 'truebe-fact-based-ai-chatbot' ); ?></button>
						<p class="truebe-attest-line"><?php esc_html_e( 'By uploading, you confirm these documents', 'truebe-fact-based-ai-chatbot' ); ?><br><?php esc_html_e( 'contain no private or personal data.', 'truebe-fact-based-ai-chatbot' ); ?></p>
					</div>
				</div>
			</form>
		</div>
		<?php
	}
}

Truebe_Admin_Upload::init();