<?php namespace flow\social;

use Exception;
use flow\social\timelines\FFCollections;
use flow\social\timelines\FFFavorites;
use flow\social\timelines\FFHomeTimeline;
use flow\social\timelines\FFListTimeline;
use flow\social\timelines\FFSearch;
use flow\social\timelines\FFTimeline;
use flow\social\timelines\FFUserTimeline;
use stdClass;

if ( ! defined( 'WPINC' ) ) die;
/**
 * Flow-Flow.
 *
 * @package   FlowFlow
 * @author    Looks Awesome <email@looks-awesome.com>
 * @link      http://looks-awesome.com
 * @copyright 2014-2016 Looks Awesome
 *
 * @noinspection PhpUnused
 */
class FFTwitter extends FFBaseFeed{
	private static $GET = "GET";

	/** @var  FFTimeline */
	private $timeline;
	/** @var FFTwitterAPIExchange */
	private $restService;
	private $image;

	public function __construct() {
		parent::__construct( 'twitter' );
	}

	/**
	 * @param stdClass $feed
	 *
	 * @throws Exception
	 */
	public function deferredInit($feed){
		$this->restService = new FFTwitterAPIExchange($feed->twitter_access_settings);
		$this->timeline = $this->getTimeline($feed);
	}

	/**
	 * @return array
	 * @throws Exception
	 */
	public function onePagePosts(){
		$json = json_decode($this->restService
			->setGetfield($this->timeline->getField())
			->buildOauth($this->timeline->getUrl(), self::$GET)
			->performRequest(), $assoc = TRUE);

		if (isset($json['errors'])) {
			//throw new LASocialRequestException($this->timeline->getUrl(), $json['errors']);
			foreach ($json['errors'] as $error) {
				$msg = $error['message'];
				$this->errors[] = [
					'type'    => 'twitter',
					'message' => $this->filterErrorMessage($msg),
					'url' => $this->timeline->getUrl()
                ];
				throw new Exception();
			}
			return [];
		}
		return $this->parseRequest($json);
	}

	private function parseRequest($json) {
		$tmp = $json;
		$result = [];

        if (isset($json['error']) && !empty($json['error'])){
            throw new LASocialException($json['error'], ['type'    => 'twitter']);
        }

		if (isset($json['statuses'])) {
			$tmp = $json['statuses'];
		}
		if (isset($json['objects']['tweets'])){
			$tmp = $json['objects']['tweets'];
		}
		if (isset($tmp) && is_array($tmp)){
			foreach ($tmp as $t) {
				$this->image = null;
				$tc = new stdClass();
				$tc->feed_id = $this->id();
				$tc->id = $t['id_str'];
				$tc->type = $this->getType();
				if (isset($t['user']['screen_name'])){
					$tc->nickname = '@'.$t['user']['screen_name'];
					$tc->screenname = (string)$t['user']['name'];
					$tc->userpic = str_replace('.jpg', '_200x200.jpg', str_replace('_normal', '', (string)$t['user']['profile_image_url']));
					$tc->userlink = 'https://twitter.com/'.$t['user']['screen_name'];
				}
				else {
					$user_id = $t['user']['id'];
					if (isset($json['objects']['users'][$user_id])){
						$user = $json['objects']['users'][$user_id];
						$tc->nickname = '@'.$user['screen_name'];
						$tc->screenname = (string)$user['name'];
						$tc->userpic = str_replace('.jpg', '_200x200.jpg', str_replace('_normal', '', (string)$user['profile_image_url']));
						$tc->userlink = 'https://twitter.com/'.$user['screen_name'];
					}
				}
				$tc->system_timestamp = strtotime($t['created_at']);
				$tc->text = $this->getText($t);
				$tc->permalink = $tc->userlink . '/status/' . $tc->id;
				$tc->header = '';

				if (!is_null($this->image)) {
					$tc->img = $this->image;
				}
				$tc->additional = [];
				if (isset($t['retweet_count'])){
					$tc->additional['shares'] = (string)$t['retweet_count'];
				}
				if (isset($t['favorite_count'])){
					$tc->additional['likes'] = (string)$t['favorite_count'];
				}
				if (isset($t['reply_count'])){
					$tc->additional['comments'] = (string)$t['reply_count'];
				}
				if ($this->isSuitablePost($tc)) $result[$tc->id] = $tc;
			}
		}
		return $result;
	}

	private function getTimeline($feed){
		$timeline = null;
		switch ($feed->{'timeline-type'}) {
			case 'home_timeline':
				$timeline = new FFHomeTimeline();
				break;
			case 'user_timeline':
				$timeline = new FFUserTimeline();
				break;
			case 'favorites':
				$timeline = new FFFavorites();
				break;
			case 'list_timeline':
				$timeline = new FFListTimeline();
				break;
			case 'collection_timeline':
				$timeline = new FFCollections();
				break;
			default:
				$timeline = new FFSearch();
		}
		$timeline->init($this, $feed);
		return $timeline;
	}

	private function getChAr($text){
		$ChAr = [];
		if (function_exists('mb_detect_encoding')){
			$encoding = mb_detect_encoding($text);
			if ($encoding === false){
				$encoding = mb_internal_encoding();
			}
			for ($i = 0; $i < mb_strlen($text, $encoding); $i++) {
				$ch = mb_substr($text, $i, 1, $encoding);
				if ($ch <> "\n") $ChAr[] = $ch; else $ChAr[] = "\n<br/>";
			}
		}
		else {
			for ($i = 0; $i < strlen($text); $i++) {
				$ch = substr($text, $i, 1);
				if ($ch <> "\n") $ChAr[] = $ch; else $ChAr[] = "\n<br/>";
			}
		}
		return $ChAr;
	}

	private function getText($tweet){
		if (!isset($tweet['entities'])){
			return isset($tweet['text']) ? (string) $tweet['text'] : $tweet['full_text'];
		}
		$text = isset($tweet['text']) ? (string) $tweet['text'] : (string) $tweet['full_text'];
		$ChAr = $this->getChAr($text);
		$entities = $tweet['entities'];
		if (isset($entities['user_mentions']))
			foreach ($entities['user_mentions'] as $entity) {
				$ChAr[$entity['indices'][0]] = "<a href='https://twitter.com/" . $entity['screen_name'] . "'>" . $ChAr[$entity['indices'][0]];
				$ChAr[$entity['indices'][1] - 1] .= "</a>";
			}
		if (isset($entities['hashtags']))
			foreach ($entities['hashtags'] as $entity) {
				$ChAr[$entity['indices'][0]] = "<a href='https://twitter.com/search?q=%23" . $entity['text'] . "'>" . $ChAr[$entity['indices'][0]];
				$ChAr[$entity['indices'][1] - 1] .= "</a>";
			}
		if (isset($entities['urls']))
			foreach ($entities['urls'] as $entity) {
				$ChAr[$entity['indices'][0]] = "<a href='" . $entity['expanded_url'] . "'>" . $entity['display_url'] . "</a>";
				for ($i = $entity['indices'][0] + 1; $i < $entity['indices'][1]; $i++) $ChAr[$i] = '';
			}
		if (isset($entities['media']))
			foreach ($entities['media'] as $entity) {
				$ChAr[$entity['indices'][0]] = "<a href='" . $entity['expanded_url'] . "'>";
				if ($entity['type'] == 'photo') {
					$sizes = $entity['sizes']['small'];
					$this->image = $this->createImage($entity['media_url_https'], $sizes['w'],$sizes['h']);
					$ChAr[$entity['indices'][0]] .= "<img src='" . $entity['media_url_https'] . "' style='width:%WIDTH%px;height:%HEIGHT%px'/>";
				} else {
					$ChAr[$entity['indices'][0]] .= $entity['display_url'];
				}
				$ChAr[$entity['indices'][0]] .= "</a>";
				for ($i = $entity['indices'][0] + 1; $i < $entity['indices'][1]; $i++) $ChAr[$i] = '';
			}
		return implode('', $ChAr);
	}
}