<?php

/********************************************************************
 * Copyright (C) 2025 Hassine RIANI (https://upvimeo.com)
 *
 * This file is part of Upvimeo
 *
 * Upvimeo is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * Upvimeo is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Upvimeo. If not, see <https://www.gnu.org/licenses/>.
 **********************************************************************/

/**
 * Class UpVimeo_Db_Base
 *
 * Responsible for communicating with the database
 *
 * @license GPLv2
 * @copyright Hassine RIANI (https://upvimeo.com)
 * @since 1.9.2
 */
class UpVimeo_Db_Base
{

	const POST_TYPE_UPLOADS = 'upvimeo-upload';

	/**
	 * The WPDB Instance
	 * @var wpdb
	 */
	protected $db;

	/**
	 * UpVimeo_Db_Helper constructor.
	 */
	public function __construct()
	{
		global $wpdb;
		$this->db = &$wpdb;
	}

	/**
	 * Return all the vimeo videos from the local database.
	 *
	 * @param  array  $args
	 * @param  string  $type
	 *
	 * @return int[]|WP_Post[]|WP_Query
	 */
	public function get_videos($args = array(), $type = 'items')
	{
		$params = array(
			'post_type' => self::POST_TYPE_UPLOADS,
			'posts_per_page' => isset($args['number']) ? $args['number'] : -1,
			'offset' => isset($args['offset']) ? $args['offset'] : 0,
			'post_status' => 'publish'
		);
		if (isset($args['author'])) {
			$params['author'] = $args['author'];
		}
		if (isset($args['s'])) {
			$params['s'] = $args['s'];
		}

		if ('items' === $type) {
			$result = get_posts($params);
		} else {
			$result = new WP_Query($params);
		}

		return $result;
	}

	/**
	 * Return total videos count
	 * @return string|null
	 */
	public function get_videos_count($args)
	{
		$cache_key = 'upvimeo_videos_count_' . md5(serialize($args));
		$count = wp_cache_get($cache_key, 'upvimeo_plugin');

		if (false === $count) {
			$query = $this->db->prepare("SELECT COUNT(*) FROM {$this->db->posts} P WHERE P.post_status='publish' AND P.post_type=%s", self::POST_TYPE_UPLOADS);
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			$count = $this->db->get_var($query);
			wp_cache_set($cache_key, $count, 'upvimeo_plugin', 3600);
		}

		return $count;
	}

	/**
	 * Return the vimeo uri for specific local vimeo video.
	 *
	 * @param $post_id
	 *
	 * @return mixed
	 */
	public function get_vimeo_uri($post_id)
	{
		$response = $this->get_vimeo_id($post_id);

		return $response ? upvimeo_id_to_uri($response) : $response;
	}

	/**
	 * Return the vimeo video id for specific local vimeo video.
	 *
	 * @param $post_id
	 * @param  int
	 *
	 * @return mixed
	 */
	public function get_vimeo_id($post_id)
	{
		$vimeo_id = get_post_meta($post_id, 'UPVIMEO_response', true);
		if ($vimeo_id) {
			$vimeo_id = str_replace('/videos/', '', $vimeo_id);
		}

		return $vimeo_id;
	}

	/**
	 * Returns local vimeo video post id.
	 *
	 * @param $vimeo_uri_or_id
	 *
	 * @return string|null
	 */
	public function get_post_id($vimeo_uri_or_id)
	{
		$vimeo_id = upvimeo_uri_to_id($vimeo_uri_or_id); // Ensure id.
		$cache_key = 'upvimeo_post_id_' . $vimeo_id;
		$post_id = wp_cache_get($cache_key, 'upvimeo_plugin');

		if (false === $post_id) {
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			$post_id = $this->db->get_var($this->db->prepare(
				"SELECT post_id FROM {$this->db->postmeta} PM WHERE PM.meta_key='UPVIMEO_response' AND PM.meta_value='%s'",
				$vimeo_id
			));

			if ($post_id) {
				wp_cache_set($cache_key, $post_id, 'upvimeo_plugin', 3600);
			}
		}

		return $post_id;
	}

	/**
	 * Return vimeo link
	 *
	 * @param $post_id
	 *
	 * @return mixed|string
	 */
	public function get_vimeo_link($post_id)
	{
		$vimeo_link = get_post_meta($post_id, 'UPVIMEO_link', true);
		if (empty($vimeo_link)) {
			$vimeo_id = $this->get_vimeo_id($post_id);
			$vimeo_link = sprintf('https://vimeo.com/%s', $vimeo_id);
		}

		return $vimeo_link;
	}

	/**
	 * Returns the local video
	 *
	 * @param $title
	 * @param $description
	 * @param $vimeo_id  - (eg. 18281821)
	 * @param  string  $context
	 *
	 * @return int|WP_Error
	 */
	public function create_local_video($title, $description, $vimeo_id, $context = 'admin')
	{

		$vimeo_id = upvimeo_uri_to_id($vimeo_id);

		// Do not create local video if it already exists.
		$postID = $this->get_post_id($vimeo_id);
		if (!empty($postID)) {
			return (int) $postID;
		}

		$args = array(
			'post_title' => wp_strip_all_tags($title),
			'post_content' => wp_strip_all_tags($description),
			'post_status' => 'publish',
			'post_type' => self::POST_TYPE_UPLOADS,
			'post_author' => is_user_logged_in() ? get_current_user_id() : 0,
		);

		$args = apply_filters('UPVIMEO_insert_video_args', $args, $context); // Deprecated.
		$args = apply_filters('UPVIMEO_before_create_local_video_params', $args, $vimeo_id, $context);

		$postID = wp_insert_post($args);

		if (!is_wp_error($postID)) {
			update_post_meta($postID, 'UPVIMEO_response', $vimeo_id);
		}

		update_post_meta($postID, 'UPVIMEO_context', $context);

		do_action('UPVIMEO_created_local_video', $postID);

		return $postID;
	}

	/**
	 * Deletes a local video
	 *
	 * @param $post_id
	 *
	 * @return array|false|WP_Post|null
	 */
	public function delete_local_video($post_id)
	{
		return wp_delete_post($post_id, true);
	}

	/**
	 * Check for uploads
	 *
	 * @param  bool  $current_user_uploads_only
	 *
	 * @return array
	 */
	public function get_uploaded_videos($current_user_uploads_only = false)
	{
		$uploads_formatted = wp_cache_get('upvimeo_uploads_formatted');
		if (false === $uploads_formatted) {
			$params = array();
			if ($current_user_uploads_only) {
				$params['author'] = get_current_user_id();
			}
			$params = apply_filters('UPVIMEO_uploaded_videos_query_args', $params);
			$uploads = $this->get_videos($params);
			$uploads_formatted = array();
			foreach ($uploads as $_upload) {
				$uploads_formatted[] = array(
					'title' => $_upload->post_title,
					'upvimeo_id' => $this->get_vimeo_id($_upload->ID),
					'ID' => $_upload->ID
				);
			}
			wp_cache_set('upvimeo_uploads_formatted', $uploads_formatted);
		}

		return $uploads_formatted;
	}

	/**
	 * Set the video metadata.
	 *
	 * @param $post_id
	 * @param $metadata
	 *
	 * @return void
	 *
	 * @since 1.9.2
	 */
	public function set_metadata($post_id, $metadata)
	{
		foreach ($metadata as $key => $value) {
			update_post_meta($post_id, $key, $value);
		}
		update_post_meta($post_id, 'UPVIMEO_last_sync_at', time());
	}

	/**
	 * Returns the total uploaded size
	 * @return int
	 */
	public function get_total_uploaded_size($args = [])
	{
		global $wpdb;

		$cache_key = 'upvimeo_total_size_' . md5(serialize($args));
		$size = wp_cache_get($cache_key, 'upvimeo_plugin');

		if (false === $size) {
			if (!empty($args['author'])) {
				// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
				$size = (int) $wpdb->get_var($wpdb->prepare(
					"SELECT SUM(PM.meta_value) FROM {$wpdb->posts} P, {$wpdb->postmeta} PM WHERE P.ID=PM.post_id AND PM.meta_key='UPVIMEO_size' AND P.post_author=%d",
					(int) $args['author']
				));
			} else {
				// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
				$size = (int) $wpdb->get_var($wpdb->prepare("SELECT SUM(PM.meta_value) FROM {$wpdb->posts} P, {$wpdb->postmeta} PM WHERE P.ID=PM.post_id AND PM.meta_key=%s", 'UPVIMEO_size'));
			}

			wp_cache_set($cache_key, $size, 'upvimeo_plugin', 3600);
		}

		return $size;
	}
}
