<?php

namespace FSPoster\App\Lib\wordpress;

use Exception;
use FSPoster\App\Providers\Curl;
use FSPoster\App\Providers\Helper;
use FSPoster\App\Providers\Request;
use GuzzleHttp\Client;
use IXR_Base64;
use IXR_Message;
use IXR_Request;

class Wordpress
{

	private $site_url;
	private $username;
	private $password;
	private $client;
	private $proxy;

	public function __construct($site_url, $username, $password, $proxy = '')
	{
		$this->proxy = $proxy;
		$this->site_url = rtrim($site_url, '/');
		$this->username = $username;
		$this->password = $password;

		include_once(ABSPATH . WPINC . '/class-IXR.php');
		//include_once( ABSPATH . WPINC . '/class-wp-http-ixr-client.php' );

		$this->client = new Client([
			'proxy' => empty($proxy) ? null : $proxy,
			'verify' => false,
			'http_errors' => false,
			'headers' => [
				'Content-Type' => 'text/xml',
				'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0'
			]
		]);
	}

	public function sendPost($postInf, $title, $excerpt, $content, $thumbnail = '')
	{
		$params = [
			'post_title' => $title,
			'post_excerpt' => $excerpt,
			'post_content' => $content,
			'post_type' => 'post',
			'post_status' => 'publish',
			'terms' => [],
		];

		if (Helper::getOption('wordpress_post_with_categories', '1') == 1) {
			$params['terms']['category'] = $this->terms($postInf['ID'], 'category');
		}

		if (Helper::getOption('wordpress_post_with_tags', '1') == 1) {
			$params['terms']['post_tag'] = $this->terms($postInf['ID'], 'post_tag');
		}

		if (empty($params['terms'])) {
			unset($params['terms']);
		}

		$mediaId = $this->uploadPhoto($thumbnail);
		if (!empty($mediaId)) {
			$params['post_thumbnail'] = $mediaId;
		}

		$createPost = $this->cmd('wp.newPost', $params);
		if (isset($createPost['faultString']) || !is_numeric($createPost)) {
			return [
				'status' => 'error',
				'error_msg' => isset($createPost['faultString']) ? $createPost['faultString'] : esc_sql('An error occurred while processing this request!')
			];
		}
		$postId = (int)$createPost;

		return [
			'status' => 'ok',
			'id' => $postId
		];
	}

	public function terms($postId, $taxonomy)
	{
		$postTerms = wp_get_post_terms($postId, $taxonomy);
		$termIDs = [];

		foreach ($postTerms as $term) {
			$termId = $this->syncTerm($term->slug, $term->name, $taxonomy);

			if (!empty($termId)) {
				$termIDs[] = $termId;
			}
		}

		return $termIDs;
	}

	public function syncTerm($termSlug, $termName, $taxonomy)
	{
		$termId = $this->findTerm($termSlug, $taxonomy);

		if (empty($termId)) {
			$termId = $this->cmd('wp.newTerm', [
				'name' => $termName,
				'slug' => $termSlug,
				'taxonomy' => $taxonomy
			]);
		}

		return $termId;
	}

	public function findTerm($termSlug, $taxonomy)
	{
		$result = $this->cmd('wp.getTerms', $taxonomy, ['search' => $termSlug]);

		foreach ($result as $termInf) {
			if ($termInf['slug'] == $termSlug) {
				return $termInf['term_id'];
			}
		}

		return false;
	}

	public function cmd()
	{
		$args = func_get_args();
		$command = array_shift($args);

		$params = array_merge([0, $this->username, $this->password], $args);

		$request = new IXR_Request($command, $params);
		$xml = $request->getXml();

		try {
			$result = $this->client->request('POST', $this->site_url . '/xmlrpc.php', [
				'body' => $xml
			]);
		} catch (Exception $e) {
			return [
				'faultString' => $e->getMessage()
			];
		}

		$message = new IXR_Message((string)$result->getBody());
		$message->parse();

		if (!isset($message->params[0])) {
			return [
				'faultString' => esc_html__('An error occurred while processing this request!')
			];
		}

		return $message->params[0];
	}

	public function uploadPhoto($image = null)
	{
		if (empty($image)) {
			return false;
		}

		$content = [
			'name' => basename($image),
			'type' => mime_content_type($image),
			'bits' => new IXR_Base64(file_get_contents($image)),
			true
		];

		$result = $this->cmd('metaWeblog.newMediaObject', $content);

		return isset($result['id']) ? $result['id'] : false;
	}

	/**
	 * @return array
	 */
	public function checkAccount()
	{
		$result = [
			'error' => true,
			'error_msg' => null
		];
		$checkUser = $this->checkUser();

		if ($checkUser !== true) {
			$result['error_msg'] = $checkUser;
		} else if ($checkUser === true) {
			$result['error'] = false;
		}

		return $result;
	}

	public function checkUser()
	{
		$info = $this->cmd('wp.getProfile');

		if (isset($info['faultString']))
			return $info['faultString'];

		if (isset($info['user_id']))
			return true;

		return esc_html__('The entered details are wrong!');
	}
}
