<?php

namespace FSPoster\App\SocialNetworks\WordPress\App;

use Exception;
use FSPoster\App\Models\Channel;
use FSPoster\App\Pages\Schedules\CalendarData;
use FSPoster\App\Providers\Channels\ChannelSessionException;
use FSPoster\App\Providers\Core\Settings;
use FSPoster\App\Providers\DB\Collection;
use FSPoster\App\Providers\Schedules\ScheduleObject;
use FSPoster\App\Providers\Schedules\ScheduleResponseObject;
use FSPoster\App\Providers\Schedules\ScheduleShareException;
use FSPoster\App\Providers\Schedules\SocialNetworkApiException;
use FSPoster\App\SocialNetworks\WordPress\Adapters\ChannelAdapter;
use FSPoster\App\SocialNetworks\WordPress\Adapters\PostingDataAdapter;
use FSPoster\App\SocialNetworks\WordPress\Api\RestApi\Api as RestApiApi;
use FSPoster\App\SocialNetworks\WordPress\Api\RestApi\AuthData as RestApiAuthData;
use FSPoster\App\SocialNetworks\WordPress\Api\XmlRpc\Api as XmlRpcApi;
use FSPoster\App\SocialNetworks\WordPress\Api\XmlRpc\AuthData as XmlRpcAuthData;

class Listener
{
	/**
	 * @throws ChannelSessionException
	 * @throws Exception
	 */
	public static function sharePost ( ScheduleResponseObject $result, ScheduleObject $scheduleObj ): ScheduleResponseObject
	{
		if ( $scheduleObj->getSocialNetwork() !== Bootstrap::getInstance()->getSlug() ) {
            return $result;
        }

		$authDataArray = $scheduleObj->getChannelSession()->data_obj->auth_data ?? [];
        $postingDataAdapter = new PostingDataAdapter( $scheduleObj );
        $postingData = $postingDataAdapter->getPostingData();

        if ($scheduleObj->getChannelSession()->method === 'RestApi') {
            $authData = new RestApiAuthData();
            $api = new RestApiApi();
        } else {
            $authData = new XmlRpcAuthData();
            $api = new XmlRpcApi();
        }

        $authData->setFromArray( $authDataArray );

		$api->setProxy( $scheduleObj->getChannelSession()->proxy )
		    ->setAuthException( ChannelSessionException::class )
		    ->setPostException( ScheduleShareException::class )
		    ->setAuthData( $authData );

		$response = $api->sendPost( $postingData );

		$snPostResponse = new ScheduleResponseObject();
		$snPostResponse->status         = 'success';
		$snPostResponse->remote_post_id = $response;

		return $snPostResponse;
	}

    /**
     * @param array $customPostData
     * @param Collection $channel
     * @param string $socialNetwork
     *
     * @return array
     */
	public static function getCustomPostData ( array $customPostData, Collection $channel, string $socialNetwork )
	{
		if ( $socialNetwork !== Bootstrap::getInstance()->getSlug() )
			return $customPostData;

		$channelSettings = $channel->custom_settings_obj->custom_post_data;

		$customPostData["post_title"] = Settings::get( 'wordpress_post_title', '{post_title}' );
		$customPostData["post_excerpt"] = Settings::get( 'wordpress_post_excerpt', '{post_excerpt}' );
		$customPostData["send_tags"] = (bool)Settings::get( 'wordpress_send_tags', true );
		$customPostData["custom_tags"] = [];
		$customPostData["send_categories"] = (bool)Settings::get( 'wordpress_send_categories', true );
		$customPostData["custom_categories"] = [];
		$customPostData["post_status"] = Settings::get( 'wordpress_post_status', 'publish' );
		$customPostData["preserve_post_type"] = (bool)Settings::get( 'wordpress_preserve_post_type', true );
		$customPostData["upload_media"] = (bool)Settings::get( 'wordpress_upload_media', false );
		$customPostData["upload_media_type"] = 'featured_image';

		if( ! empty( $channelSettings[ 'use_custom_post_content' ] ) )
			$customPostData['post_content'] = $channelSettings[ 'post_content' ];
		else
			$customPostData['post_content'] = Settings::get( 'wordpress_post_content', "{post_content}" );

		return $customPostData;
	}

    /**
     * @param string $socialNetwork
     * @param Collection $channel
     * @param Collection $channelSession
     * @return void
     */
    public static function disableSocialChannel (string $socialNetwork, Collection $channel, Collection $channelSession ): void
    {
        if ( $socialNetwork !== Bootstrap::getInstance()->getSlug() )
            return;

        Channel::where( 'channel_session_id', $channelSession->id )->update( [ 'status' => 0 ] );
    }

    /**
     * @param CalendarData $calendarData
     * @param ScheduleObject $scheduleObj
     * @return CalendarData
     */
    public static function getCalendarData(CalendarData $calendarData, ScheduleObject $scheduleObj ): CalendarData
    {
		if ( $scheduleObj->getSocialNetwork() !== Bootstrap::getInstance()->getSlug() )
			return $calendarData;

		$postingData = new PostingDataAdapter( $scheduleObj );

		$calendarData->content   = $postingData->getPostingDataTitle();
		$calendarData->mediaList = $postingData->getPostingDataUploadMedia();

		return $calendarData;
	}

    /**
     * @param string $postLink
     * @param ScheduleObject $scheduleObj
     * @return string
     */
    public static function getPostLink (string $postLink, ScheduleObject $scheduleObj ): string
    {
        if ( $scheduleObj->getSocialNetwork() !== Bootstrap::getInstance()->getSlug() )
			return $postLink;

        return rtrim( $scheduleObj->getChannel()->remote_id, '/' ) . '/?p=' . $scheduleObj->getSchedule()->remote_post_id;
    }

    /**
     * @param string $channelLink
     * @param string $socialNetwork
     * @param Collection $channel
     * @return string
     */
    public static function getChannelLink (string $channelLink, string $socialNetwork, Collection $channel ): string
    {
        if ( $socialNetwork !== Bootstrap::getInstance()->getSlug() )
			return $channelLink;

        return $channel->remote_id;
    }

    /**
     * @throws SocialNetworkApiException
     * @throws ChannelSessionException
     */
    public static function refreshChannel (array $updatedChannel, string $socialNetwork, Collection $channel, Collection $channelSession ): array
    {
        if ( $socialNetwork !== Bootstrap::getInstance()->getSlug() )
            return $updatedChannel;

	    $authDataArray = $channelSession->data_obj->auth_data ?? [];

        if ($channelSession->method === 'RestApi') {
            $authData = new RestApiAuthData();
            $api = new RestApiApi();
        } else {
            $authData = new XmlRpcAuthData();
            $api = new XmlRpcApi();
        }

        $authData->setFromArray( $authDataArray );

	    $api->setProxy( $channelSession->proxy )
	        ->setAuthException( ChannelSessionException::class )
	        ->setAuthData( $authData );

	    $refreshedChannels = ChannelAdapter::fetchChannels($api, $channelSession->method);

        foreach ( $refreshedChannels as $refreshedChannel )
        {
            if ( $refreshedChannel[ 'remote_id' ] == $channel->remote_id )
            {
                return $refreshedChannel;
            }
        }

        return $updatedChannel;
    }
}