<?php

namespace FileBird\Controller;

defined( 'ABSPATH' ) || exit;

use FileBird\Model\Folder as FolderModel;

class SyncController {
	public function exportCSV( \WP_REST_Request $request ) {
		if ( ! current_user_can( 'manage_options' ) ) {
			return new \WP_Error( 
				'rest_forbidden', 
				__( 'Sorry, you are not allowed to export CSV.', 'filebird' ), 
				array( 'status' => rest_authorization_required_code() ) 
			);
		}
		$id = $request->get_param( 'id' );
		if ( ! empty( $id ) ) {
			$folders = get_option( 'filebird_backup_' . $id, array() );
		} else {
			$folders = FolderModel::exportAll();
		}
		return new \WP_REST_Response( array( 'folders' => $folders ) );
	}

	/**
	 * Parse the uploaded CSV file.
	 *
	 * @return array|\WP_Error Rows on success, WP_Error on any failure.
	 */
    public function readCSV( \WP_REST_Request $request ) {
		$params = $request->get_file_params();

		if ( empty( $params['file'] ) || ! isset( $params['file']['tmp_name'] ) ) {
			return new \WP_Error(
				'fbv_no_file',
				__( 'No file was uploaded. Please choose a CSV file and try again.', 'filebird' ),
				array( 'status' => 400 )
			);
		}

		if ( isset( $params['file']['error'] ) && UPLOAD_ERR_OK !== $params['file']['error'] ) {
			return new \WP_Error(
				'fbv_upload_error',
				__( 'The file could not be uploaded. Please try again.', 'filebird' ),
				array( 'status' => 400 )
			);
		}

		if ( ! is_uploaded_file( $params['file']['tmp_name'] ) ) {
			return new \WP_Error(
				'fbv_invalid_upload',
				__( 'The uploaded file is not valid.', 'filebird' ),
				array( 'status' => 400 )
			);
		}

		$handle = \fopen( $params['file']['tmp_name'], 'r' );

		if ( false === $handle ) {
			return new \WP_Error(
				'fbv_unreadable_file',
				__( 'The uploaded file could not be read. Please try again.', 'filebird' ),
				array( 'status' => 400 )
			);
		}

		$data    = array();
		$columns = array();
		$count   = 1;
		while ( 1 ) {
			$row = fgetcsv( $handle, 0, ',', '"', '\\' );
			if ( false === $row || null === $row ) {
				break;
			}
			if ( 1 === $count ) {
				$columns = $row;
				$count++;
				continue;
			}
			$tmp = array();
			foreach ( $columns as $key => $col ) {
				$tmp[ $col ] = isset( $row[ $key ] ) ? $row[ $key ] : '';
			}
			$data[] = $tmp;
		}
		\fclose( $handle );

		$check = array_diff(
			$columns,
			array(
				'id',
				'name',
				'parent',
				'type',
				'ord',
				'created_by',
				'attachment_ids',
				'post_type'
			)
		);

		$required = array_diff( array( 'id', 'name', 'parent', 'created_by' ), $columns );

		if ( count( $check ) > 0 || count( $required ) > 0 ) {
			return new \WP_Error(
				'fbv_invalid_csv',
				__( 'The uploaded file was not generated by FileBird. Please check again.', 'filebird' ),
				array( 'status' => 400 )
			);
		}

		return $data;
	}

    public function restoreFolderStructure( $folders ) {
		$attachment_folders = array();
		$post_type_folders  = array();
		foreach ( $folders as $folder ) {
			$post_type = $folder['post_type'] ?? 'attachment';
			if ( $post_type == 'attachment' ) {
				$attachment_folders[] = $folder;
			} else {
				$post_type_folders[] = $folder;
			}
		}

		// Import attachment folders
		$tree                             = $this->buildTree( $attachment_folders );
        $folders_created_attachment       = $this->run_import_folders( $tree );

		// Import post type folders
		$tree                             = $this->buildTree( $post_type_folders );
		$folders_created_post_type        = $this->run_import_post_type_folders( $tree );

		// $folders_created = array_merge( $folders_created_attachment, $folders_created_post_type );
		// $mess = sprintf( __( 'Congratulations! We imported successfully %d folders into <strong>FileBird.</strong>', 'filebird' ), count( $folders_created ) );

		return __( 'Congratulations! Your folders have been imported into <strong>FileBird</strong>.', 'filebird' );
	}

    public function buildTree( array &$data, $parentId = 0 ) {
		$tree = array();
		foreach ( $data as &$node ) {
			if ( $node['parent'] == $parentId ) {
				$children = $this->buildTree( $data, $node['id'] );
				if ( $children ) {
					$node['children'] = $children;
				}
				$tree[] = $node;
				unset( $node );
			}
		}
		return $tree;
	}

	public function run_import_folders( $folders, $parent = 0 ) {
        $folders_created = array();

		usort(
			$folders,
			function( $folder1, $folder2 ) {
				return intval( $folder1['ord'] ) > intval( $folder2['ord'] ) ? 1 : -1;
			}
		);

		foreach ( $folders as $folder ) {
			$new_folder     = FolderModel::newOrGet( $folder['name'], $parent );
			$attachment_ids = ! empty( $folder['attachment_ids'] ) ? explode( '|', $folder['attachment_ids'] ) : false;
            array_push( $folders_created, $folder['id'] );

			if ( $attachment_ids && false !== $new_folder ) {
				FolderModel::setFoldersForPosts( $attachment_ids, $new_folder['id'] );
			}

			if ( isset( $folder['children'] ) && count( $folder['children'] ) > 0 ) {
				$new_child_folders = $this->run_import_folders( $folder['children'], $new_folder['id'] );
				$folders_created   = array_merge( $folders_created, $new_child_folders );
			}
		}

		return $folders_created;
    }
	public function run_import_post_type_folders( $folders, $parent = 0 ) {
		$folders_created = array();

		usort(
			$folders,
			function( $folder1, $folder2 ) {
				return intval( $folder1['ord'] ) > intval( $folder2['ord'] ) ? 1 : -1;
			}
		);
		$all_terms = array();

		foreach ( $folders as $folder ) {
			//Create new term at fbv_pt_tax_$folder['post_type'] taxonomy if not exist, if exist, get term
			$term = false;
			if( ! isset( $all_terms[$folder['post_type'] . '_' . $parent] ) ) {
				$all_terms[$folder['post_type'] . '_' . $parent] = get_terms(array(
					'taxonomy' => 'fbv_pt_tax_' . $folder['post_type'],
					'parent' => $parent,
					'hide_empty' => false
				));
			}
			
			foreach ($all_terms[$folder['post_type'] . '_' . $parent] as $t) {
				if ($t->name === $folder['name']) {
					$author = get_term_meta( $t->term_id, 'fbv_author', true );
					if( $author == $folder['created_by'] ) {
						$term = (array)$t;
						break;
					}
				}
			}
			if ( ! $term ) {
				$term = wp_insert_term( $folder['name'], 'fbv_pt_tax_' . $folder['post_type'], array(
					'parent' => $parent
				) );
				update_term_meta( $term['term_id'], 'fbv_author', $folder['created_by'] );
				update_term_meta( $term['term_id'], 'fbv_tax_order', $folder['ord'] );
			}
			$folders_created[] = $term['term_id'];

			$attachment_ids = ! empty( $folder['attachment_ids'] ) ? explode( '|', $folder['attachment_ids'] ) : false;
			if ( $attachment_ids !== false && $term !== false ) {
				foreach ( $attachment_ids as $attachment_id ) {
					wp_set_object_terms( $attachment_id, $term['term_id'], 'fbv_pt_tax_' . $folder['post_type'] );
				}
			}

			if ( isset( $folder['children'] ) && count( $folder['children'] ) > 0 ) {
				$new_child_folders = $this->run_import_post_type_folders( $folder['children'], $term['term_id'] );
				$folders_created   = array_merge( $folders_created, $new_child_folders );
			}
		}
		return $folders_created;
	}

    public function importCSV( \WP_REST_Request $request ) {
		if ( ! current_user_can( 'manage_options' ) ) {
			return new \WP_Error( 
				'rest_forbidden', 
				__( 'Sorry, you are not allowed to import CSV.', 'filebird' ), 
				array( 'status' => rest_authorization_required_code() ) 
			);
		}
		$data = $this->readCSV( $request );

		if ( is_wp_error( $data ) ) {
			return $data;
		}

		$createdBy = intval( $request->get_param( 'userId' ) );

		if ( $createdBy != '-1' ) {
			$data = array_filter(
                $data,
                function( $item ) use ( $createdBy ) {
				return $item['created_by'] == $createdBy;
				}
                );
		}

		if ( empty( $data ) ) {
			return new \WP_Error(
				'fbv_no_folders',
				__( 'There are no folders to import in the uploaded file.', 'filebird' ),
				array( 'status' => 400 )
			);
		}

		$mess = $this->restoreFolderStructure( $data );

		return new \WP_REST_Response(
			array(
				'success' => true,
				'message' => $mess,
			)
		);
	}

	public function getImportCSVDetail( \WP_REST_Request $request ) {
		if ( ! current_user_can( 'manage_options' ) ) {
			return new \WP_Error( 
				'rest_forbidden', 
				__( 'Sorry, you are not allowed to get import CSV detail.', 'filebird' ), 
				array( 'status' => rest_authorization_required_code() ) 
			);
		}
		$data = $this->readCSV( $request );

		if ( is_wp_error( $data ) ) {
			return $data;
		}

		$authors = array_filter( array_unique( array_column( $data, 'created_by' ) ), 'is_numeric' );

		$users = empty( $authors ) ? array() : \get_users(
            array(
				'include' => $authors,
			)
            );

		$usersReturn = array();

		foreach ( $users as $user ) {
			$usersReturn[ $user->ID ] = $user->data->display_name . ' ' . __( 'folders', 'filebird' );
		}

		return new \WP_REST_Response( $usersReturn );
	}
}
