<?php
/**
 * Global helper functions for StoryPosts.
 *
 * @package Storyposts
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Check if a specific component is active/present.
 *
 * @since 1.0.4
 * @param string $component The component folder or file name.
 * @param string $type      Optional. The type of check: 'dir' or 'file'. Defaults to 'dir'.
 * @return bool True if the component exists, false otherwise.
 */
function storyposts_component_exists( $component, $type = 'dir' ) {
	$path = STORYPOSTS_PATH . 'includes/' . $component;
	
	if ( 'file' === $type ) {
		return file_exists( $path );
	}

	return is_dir( $path );
}

/**
 * Check if the current user can create a story.
 *
 * @param int $user_id Optional. User ID to check. Defaults to current user.
 * @return bool True if user can create story, false otherwise.
 */
function storyposts_user_can_create_story( $user_id = 0 ) {
	if ( ! $user_id ) {
		$user_id = get_current_user_id();
	}

	// 1. Must be logged in
	if ( ! $user_id ) {
		return false;
	}

	// 2. Must have upload capability (all story types require media uploads)
	// if ( ! user_can( $user_id, 'upload_files' ) ) {
	// 	return false;
	// }

    // 3. Check if user component exists.
    if ( ! storyposts_component_exists( 'user-stories' ) ) {
        return false;
    }

	// 4. "Enable User Stories" setting must be on
	$enabled = Storyposts_Settings::get( 'enable_user_stories', 'on' );
	if ( 'on' !== $enabled ) {
		return false;
	}

	// Default permission is true if all checks pass
	$can_create = true;

	/**
	 * Filter whether a user can create a story.
	 *
	 * @since 1.0.0
	 *
	 * @param bool $can_create Whether the user can create a story.
	 * @param int  $user_id    The user ID being checked.
	 */
	return apply_filters( 'storyposts_user_can_create_story', $can_create, $user_id );
}

/**
 * Check if the current user can view stories.
 *
 * @return bool True if user can view stories, false otherwise.
 */
function storyposts_user_can_view_stories() {
	$enabled = Storyposts_Settings::get( 'enable_user_stories', 'on' );
	
	// If feature is disabled, nobody can view
	if ( 'on' !== $enabled ) {
		return apply_filters( 'storyposts_user_can_view_stories', false );
	}
	
	$require_login = Storyposts_Settings::get( 'require_login_to_view', 'off' );
	$can_view = true;
	
	if ( 'on' === $require_login ) {
		$can_view = is_user_logged_in();
	}
	
	/**
	 * Filter whether a user can view stories.
	 *
	 * @since 1.0.0
	 *
	 * @param bool $can_view Whether the user can view stories.
	 */
	return apply_filters( 'storyposts_user_can_view_stories', $can_view );
}

/**
 * Update the story count for a user.
 * Counts only non-expired, published stories.
 *
 * @param int $user_id User ID to update count for.
 * @return void
 */
function storyposts_update_user_story_count( $user_id ) {
	if ( ! $user_id ) {
		return;
	}

	$current_time = current_time( 'timestamp' );
	$enable_expiry = Storyposts_Settings::get( 'enable_story_expiry', 'off' );

	$args = array(
		'post_type'      => 'stpo_story',
		'post_status'    => 'publish',
		'author'         => $user_id,
		'posts_per_page' => -1,
		'fields'         => 'ids',
	);

	// Build meta query
	$meta_query = array(
		'relation' => 'AND',
		// Only count user stories
		array(
			'key'     => '_story_context',
			'value'   => 'user',
			'compare' => '=',
		),
	);

	// Only filter by expiry if expiry is enabled
	if ( 'on' === $enable_expiry ) {
		$meta_query[] = array(
			'key'     => '_stpo_expire_at',
			'value'   => $current_time,
			'compare' => '>',
			'type'    => 'NUMERIC',
		);
	}

	$args['meta_query'] = $meta_query;

	$query = new WP_Query( $args );
	$count = $query->found_posts;

	update_user_meta( $user_id, '_stpo_story_count', $count );
}

/**
 * Get expired story IDs.
 *
 * @param int $limit Maximum number of stories to return.
 * @return array Array of post IDs.
 */
function storyposts_get_expired_stories( $limit = 50 ) {
	$current_time = current_time( 'timestamp' );

	$args = array(
		'post_type'      => 'stpo_story',
		'post_status'    => 'publish',
		'posts_per_page' => $limit,
		'fields'         => 'ids',
		'meta_query'     => array(
			'relation' => 'AND',
			// Only get user stories (storybook stories have their own lifecycle)
			array(
				'key'     => '_story_context',
				'value'   => 'user',
				'compare' => '=',
			),
			array(
				'key'     => '_stpo_expire_at',
				'value'   => array( 1, $current_time ), // Between 1 and now (excludes 0 = never expires)
				'compare' => 'BETWEEN',
				'type'    => 'NUMERIC',
			),
		),
	);

	$query = new WP_Query( $args );
	return $query->posts;
}

/**
 * Delete a story and its media attachments.
 *
 * @param int $post_id Story post ID.
 * @return void
 */
function storyposts_delete_story_and_media( $post_id ) {
	if ( ! $post_id || get_post_type( $post_id ) !== 'stpo_story' ) {
		return;
	}

	// Get author before deletion
	$author_id = get_post_field( 'post_author', $post_id );

	// Delete media attachments
	$image_id  = get_post_meta( $post_id, '_stpo_image_id', true );
	$video_id  = get_post_meta( $post_id, '_stpo_video_id', true );
	$poster_id = get_post_meta( $post_id, '_stpo_poster_id', true );

	foreach ( array( $image_id, $video_id, $poster_id ) as $media_id ) {
		if ( $media_id ) {
			wp_delete_attachment( $media_id, true );
		}
	}

	// Delete the story post
	wp_delete_post( $post_id, true );

	// Update user's story count
	if ( $author_id ) {
		storyposts_update_user_story_count( $author_id );
	}
}

/**
 * Maybe cleanup expired stories (throttled).
 * Runs once per hour maximum.
 *
 * @return void
 */
function storyposts_maybe_cleanup_expired_stories() {
	// Only run if expiry is enabled
	$enable_expiry = Storyposts_Settings::get( 'enable_story_expiry', 'off' );
	if ( 'on' !== $enable_expiry ) {
		return;
	}

	// Throttle: Only check once per hour
	$last_check = get_transient( 'storyposts_last_cleanup_check' );
	if ( $last_check ) {
		return; // Too soon
	}

	// Find expired stories (batch of 50)
	$expired = storyposts_get_expired_stories( 50 );

	if ( empty( $expired ) ) {
		// No expired stories, set transient and return
		set_transient( 'storyposts_last_cleanup_check', true, HOUR_IN_SECONDS );
		return;
	}

	// Delete expired stories
	foreach ( $expired as $post_id ) {
		storyposts_delete_story_and_media( $post_id );
	}

	// Set transient to prevent running again for an hour
	set_transient( 'storyposts_last_cleanup_check', true, HOUR_IN_SECONDS );
}

/**
 * Load a StoryPosts template partial.
 *
 * @param string $slug Partial slug (without .php).
 * @param array  $args Optional. Arguments to pass to the template.
 * @return void
 */
function storyposts_get_template_part( $slug, $args = [] ) {
	if ( ! empty( $args ) ) {
		extract( $args );
	}

	$file = STORYPOSTS_PATH . 'public/partials/' . $slug . '.php';
	
	/**
	 * Filter the template file path.
	 * 
	 * @param string $file The template file path.
	 * @param string $slug The template slug.
	 */
	$file = apply_filters( 'storyposts_get_template_part', $file, $slug );

	if ( file_exists( $file ) ) {
		include $file;
	}
}

/**
 * Render components shared across all sliders (modals).
 *
 * @return void
 */
function storyposts_render_modals( $type = '' ) {
	static $modals_rendered = false;
	static $upload_modals_rendered = false;

	if ( ! $modals_rendered ) {
		storyposts_get_template_part( 'story-modal' );
		$modals_rendered = true;
	}

	if ( 'users' === $type && ! $upload_modals_rendered && storyposts_user_can_create_story() ) {
		storyposts_get_template_part( 'story-upload-modal' );
		$upload_modals_rendered = true;
	}
}


