<?php

namespace App\Packages\v4\Capsule\Transformer;

use App\Packages\Capsule\Models\Capsule;
use App\Packages\Capsule\Models\CapsuleComment;
use App\Packages\Capsule\Models\CapsuleLike;
use App\Packages\Capsule\Models\CapsuleOpen;
use App\Packages\Capsule\Models\CapsulePreview;
use App\Packages\Capsule\Models\CapsuleRemoved;
use App\Packages\Capsule\Models\CapsuleSubscriber;
use App\Packages\Capsule\Models\CapsuleTaggedUser;
use App\Packages\Capsule\Services\CapsuleTeaserUploadService;
use App\Packages\Core\Models\Address;
use App\Packages\User\Models\User;
use App\Packages\User\Models\UserMention;
use App\Packages\v4\Capsule\Repository\CapsuleCommentRepository;
use App\Packages\v4\Capsule\Repository\CapsuleLikeRepository;
use App\Packages\v4\Capsule\Repository\CapsuleRemovedRepository;
use App\Packages\v4\Capsule\Repository\CapsuleSubscriberRepository;
use App\Packages\v4\Capsule\Repository\CapsuleTaggedUserRepository;
use App\Packages\v4\User\Repository\UserMentionRepository;
use App\Packages\v4\User\Service\UserMentionService;
use App\Packages\v4\User\Transformer\UserMentionTransformer;
use App\Packages\v4\User\Transformer\UserTransformer;
use Illuminate\Support\Carbon;

/**
 * Class CapsuleArrayTransformer
 * @package App\Packages\Capsule\Transformer
 */
class CapsuleArrayTransformer
{
	/**
	 * @param Capsule $capsule
	 *
	 * @return array
	 */
	public static function smallObject(Capsule $capsule)
	{
        $canBeOpened = $capsule->canBeOpened();

		$result = [
			"id" => $capsule->uuid,
		];

		if ( ! $canBeOpened ) {
		    $result['teaser_url'] = $capsule->getTeaserUrl();
        }

		if ($capsule->thumbnail) {
			$result['thumbnail'] = static::imageFullObject($capsule->thumbnail);
		}

        if ($capsule->preview) {
            $result['preview'] = static::imageFullObject($capsule->preview);
        }

        if ($capsule->cropped) {
            $result['cropped'] = static::imageFullObject($capsule->cropped);
        }

		return $result;
	}

    /**
     * @param Capsule $capsule
     * @return array
     * @throws \Exception
     */
	public static function searchObject(Capsule $capsule)
    {
        $canBeOpened = $capsule->canBeOpened();

        $result = [
            "id" => $capsule->uuid,
            "capsule_status" => $capsule->openedByMe ? Capsule::STATUS_OPENED : $capsule->status,
            "opens_at" => formatDate($capsule->open_at),
            "opened_at" => ($capsule->openedAt) ? formatDate($capsule->openedAt) : null,
            "created_at" => formatDate($capsule->created_at),
            "caption" => $capsule->caption,
        ];

        $result['owner'] = [
            "user_id" => $capsule->userUuid,
            "nickname" => $capsule->userName
        ];

        if ($capsule->avatarAwsKey) {
            $result['owner']['image_url'] = avatarAwsPath($capsule->avatarAwsKey);
        }

        if ($capsule->originalAvatarAwsKey) {
            $result['owner']['original_image_url'] = avatarAwsPath($capsule->originalAvatarAwsKey);
        }

        if ( ! $canBeOpened ) {
            $result['teaser_url'] = $capsule->getTeaserUrl();
        }

        if ($capsule->thumbnail) {
            $result['thumbnail'] = static::imageFullObject($capsule->thumbnail);
        }

        if ($capsule->preview) {
            $result['preview'] = static::imageFullObject($capsule->preview);
        }

        if ($capsule->cropped) {
            $result['cropped'] = static::imageFullObject($capsule->cropped);
        }

        return $result;
    }

    /**
     * @param $capsule
     * @param User $user
     *
     * @return array
     *
     * @throws \Exception
     */
    public static function feedCapsuleArray($capsule, User $user)
    {
        $canBeOpened = new Carbon($capsule->open_at) <= now();
        $mentioned = UserMentionRepository::init()->getAllFromCapsule($capsule);

        $result = [
            "cap_id" => $capsule->id,
            "id" => $capsule->uuid,

            "capsule_status" => $capsule->openedByMe ? Capsule::STATUS_OPENED : $capsule->status,
            "share_link" => route('capsule.share', [
                'uuid' => $capsule->uuid,
                'share_key' => hash('crc32', $capsule->id)
            ]),

            "is_private" => (bool)$capsule->is_private,
            "opens_at" => formatDate($capsule->open_at),
            "opened_at" => ($capsule->openedAt) ? formatDate($capsule->openedAt) : null,
            "created_at" => formatDate($capsule->created_at),

            "caption" => $capsule->caption,
            "has_mentions" => false,
            "is_complete" => $capsule->is_complete,
            "is_blocked" => $capsule->blocked,

            "is_my_capsule" => $capsule->user_id == $user->id,

            "liked_by_me" => (bool)$capsule->likedByMe,
            "subscribed_by_me" => (bool)$capsule->subscribedByMe,

            "is_tagged" => (bool)$capsule->taggedInMe,
            "is_removed" => (bool)$capsule->removedByMe,

            "count_comment" => (int)$capsule->count_comments,
            "count_like" => (int)$capsule->count_likes,
            "count_subscribers" => (int)$capsule->count_subscribers,
        ];

        $result['owner'] = [
            "user_id" => $capsule->userUuid,
            "nickname" => $capsule->userName
        ];

        if ($capsule->avatarAwsKey) {
            $result['owner']['image_url'] = avatarAwsPath($capsule->avatarAwsKey);
        }

        if ($capsule->originalAvatarAwsKey) {
            $result['owner']['original_image_url'] = avatarAwsPath($capsule->originalAvatarAwsKey);
        }

        if ( $mentioned->isNotEmpty() ) {
            $result['caption'] = UserMentionService::normalizeString($capsule->caption, $mentioned);
            $result['has_mentions'] = true;
            $result['mentioned_users'] = UserMentionTransformer::smallObject($mentioned);
        }

        if ( ! $canBeOpened ) {
            $result['teaser_url'] = '';

            if ($capsule->teaserAwsKey) {
                $teaserUploadService = app(CapsuleTeaserUploadService::class);
                $teaser_uploaded = $teaserUploadService->checkIfExist($capsule->teaserAwsKey);
                $result['teaser_url'] = ($teaser_uploaded) ? teaserAwsPathCDN($capsule->teaserAwsKey) : '';
            }
        }

        $result['preview'] = [
            'width' => (int)$capsule->previewWidth,
            'height' => (int)$capsule->previewHeight,
            'url' => previewAwsPathCDN($capsule->previewAwsKey),
        ];

        if ($capsule->croppedAwsKey) {
            $result['cropped'] = [
                'width' => (int)$capsule->croppedWidth,
                'height' => (int)$capsule->croppedHeight,
                'url' => previewAwsPathCDN($capsule->croppedAwsKey),
            ];
        }

        return $result;
    }

    /**
     * @param $capsule
     * @param User $user
     * @return array
     *
     * @throws \Exception
     */
    public static function profileCapsuleArray($capsule, User $user)
    {
        $canBeOpened = new Carbon($capsule->open_at) <= now();
        $mentioned = UserMentionRepository::init()->getAllFromCapsule($capsule);

        $result = [
            "media_url" => ($canBeOpened) ? videoAwsPathCDN($capsule->videoAwsKey) : null,
            "share_link" => route('capsule.share', [
                'uuid' => $capsule->uuid,
                'share_key' => hash('crc32', $capsule->id)
            ]),

            "cap_id" => $capsule->id,
            "id" => $capsule->uuid,

            "capsule_status" => $capsule->openedByMe ? Capsule::STATUS_OPENED : $capsule->status,

            "is_private" => (bool)$capsule->is_private,
            "opens_at" => formatDate($capsule->open_at),
            "opened_at" => ($capsule->openedAt) ? formatDate($capsule->openedAt) : null,
            "created_at" => formatDate($capsule->created_at),

            "caption" => $capsule->caption,
            "has_mentions" => false,
            "is_complete" => $capsule->is_complete,
            "is_blocked" => $capsule->blocked,

            "is_my_capsule" => $capsule->user_id == $user->id,

            "liked_by_me" => (bool)$capsule->likedByMe,
            "subscribed_by_me" => (bool)$capsule->subscribedByMe,

            "is_tagged" => (bool)$capsule->taggedInMe,
            "is_removed" => false,
        ];

        $result['owner'] = [
            "user_id" => $capsule->userUuid,
            "nickname" => $capsule->userName,
        ];

        if ($capsule->avatarAwsKey) {
            $result['owner']['image_url'] = avatarAwsPath($capsule->avatarAwsKey);
        }

        if ($capsule->originalAvatarAwsKey) {
            $result['owner']['original_image_url'] = avatarAwsPath($capsule->originalAvatarAwsKey);
        }

        if ( $mentioned->isNotEmpty() ) {
            $result['caption'] = UserMentionService::normalizeString($capsule->caption, $mentioned);
            $result['has_mentions'] = true;
            $result['mentioned_users'] = UserMentionTransformer::smallObject($mentioned);
        }

        if ( ! $canBeOpened ) {
            $result['teaser_url'] = '';

            if ($capsule->teaserAwsKey) {
                $teaserUploadService = app(CapsuleTeaserUploadService::class);
                $teaser_uploaded = $teaserUploadService->checkIfExist($capsule->teaserAwsKey);
                $result['teaser_url'] = ($teaser_uploaded) ? teaserAwsPathCDN($capsule->teaserAwsKey) : '';
            }
        }

        if ($capsule->previewAwsKey) {
            $result['preview'] = [
                'width' => (int)$capsule->previewWidth,
                'height' => (int)$capsule->previewHeight,
                'url' => previewAwsPathCDN($capsule->previewAwsKey),
            ];
        }

        if ($capsule->thumbnailAwsKey) {
            $result['thumbnail'] = [
                'width' => (int)$capsule->thumbnailWidth,
                'height' => (int)$capsule->thumbnailHeight,
                'url' => previewAwsPathCDN($capsule->thumbnailAwsKey),
            ];
        }

        return $result;
    }

    /**
     * @param Capsule $capsule
     * @param User $user
     *
     * @return array
     */
    public static function mainCapsule(Capsule $capsule, User $user)
    {
        $likesByMe = CapsuleLikeRepository::init()->capsuleLikedByUser($capsule, $user);
        $subscribedByMe = CapsuleSubscriberRepository::init()->capsuleSubscribedByUser($capsule, $user);
        $taggedInMe = CapsuleTaggedUserRepository::init()->existsTaggedUser($capsule, $user);
        $capsuleIsRemoved = CapsuleRemovedRepository::init()->capsuleIsRemoved($capsule, $user);

        $status = CapsuleOpen::isOpenedByUser($capsule, $user);
        $status = ($status) ? Capsule::STATUS_OPENED : $capsule->status;

        $countComments = CapsuleCommentRepository::init()->capsuleCommentsCount($capsule);
        $countLikes = CapsuleLikeRepository::init()->capsuleLikesCount($capsule);
        $countSubscribers = CapsuleSubscriberRepository::init()->capsuleSubscribersCount($capsule);

        $canBeOpened = $capsule->canBeOpened();
        $mentioned = UserMentionRepository::init()->getAllFromCapsule($capsule);

        $result = [
            "cap_id" => $capsule->id,
            "id" => $capsule->uuid,

            "capsule_status" => $status,
            "media_url" => ($canBeOpened) ? $capsule->getMediaUrl() : null,
            "share_link" => route('capsule.share', ['uuid' => $capsule->uuid, 'share_key' => $capsule->share_key]),

            "is_private" => (bool)$capsule->is_private,
            "opens_at" => $capsule->getFormattedOpenDate(),
            "caption" => $capsule->caption,
            "has_mentions" => false,
            "is_complete" => $capsule->is_complete,
            "is_blocked" => $capsule->blocked,

            "created_at" => $capsule->getFormattedCreatedDate(),

            "owner" => UserTransformer::smallObject($capsule->user),
            "is_my_capsule" => $capsule->user_id == $user->id,

            "liked_by_me" => $likesByMe,
            "subscribed_by_me" => $subscribedByMe,

            "is_tagged" => $taggedInMe,
            "tagged_in_me" => $taggedInMe,

            "is_removed" => $capsuleIsRemoved,

            "count_comment" => (int)$countComments,
            "count_like" => (int)$countLikes,
            "count_subscribers" => (int)$countSubscribers,
        ];

       // if ($capsule->id % 2 == 0) {
            $result["media_hls_url"] = ($canBeOpened) ? $capsule->getMediaUrl() : null;
        //}

        if ( $mentioned->isNotEmpty() ) {
            $result['caption'] = UserMentionService::normalizeString($capsule->caption, $mentioned);
            $result['has_mentions'] = true;
            $result['mentioned_users'] = UserMentionTransformer::smallObject($mentioned);
        }

        /** If capsule locked show teaser video */
        if ( ! $canBeOpened ) {
            $result['teaser_url'] = $capsule->getTeaserUrl();
        }

        if ($capsule->preview) {
            $result['preview'] = static::imageFullObject($capsule->preview);
        }

        if ($capsule->thumbnail) {
            $result['thumbnail'] = static::imageFullObject($capsule->thumbnail);
        }

        if ($capsule->cropped) {
            $result['cropped'] = static::imageFullObject($capsule->cropped);
        }

        if ($capsule->address) {
            $result['address'] = static::addressFullObject($capsule->address);
        }

        $lastComments = CapsuleCommentRepository::init()->lastCapsuleComments($capsule);
        $lastComments = $lastComments->map(function (CapsuleComment $comment) use ($user) {
            return CapsuleCommentTransformer::commentFull($comment, $user);
        });

        $result['last_comments'] = $lastComments;


        $taggedUsers = CapsuleTaggedUserRepository::init()->capsuleTaggedUsers($capsule);
        $taggedUsers = $taggedUsers->map(function (User $taggedUser) use ($user, $capsule) {
            $formatted = UserTransformer::middleObject($taggedUser, $user);
            $formatted['is_open'] = (CapsuleOpen::isOpenedByUser($capsule, $taggedUser)) ? true : false;
            return $formatted;
        });

        $result['tagged_users'] = $taggedUsers;

        return $result;
    }

	/**
	 * @param Address $address
	 *
	 * @return array
	 */
	public static function addressFullObject(Address $address)
	{
		return [
			"id" => $address->google_place_id,
			"lat" => $address->lat,
			"lng" => $address->lng,
			"vicinity" => $address->user_input,

			"street_title" => $address->street_title,
			"street_number" => $address->street_number,
			"country_title" => $address->country_title,
			"full_address" => $address->full_string,
			"city" => $address->city,
		];
	}

	/**
	 * @param CapsulePreview $thumbnail
	 *
	 * @return array
	 */
	public static function imageFullObject(CapsulePreview $thumbnail)
	{
		return [
			'width' => (int)$thumbnail->width,
			'height' => (int)$thumbnail->height,
			'url' => previewAwsPathCDN($thumbnail->aws_key),
		];
	}
}
