<?php
/**
 * Grieg CLI
 *
 * @package Nisje
 */

declare( strict_types=1 );

namespace Dekode\Nisje\Commands;

use WP_CLI;
use Exception;
use StdClass;
use WP_Post;

if ( class_exists( 'WP_CLI' ) ) {
	/**
	 * Grieg functionality
	 */
	class Grieg {
		/**
		 * Users
		 *
		 * @var array
		 */
		private $users = [];

		/**
		 * Group mapping
		 *
		 * @var array
		 */
		private $group_mappings = [];

		/**
		 * Populate data
		 */
		private function populate_data() {
			$this->populate_users();
			$this->populate_group_companies();
		}

		/**
		 * Populate users.
		 */
		private function populate_users() {
			$file = dirname( __FILE__ ) . '/import/users.json';
			if ( file_exists( $file ) ) {
				$content     = file_get_contents( $file ); // phpcs:ignore
				$this->users = json_decode( $content, true );
			}
		}

		/**
		 * Populate group companies relation.
		 */
		private function populate_group_companies() {
			$file = dirname( __FILE__ ) . '/import/group_mappings.json';
			if ( file_exists( $file ) ) {
				$content              = file_get_contents( $file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
				$this->group_mappings = json_decode( $content, true );
			}
		}

		/**
		 * This function is run on the command "wp grieg import_companies"
		 */
		public function import_companies() {
			$file = dirname( __FILE__ ) . '/import/companies.json';
			if ( file_exists( $file ) ) {
				$content = file_get_contents( $file ); // phpcs:ignore
				$companies = json_decode( $content, true );

				foreach ( $companies as  $company ) {
					$groups = groups_get_groups( [
						'meta_query'  => [ // phpcs:ignore
							[
								'key'     => '_id_in_remote',
								'value'   => $company['ID'],
								'compare' => '=',
							],
						],
					] );

					if ( empty( $groups['groups'] ) ) {
						$group_args = [
							'creator_id'  => 1,
							'name'        => $company['title'],
							'description' => ' ',
							'status'      => 'private',
						];

						$group_id = groups_create_group( $group_args );

						if ( ! $group_id ) {
							return;
						}

						groups_update_groupmeta( $group_id, '_id_in_remote', $company['ID'] );

						WP_CLI::line( $company['title'] . ' added' );
					} else {
						$group_id = $groups['groups'][0]->id;
						WP_CLI::line( $company['title'] . ' exists' );
					}

					$users = get_users( [
						'meta_key'     => 'company_id',  // phpcs:ignore
						'meta_value'   => $company['ID'],  // phpcs:ignore
						'meta_compare' => '=',
						'number'       => 999,
					] );

					WP_CLI::line( count( $users ) . ' in ' . $company['title'] . ' - ' . $group_id );

					foreach ( $users as $user ) {
						groups_join_group( $group_id, $user->data->ID );
						WP_CLI::line( $user->data->ID . ' joined group ' . $group_id );
						update_user_meta( $user->data->ID, 'main_group', $group_id );
					}
				}
			}
		}

		/**
		 * This function is run on the command "wp grieg import_user_content"
		 */
		public function import_user_content() {
			$file = dirname( __FILE__ ) . '/import/user_content.json';
			if ( file_exists( $file ) ) {
				$this->populate_data();

				$content    = file_get_contents( $file ); // phpcs:ignore
				$user_posts = json_decode( $content, true );
				foreach ( $user_posts as $user_post ) {
					$args = (array) $user_post['post'];
					unset( $args['ID'] );

					$existing_user = get_user_by( 'ID', $args['post_author'] );
					if ( false === $existing_user ) {
						WP_CLI::line( "\t" . 'Could not find user. Bypassing post id: ' . $user_post['ID'] );
					}

					$args['post_type'] = nisje_get_setting( 'post_type_name', 'user-content' );

					$author      = $args['post_author'];
					$post_parent = 0;
					if ( $author ) {
						if ( isset( $this->users[ $author ], $this->group_mappings[ $this->users[ $author ] ] ) ) {
							$post_parent = $this->group_mappings[ $this->users[ $author ] ];
						}
					}

					$args['post_parent'] = $post_parent;
					$args['post_status'] = 'publish';

					$original_post = $this->get_existing_post( (string) $user_post['ID'], nisje_get_setting( 'post_type_name', 'user-content' ) );

					if ( is_object( $original_post ) && 'WP_Post' === get_class( $original_post ) ) {
						$args['ID'] = $original_post->ID;
						WP_CLI::line( "\t" . 'Found original post so updating post ' . $original_post->ID );
					} else {
						WP_CLI::line( "\t" . 'No original post found, creating new' );
					}

					$post_id = wp_insert_post( $args );

					if ( 0 !== $post_parent ) {
						update_post_meta( $post_id, '_nisje_group_connection', $post_parent );
					}

					update_post_meta( $post_id, '_id_in_remote', $user_post['ID'] );

					$taxonomy_type_name = nisje_get_setting( 'taxonomy_type_name', 'user-content' );

					wp_set_post_terms( $post_id, 'social', $taxonomy_type_name );
				}
			}
		}

		/**
		 * This function is run on the command "wp grieg import_news"
		 */
		public function import_news() {
			$file = dirname( __FILE__ ) . '/import/news.json';
			if ( file_exists( $file ) ) {
				$this->populate_data();

				$content    = file_get_contents( $file ); // phpcs:ignore
				$news_posts = json_decode( $content, true );
				foreach ( $news_posts as $news_post ) {
					$content     = isset( $news_post['meta']['content'][0] ) && ! empty( $news_post['meta']['content'][0] ) ? $news_post['meta']['content'][0] : '';
					$limits      = false;
					$post_type   = nisje_get_setting( 'post_type_name', 'news' );
					$post_parent = 0;
					if ( isset( $news_post['meta']['limits'] ) ) {
						$limits      = $news_post['meta']['limits'];
						$post_type   = nisje_get_setting( 'post_type_name_group', 'news' );
						$post_parent = isset( $this->group_mappings[ $limits ] ) ? $this->group_mappings[ $limits ] : 0;
					}

					$args = (array) $news_post['post'];
					if ( empty( $args['post_content'] ) ) {
						$args['post_content'] = $content;
					}

					unset( $args['ID'] );

					$args['post_parent'] = $post_parent;
					$args['post_type']   = $post_type;

					$existing_user = get_user_by( 'ID', $args['post_author'] );
					if ( false === $existing_user ) {
						WP_CLI::line( "\t" . 'Could not find user. Bypassing post id: ' . $news_post['ID'] );
					}

					$original_post = $this->get_existing_post( (string) $news_post['ID'], $post_type );

					if ( is_object( $original_post ) && 'WP_Post' === get_class( $original_post ) ) {
						$args['ID'] = $original_post->ID;
						WP_CLI::line( "\t" . 'Found original post so updating post ' . $original_post->ID );
					} else {
						WP_CLI::line( "\t" . 'No original post found, creating new' );
					}

					WP_CLI::line( "\t" . 'Post Type: ' . $post_type );

					$post_id = wp_insert_post( $args );
					if ( 0 !== $post_parent ) {
						update_post_meta( $post_id, '_nisje_group_connection', $post_parent );
					}

					update_post_meta( $post_id, '_id_in_remote', $news_post['ID'] );
				}
			}
		}

		/**
		 * This function is run on the command "wp grieg import_wiki"
		 */
		public function import_wiki() {
			$file = dirname( __FILE__ ) . '/import/wiki.json';
			if ( file_exists( $file ) ) {
				$this->populate_data();

				$content    = file_get_contents( $file ); // phpcs:ignore
				$wiki_posts = json_decode( $content, true );
				foreach ( $wiki_posts as $wiki_post ) {
					$content     = isset( $news_post['meta']['content'][0] ) && ! empty( $news_post['meta']['content'][0] ) ? $news_post['meta']['content'][0] : '';
					$limits      = false;
					$post_type   = nisje_get_setting( 'post_type_name', 'news' );
					$post_parent = 0;
					if ( isset( $news_post['meta']['limits'] ) ) {
						$limits      = $news_post['meta']['limits'];
						$post_type   = nisje_get_setting( 'post_type_name_group', 'news' );
						$post_parent = isset( $this->group_mappings[ $limits ] ) ? $this->group_mappings[ $limits ] : 0;
					}

					$args = (array) $news_post['post'];
					if ( empty( $args['post_content'] ) ) {
						$args['post_content'] = $content;
					}

					unset( $args['ID'] );

					$args['post_parent'] = $post_parent;
					$args['post_type']   = $post_type;

					$existing_user = get_user_by( 'ID', $args['post_author'] );
					if ( false === $existing_user ) {
						WP_CLI::line( "\t" . 'Could not find user. Bypassing post id: ' . $news_post['ID'] );
					}

					$original_post = $this->get_existing_post( (string) $news_post['ID'], $post_type );

					if ( is_object( $original_post ) && 'WP_Post' === get_class( $original_post ) ) {
						$args['ID'] = $original_post->ID;
						WP_CLI::line( "\t" . 'Found original post so updating post ' . $original_post->ID );
					} else {
						WP_CLI::line( "\t" . 'No original post found, creating new' );
					}

					WP_CLI::line( "\t" . 'Post Type: ' . $post_type );

					$post_id = wp_insert_post( $args );
					if ( 0 !== $post_parent ) {
						update_post_meta( $post_id, '_nisje_group_connection', $post_parent );
					}

					update_post_meta( $post_id, '_id_in_remote', $news_post['ID'] );
				}
			}
		}

		/**
		 * Finds existing post in WordPress
		 *
		 * @param string $remote_id The ID of the post to be found.
		 * @param string $type      The post type.
		 * @return array|boolean
		 */
		private function get_existing_post( string $remote_id, string $type = '' ) {  // phpcs:ignore
			if ( '' === $type ) {
				return null;
			}

			$args = [
				'post_type'   => $type,
				'post_status' => [ 'publish', 'draft' ],
				'meta_query'  => [ // phpcs:ignore
					[
						'key'     => '_id_in_remote',
						'value'   => $remote_id,
						'compare' => '=',
					],
				],
			];

			$query = new \WP_Query( $args );

			$posts = $query->get_posts();
			if ( isset( $posts[0] ) ) {
				WP_CLI::line( 'Post title found: ' . $posts[0]->post_title );
				WP_CLI::line( 'Post ID found: ' . $posts[0]->ID );
				return $posts[0];
			} else {
				return null;
			}
		}
	}

	$grieg = new Grieg();

	WP_CLI::add_command( 'grieg', $grieg );
}
