<?php

namespace IGD_PRO;

use IGD\Account;
use IGD\App;
use IGD\Files;

defined( 'ABSPATH' ) || exit();

class PrivateFolders {
	/**
	 * @var null
	 */
	protected static $instance = null;

	public function __construct() {
		// Automatic creates private folders
		if ( igd_get_settings( 'autoPrivateFolders' ) ) {
			add_action( 'user_register', [ $this, 'maybe_create_user_folder' ] );
			add_action( 'gform_user_registered', [ $this, 'maybe_create_user_folder' ] );

			if ( igd_get_settings( 'deleteAutoPrivateFolders', false ) ) {
				add_action( 'delete_user', [ $this, 'delete_user_folder' ] );
			}
		}
	}

	public function maybe_create_user_folder( $user_id ) {
		// Get allowed user roles
		$allowed_user_roles = igd_get_settings( 'privateFolderRoles', [
			'editor',
			'contributor',
			'author',
		] );

		// Check if user role is allowed
		if ( ! in_array( 'all', $allowed_user_roles ) ) {
			$user = get_user_by( 'id', $user_id );

			if ( ! in_array( $user->roles[0], $allowed_user_roles ) ) {
				return;
			}
		}

		$this->create_user_folder( $user_id );
	}

	public function create_user_folder( $user_id = null, $data = [] ) {

		if ( ! $user_id ) {
			$user_id = get_current_user_id();
		}

		$user = get_userdata( $user_id );
		if ( ! $user ) {
			return [];
		}

		@set_time_limit( 60 );

		$name_template   = ! empty( $data['nameTemplate'] ) ? $data['nameTemplate'] : igd_get_settings( 'nameTemplate', '%user_login% (%user_email%)' );
		$parent_folder   = ! empty( $data['parentFolder'] ) ? $data['parentFolder'] : igd_get_settings( 'parentFolder', [] );
		$template_folder = ! empty( $data['templateFolder'] ) ? $data['templateFolder'] : igd_get_settings( 'templateFolder' );
		$merge_folders   = igd_get_settings( 'mergeFolders', true );
		$share_folder    = igd_get_settings( 'sharePrivateFolder' );

		if ( empty( $parent_folder ) ) {
			$parent_folder = [
				'id'        => 'root',
				'accountId' => igd_get_active_account_id(),
			];
		}

		$args = [
			'parent'       => $parent_folder,
			'name'         => $name_template,
			'user'         => $user,
			'mergeFolders' => $merge_folders,
		];

		// Get post to replace the post tags
		if ( igd_contains_tags( 'post', $name_template ) ) {
			$args['post'] = get_post();
		}

		$user_folder = $this->create_folder( $args );

		if ( ! empty( $user_folder ) ) {

			if ( $share_folder ) {
				$user_data = [
					'id'    => $user_id,
					'name'  => $user->display_name ?? $user->user_login,
					'email' => $user->user_email,
				];

				igd_pro_share_file( $user_folder, $user_data );
			}

		}

		update_user_meta( $user_id, 'igd_folders', [ $user_folder ] );

		// Check if the template folder should be copied to the user folder
		if ( ! empty( $template_folder ) ) {

			// Check if the template folder is the same as the parent folder or the template folder and the parent folder not in the same account
			if ( ( $template_folder['id'] != $parent_folder['id'] ) || ( $template_folder['accountId'] == $parent_folder['accountId'] ) ) {
				try {
					$this->copy_folder( $template_folder, $user_folder['id'] );
				} catch ( \Exception $e ) {
					error_log( $e->getMessage() );
				}
			}
		}

		return [ $user_folder ];
	}

	public function copy_folder( $folder, $parent_id ) {

		if ( empty( $folder ) || empty( $parent_id ) ) {
			return false;
		}

		$app = App::instance( $folder['accountId'] );

		$args = [
			'folder' => $folder,
		];

		$data  = $app->get_files( $args );
		$files = ! empty( $data['files'] ) ? $data['files'] : [];

		if ( empty( $files ) ) {
			return false;
		}

		$batch          = new \IGDGoogle_Http_Batch( $app->client );
		$batch_requests = 0;
		$app->client->setUseBatch( true );


		foreach ( $files as $file ) {

			if ( igd_is_dir( $file ) ) {
				//Create new folder in parent folder
				$new_folder = new \IGDGoogle_Service_Drive_DriveFile();
				$new_folder->setName( $file['name'] );
				$new_folder->setMimeType( 'application/vnd.google-apps.folder' );
				$new_folder->setParents( [ $parent_id ] );

				$batch->add( $app->service->files->create( $new_folder, [
					'fields'            => $app->file_fields,
					'supportsAllDrives' => true
				] ), $file['id'] );
			} else {
				// Copy file to new folder
				$new_file = new \IGDGoogle_Service_Drive_DriveFile();
				$new_file->setName( $file['name'] );
				$new_file->setParents( [ $parent_id ] );

				$batch->add( $app->service->files->copy( $file['id'], $new_file, [
					'fields'            => $app->file_fields,
					'supportsAllDrives' => true
				] ), $file['id'] );
			}

			++ $batch_requests;
		}

		// Execute the Batch Call
		try {
			usleep( 20000 * $batch_requests );
			@set_time_limit( 30 );

			$batch_result = $batch->execute();
		} catch ( \Exception $ex ) {
			error_log( '[Integrate Google Drive Message]: ' . sprintf( 'API Error on line %s: %s', __LINE__, $ex->getMessage() ) );

			return false;
		}

		$app->client->setUseBatch( false );

		foreach ( $batch_result as $key => $file ) {

			$file = igd_file_map( $file, $app->account_id );
			Files::add_file( $file );

			if ( igd_is_dir( $file ) ) {
				$original_id   = str_replace( 'response-', '', $key );
				$original_file = array_filter( $files, function ( $item ) use ( $original_id ) {
					return $item['id'] == $original_id;
				} );
				$original_file = array_shift( $original_file );
				$new_id        = $file['id'];

				$this->copy_folder( $original_file, $new_id );
			}
		}
	}

	public function create_folder( $args ) {

		$parent_folder = ! empty( $args['parent'] ) ? $args['parent'] : [
			'id'        => 'root',
			'accountId' => Account::instance()->get_active_account()['id']
		];

		$app         = App::instance( $parent_folder['accountId'] );
		$folder_name = igd_replace_template_tags( $args );

		$merge_folders = ! empty( $args['mergeFolders'] );
		$folder_exist  = false;

		// Check if folder is already exists
		if ( $merge_folders ) {
			$folder_exist = $app->get_file_by_name( $folder_name, $parent_folder['id'], current_user_can( 'manage_options' ) );
		}

		if ( ! $folder_exist ) {
			try {
				return $app->new_folder( $folder_name, $parent_folder['id'] );
			} catch ( \Exception $e ) {
				error_log( $e->getMessage() );

				return [];
			}
		}

		return $folder_exist;
	}

	public function delete_user_folder( $user_id ) {
		$folders = get_user_meta( $user_id, 'igd_folders', true );
		if ( empty( $folders ) ) {
			return;
		}

		$account_id = $folders[0]['accountId'];
		$folder_ids = wp_list_pluck( $folders, 'id' );

		try {
			App::instance( $account_id )->delete( $folder_ids );
		} catch ( \Exception $e ) {
			error_log( $e->getMessage() );

			return;
		}
	}

	/**
	 * @return PrivateFolders|null
	 */
	public static function instance() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

}

PrivateFolders::instance();