<?php
namespace Fabrica\Dashboard;

if (!defined('WPINC')) { die(); }

require_once('base.php');

class MediaBreakdown {
	public static function init() {
		add_action('wp_dashboard_setup', array(__CLASS__, 'register'));
		add_action('wp_ajax_fd-media-breakdown', array(__CLASS__, 'displayAjax'));
		add_filter('post_mime_types', array(__CLASS__, 'filterPostMimeTypes'));
	}

	// Add filters to the Media library so we can link directly there
	public static function filterPostMimeTypes($types) {
		$mimes = get_allowed_mime_types();
		foreach ($mimes as $mime => $data) {
			$types[$data] = array(str_replace('|', ' / ', $mime));
		}
		return $types;
	}

	// Register
	public static function register() {
		add_meta_box('fd_media_breakdown', 'Media Breakdown', array(__CLASS__, 'displayWrapper'), 'dashboard', 'normal', 'high');
	}

	// Update parameters supplied by AJAX and return new output
	public static function displayAjax() {
		header('Content-Type: text/html');

		// Check + set user filter + display requested results accordingly
		if (isset($_POST['data']['filter']) && $_POST['data']['filter'] === 'true') {
			update_user_meta(Base::$currentUser->ID, 'fd-media-breakdown-user-filter', true);
			self::displayUserOnly();
		} else {
			update_user_meta(Base::$currentUser->ID, 'fd-media-breakdown-user-filter', false);
			self::displaySitewide();
		}
		exit;
	}

	// Display wrapper with filter switch
	public static function displayWrapper() {
		if (Base::$isEditor && Base::$totalUsers > 1) {
			?><div class="fd-util-center fd-util-margin-bottom"><?php
				esc_html_e("Show", Base::$textDomain); ?>: <strong><?php esc_html_e("files on server", Base::$textDomain); ?>&nbsp;</strong>
				<input type="checkbox" class="fd-toggle fd-ajaxSwitch" data-ajax-action="fd-media-breakdown" id="fd-media-breakdown-user-filter" name="fd-media-breakdown-user-filter" value="1" <?php if (get_user_meta(Base::$currentUser->ID, 'fd-media-breakdown-user-filter', true) === '1') echo 'checked'; ?>>
				<label class="fd-toggleButton" for="fd-media-breakdown-user-filter"></label>
				<strong>&nbsp;<?php esc_html_e("your uploads", Base::$textDomain); ?></strong>
			</div><?php
		}
		if (!Base::$isEditor || (Base::$isEditor && get_user_meta(Base::$currentUser->ID, 'fd-media-breakdown-user-filter', true) === '1')) {
			self::displayUserOnly();
		} else {
			self::displaySitewideEmpty();
		}
	}

	// Display Sitewide 'empty' (actual info is always loaded via AJAX, even when initial view, in case of a lag while crunching files)
	public static function displaySitewideEmpty() {
		?><table class="wp-list-table widefat striped fd-ajaxLoad fd-util-normal-table" id="fd-media-breakdown" data-ajax-action="fd-media-breakdown">
			<tbody>
				<tr><td><?php esc_html_e("Loading", Base::$textDomain); ?>...</td></tr>
			</tbody>
		</table><?php
	}

	// Display Sitewide full info (always called by AJAX)
	private static function displaySitewide() {

		// Traverse folders recursively and look for files with the given extensions
		$uploadDir = wp_upload_dir();
		$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($uploadDir['basedir'], \RecursiveDirectoryIterator::SKIP_DOTS));

		// Update stats
		$media = array('images' => array(), 'other' => array());
		$mimes = get_allowed_mime_types();
		foreach ($files as $file) {
			$filename = $file->getPathname();
			$extension = $file->getExtension();

			// Check what is the file type and if it is among those permitted in WordPress
			$mimetype = false;
			foreach ($mimes as $extensions => $mime) {
				if (preg_match('/^(' . $extensions . ')$/', $extension)) {
					$mimetype = current(explode('/', $mime));
					break;
				}
			}
			if ($mimetype == 'image') {
				$table = 'images';
				if (!array_key_exists($extension, $media[$table])) {
					$media[$table][$extension] = array('original' => 0, 'resized' => 0, 'weight' => 0, 'last' => 0, 'mimetype' => $mime);
				}

				// Determine if image is original or resized through the filename format
				if (preg_match('/^(.*)-\d+x\d.*\.(\S+)$/', $filename, $matches) && file_exists($matches[1] . '.' . $matches[2])) {
					$media[$table][$extension]['resized']++;
				} else {
					$media[$table][$extension]['original']++;
				}
			} else {
				$table = 'other';
				if (!array_key_exists($extension, $media[$table])) {
					$media[$table][$extension] = array('original' => 0, 'weight' => 0, 'last' => 0, 'allowed' => ($mimetype != false), 'mimetype' => $mime);
				}
				$media[$table][$extension]['original']++;
			}

			$media[$table][$extension]['weight'] += filesize($filename);
			$fileDate = filemtime($filename);
			if ($fileDate > $media[$table][$extension]['last']) {
				$media[$table][$extension]['last'] = $fileDate;
			}
		}

		// Render
		?><div id="fd-media-breakdown" data-ajax-replace="fd-media-breakdown">
			<table class="wp-list-table widefat striped fd-util-normal-table fd-util-margin-bottom">
				<thead>
					<th><?php esc_html_e("Image format", Base::$textDomain); ?></th>
					<th class="fd-util-right"><?php esc_html_e("Originals", Base::$textDomain); ?></th>
					<th class="fd-util-right"><?php esc_html_e("Resized", Base::$textDomain); ?></th>
					<th class="fd-util-right"><?php esc_html_e("Weight", Base::$textDomain); ?></th>
					<th class="fd-util-right"><span class="fd-media-breakdown-col-icon dashicons dashicons-clock" title="<?php esc_attr_e("Updated", Base::$textDomain); ?>"></span><span class="fd-media-breakdown-col-label"><?php esc_html_e("Updated", Base::$textDomain); ?></span></th>
				</thead>
				<tbody><?php
					if (count($media['images']) == 0) {
						?><tr><td colspan="5"><?php esc_html_e("There are no image files in the uploads folder.", Base::$textDomain); ?></td></tr><?php
					} else {
						foreach ($media['images'] as $extension => $row) {
							?><tr>
								<td><a href="<?php echo esc_attr(admin_url('upload.php?mode=list&attachment-filter=post_mime_type%3A' . urlencode($row['mimetype']))); ?>"><?php echo esc_html($extension); ?></a></td>
								<td class="fd-util-right"><?php echo esc_html(Base::z2d($row['original'])); ?></td>
								<td class="fd-util-right"><?php echo esc_html(Base::z2d($row['resized'])); ?></td>
								<td class="fd-util-right"><?php echo esc_html(Base::formatSize($row['weight'])); ?></td>
								<td class="fd-util-right"><?php echo $row['last'] > 0 ? wp_kses_post(Base::ago($row['last'])) : ''; ?></td>
							</tr><?php
						}
					}
				?></tbody>
			</table>
			<table class="wp-list-table widefat striped fd-util-normal-table">
				<thead>
					<th><?php esc_html_e("Other files", Base::$textDomain); ?></th>
					<th class="fd-util-right"><?php esc_html_e("Number", Base::$textDomain); ?></th>
					<th class="fd-util-right"><?php esc_html_e("Total weight", Base::$textDomain); ?></th>
					<th class="fd-util-right"><span class="fd-media-breakdown-col-icon dashicons dashicons-clock" title="<?php esc_attr_e("Updated", Base::$textDomain); ?>"></span><span class="fd-media-breakdown-col-label"><?php esc_html_e("Updated", Base::$textDomain); ?></span></th>
				</thead>
				<tbody><?php
					if (count($media['other']) == 0) {
						?><tr><td colspan="4"><?php esc_html_e("There are no other files in the uploads folder.", Base::$textDomain); ?></td></tr><?php
					} else {
						foreach ($media['other'] as $extension => $row) {
							?><tr>
								<td><?php
									if (trim($extension) == '') {
										$extension = '<em>' . __("no file extension", Base::$textDomain) . '</em>';
									}
									if (!$row['allowed']) {
										?><span class="dashicons dashicons-warning fd-util-red" title="<?php esc_attr_e("File type not allowed in WordPress", Base::$textDomain); ?>"></span> <?php
										echo esc_html($extension);
									} else {
										?><a href="<?php echo esc_url(admin_url('upload.php?mode=list&attachment-filter=post_mime_type%3A' . urlencode($row['mimetype']))); ?>"><?php
										echo esc_html($extension);
										?></a><?php
									}
								?></a></td>
								<td class="fd-util-right"><?php echo esc_html(Base::z2d($row['original'])); ?></td>
								<td class="fd-util-right"><?php echo esc_html(Base::formatSize($row['weight'])); ?></td>
								<td class="fd-util-right"><?php echo $row['last'] > 0 ? wp_kses_post(Base::ago($row['last'])) : ''; ?></td>
							</tr><?php
						}
					}
				?></tbody>
			</table>
		</div><?php
	}

	private static function displayUserOnlyTable($files, $noFilesMessage = '', $classNames = '') { ?>
		<table class="wp-list-table widefat striped fd-util-normal-table <?php echo esc_attr($classNames) ?>">
			<thead>
				<th><?php esc_html_e("Image format", Base::$textDomain); ?></th>
				<th class="fd-util-right"><?php esc_html_e("Count", Base::$textDomain); ?></th>
				<th class="fd-util-right"><?php esc_html_e("Last upload", Base::$textDomain); ?></th>
			</thead>
			<tbody><?php
				if (empty($files)) {
					?><tr><td colspan="3"><?php esc_html_e($noFilesMessage, Base::$textDomain); ?></td></tr><?php
				} else {
					foreach ($files as $extensions => $row) {
						?><tr>
							<td><a href="<?php echo esc_url(admin_url('upload.php?mode=list&attachment-filter=post_mime_type%3A' . urlencode($row['mimetype']))); ?>"><?php echo esc_html($extensions); ?></a></td>
							<td class="fd-util-right"><?php echo esc_html(Base::z2d($row['original'])); ?></td>
							<td class="fd-util-right"><?php echo $row['last'] > 0 ? wp_kses_post(Base::ago($row['last'])) : '-'; ?></td>
						</tr><?php
					}
				}
			?></tbody>
		</table><?php
	}

	// Display user only info
	private static function displayUserOnly() {

		// Get user's uploaded filetypes and counts for each
		global $wpdb;
		$query = $wpdb->prepare('SELECT post_mime_type, COUNT(post_mime_type) as count FROM ' . Base::$dbPrefix . 'posts WHERE post_type = \'attachment\' AND post_author = %s GROUP BY post_mime_type', Base::$currentUser->ID);
		$results = $wpdb->get_results($query, OBJECT_K);

		// Update stats
		$media = array('images' => array(), 'other' => array());
		$mimes = get_allowed_mime_types();
		foreach ($results as $mime => $data) {

			// Look up this mime type in the allowed list
			$extensions = array_search($mime, $mimes);
			if (!$extensions) { // Should never happen since uploads in DB must be in allowed list
				continue;
			}

			// Replace pipes with commas for extension groups for human readability
			$extensions = str_replace('|', ' / ', $extensions);

			// Image or other?
			$mimetype = current(explode('/', $mime));
			if ($mimetype == 'image') {
				$table = 'images';
			} else {
				$table = 'other';
			}

			// Get latest upload for this type
			$lastUploadDate = 0;
			$query = $wpdb->prepare('SELECT ID, post_date FROM ' . Base::$dbPrefix . 'posts WHERE post_type = \'attachment\' AND post_author = %s AND post_mime_type = %s ORDER BY post_date DESC LIMIT 1', Base::$currentUser->ID, $mime);
			$results = $wpdb->get_results($query, OBJECT_K);
			if ($results) { // There should always be a result because the query is based on data returned by the previous one, but just in case of an error:
				$lastUpload = current($results);
				$lastUploadDate = strtotime($lastUpload->post_date);
			}

			// Create row for this mimetype
			$media[$table][$extensions] = array('original' => $data->count, 'last' => $lastUploadDate, 'mimetype' => $data->post_mime_type);
		}

		// Render
		?><div id="fd-media-breakdown" data-ajax-replace="fd-media-breakdown"><?php
			self::displayUserOnlyTable($media['images'], 'You currently have no image uploads.', 'fd-util-margin-bottom');
			self::displayUserOnlyTable($media['other'], 'You currently have no other file uploads.'); ?>
		</div><?php
	}
}
MediaBreakdown::init();
