<?php

namespace App\Http\Resources;

use App\Libs\Database\Eloquent\Collection\BaseCollection;
use App\Libs\Database\Eloquent\Collection\ContentTypeCollection;
use App\Libs\Database\Eloquent\ContentTypeModel;
use App\Models\GenericBackoffice\OpenPosition;
use App\Models\GenericBackoffice\TeamMember;
use App\Models\GenericBackoffice\WebsiteObjectLanguage;
use Illuminate\Http\Resources\Json\JsonResource;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;

class Blocks extends JsonResource
{
    /**
     * Accesses constructor.
     * @param $resource
     */
    public function __construct($resource)
    {
        $this->resource = $resource;
    }

    public function toArray($request)
    {
        $out = [
            'id'   => (int)$this->id,
            'type' => $this->type,
            'slug' => $this->lang_slug
        ];

        // Specific block data per type
        $out = array_merge($out, $this->_getBlockData());

        return $out;
    }

    private function _getBlockData()
    {
        $out = [];
        switch ($this->type) {
            case 'blockWysiwyg':
                $out = $this->_getBlockWysiwyg();
                break;
            case 'blockClaim':
                $out = $this->_getBlockClaim();
                break;
            case 'blockImageTitleTextAndLink':
                $out = $this->_getBlockImageTitleTextAndLink();
                break;
            case 'blockOpenPositionsLink':
                $out = $this->_getBlockOpenPositionsLink();
                break;
            case 'blockLatestProject':
                $out = $this->_getBlockLatestProject();
                break;
            case 'blockHighlight':
                $out = $this->_getBlockHighlight();
                break;
            case 'blockOurSolutionsWithLink':
                $out = $this->_getBlockOurSolutionsWithLink();
                break;
            case 'blockServiceColumns':
                $out = $this->_getBlockServiceColumns();
                break;
            case 'blockCapabilitiesHero':
                $out = $this->_getBlockCapabilitiesHero();
                break;
            case 'blockOurValues':
                $out = $this->_getBlockOurValues();
                break;
            case 'blockPartnerRelationships':
                $out = $this->_getBlockPartnerRelationships();
                break;
            case 'blockCapabilityDetailTop':
                $out = $this->_getBlockCapabilityDetailTop();
                break;
            case 'blockTitleAndTextInColumns':
            case 'blockTitleAndTextInRows':
            case 'blockBlogArticleSection':
                $out = $this->_getBlockTitleAndText();
                break;
            case 'blockServicesAndSolutions':
                $out = $this->_getBlockServicesAndSolutions();
                break;
            case 'blockBenefits':
                $out = $this->_getBlockBenefits();
                break;
            case 'blockCase':
                $out = $this->_getBlockCase();
                break;
            case 'blockNext':
                $out = $this->_getBlockNext();
                break;
            case 'blockRelated':
                $out = $this->_getBlockRelated();
                break;
            case 'blockMeetUs':
                $out = $this->_getBlockMeetUs();
                break;
            case 'blockAccordion':
                $out = $this->_getBlockAccordion();
                break;
            case 'blockOpenPositionsList':
                $out = $this->_getBlockOpenPositionsList();
                break;
            case 'blockTeamMembersList':
                $out = $this->_getBlockTeamMembersList();
                break;
            case 'blockContactUsForm':
            case 'blockGetEstimateForm':
                $out = $this->_getBlockForms();
                break;
            case 'blockMediaHero':
                $out = $this->_getBlockMediaHero();
                break;
            case 'blockProjectIntroWithDeliverables':
                $out = $this->_getBlockProjectIntroWithDeliverables();
                break;
            case 'blockProjectDetails':
                $out = $this->_getBlockProjectDetails();
                break;
            case 'blockProjectsList':
            case 'blockBlogArticlesList':
                $out = $this->_getBlockWithFilterableList();
                break;
            case 'blockSingleImageContainer':
                $out = $this->_getBlockSingleImageContainer();
                break;
            case 'blockMultipleImageContainer':
                $out = $this->_getBlockMultipleImageContainer();
                break;
            case 'blockCaseContainer':
                $out = $this->_getBlockCaseContainer();
                break;
            case 'blockAuthor':
                $out = $this->_getBlockAuthor();
                break;
            case 'blockCodeSnippet':
                $out = $this->_getBlockCodeSnippet();
                break;
        }
        return $out;
    }

    /**************
     * Helpers
     **************/

    private function _getLink(?array $blockLink)
    {
        if ($blockLink) {
            if (array_key_exists('objectId', $blockLink)) {
                $activeLanguage = getActiveLanguage();
                $websiteObject = WebsiteObjectLanguage::where('website_object_id', $blockLink['objectId'])
                    ->where('wo_language_id', $activeLanguage)
                    ->first();
                if ($websiteObject) {
                    $blockLink['url'] = lang_uri($websiteObject->lang_uri, $activeLanguage);
                }
            }
        }

        return $blockLink;
    }

    private function _getBlockLinkWithStyleInfo($blockLink)
    {
        if (!is_array($blockLink)) {
            $blockLink = json_decode($blockLink, true);
        }
        $blockLink = $this->_getLink($blockLink);
        if ($blockLink && $blockLink['url']) {
            $blockLink['style'] = [];
            $blockLink['style']['type'] = $this->block_link_effect;
            $blockLink['style']['iconSize'] = $this->block_link_icon_size;
            $blockLink['style']['isIconFirst'] = $this->block_link_icon_side == 'left';
            $blockLink['style']['textSize'] = $this->block_link_text_size;
        } else {
            $blockLink = null;
        }
        return $blockLink;
    }

    private function _getSimpleLinksWithStyleInfo(ContentTypeCollection $blockSimpleLinks)
    {
        $out = [];
        $simpleLinks = $this->blockSimpleLinks;
        foreach ($simpleLinks as $linkRecord) {
            $out[] = $this->_getSimpleLinkWithStyleInfo($linkRecord);
        }

        return $out;
    }

    private function _getSimpleLinkWithStyleInfo(ContentTypeModel $simpleLink)
    {
        $link = $this->_getLink($simpleLink->link_info);
        if ($link) {
            $link['style'] = [];
            $link['style']['type'] = $simpleLink->link_effect;
            $link['style']['iconSize'] = $simpleLink->link_icon_size;
            $link['style']['isIconFirst'] = $simpleLink->link_icon_side == 'left';
            $link['style']['textSize'] = $simpleLink->link_text_size;
        }

        return $link;
    }

    private function _getMediaItem($mediaItem = NULL, $mediaSize = '')
    {
        if ($mediaItem) {
            return getImage($mediaItem, $mediaSize);
        } else {
            return (object)[
                'src' => null,
                'alt' => null,
            ];
        }
    }

    private function _getImages(BaseCollection $blockImages): array
    {
        $videoExts = config('backoffice.media.allowedExts.video');
        $images = $blockImages;
        $out = [];
        foreach ($images as $imageRecord) {
            $temp = $this->_getMediaItem($imageRecord);
            $temp->type = in_array(pathinfo($temp->src, PATHINFO_EXTENSION), $videoExts) ? 'video' : 'image';
            $out[] = $temp;
        }

        return $out;
    }

    private function _getKeyMessages(ContentTypeCollection $blockKeyMessages): array
    {
        $keyMessages = $blockKeyMessages;
        $out = [];
        foreach ($keyMessages as $keyMessageRecord) {
            $message = [
                'title' => $keyMessageRecord->message_title,
                'text'  => $keyMessageRecord->text
            ];

            $out[] = $message;
        }

        return $out;
    }

    private function _getClientLogos(ContentTypeCollection $blockClientLogos): array
    {
        $clientLogos = $blockClientLogos;
        $out = [];
        $columnIndexes = [];
        foreach ($clientLogos as $clientLogoRecord) {
            $message = [
                'title' => $clientLogoRecord->title,
                'img'   => $this->_getMediaItem($clientLogoRecord->logoImage)
            ];

            $out[$clientLogoRecord->column_index][$clientLogoRecord->pivot->position] = $message;
            if (!in_array($clientLogoRecord->column_index, $columnIndexes)) {
                $columnIndexes[] = $clientLogoRecord->column_index;
            }
        }

        foreach ($columnIndexes as $index) {
            ksort($out[$index]);
        }
        return $out;
    }

    private function _getServicesAndSolutions(ContentTypeCollection $blockServicesSolutions): array
    {
        $servicesSolutions = $blockServicesSolutions;
        $out = [];
        foreach ($servicesSolutions as $serviceSolutionRecord) {
            $out[] = $serviceSolutionRecord->title;
        }

        return $out;
    }

    private function _getBenefits(ContentTypeCollection $blockBenefits): array
    {
        $benefits = $blockBenefits;
        $out = [];
        foreach ($benefits as $benefitRecord) {
            $benefit = [
                'title' => $benefitRecord->context_index,
                'text'  => $benefitRecord->text,
                'link'  => $this->_getSimpleLinkWithStyleInfo($benefitRecord)
            ];

            $out[$benefitRecord->context_index] = $benefit;
        }

        return $out;
    }

    private function _getTeamPhrases(ContentTypeCollection $blockPhrases): array
    {
        $phrases = $blockPhrases;
        $out = [];
        foreach ($phrases as $phraseRecord) {
            $out[] = $phraseRecord->phrase;
        }
        return $out;
    }

    private function _getProjectDetails(ContentTypeCollection $blockProjectDetails): array
    {
        $details = $blockProjectDetails;
        $out = [];
        foreach ($details as $detailRecord) {
            $out[] = [
                'title' => $detailRecord->label,
                'text'  => $detailRecord->info
            ];
        }
        return $out;
    }

    /**************
     * Blocks
     **************/

    // Block Wysiwyg
    private function _getBlockWysiwyg(): array
    {
        return [
            'title' => $this->block_title,
            'text'  => $this->wysiwyg
        ];
    }

    // Block Wysiwyg
    private function _getBlockClaim(): array
    {
        return [
            'text' => $this->wysiwyg
        ];
    }

    // Block Image, Title, Text and Link
    private function _getBlockImageTitleTextAndLink(): array
    {
        return [
            'title'        => $this->block_title_text_area,
            'description'  => $this->block_primary_text_area,
            'link'         => $this->_getBlockLinkWithStyleInfo($this->block_link),
            'image'        => $this->_getMediaItem($this->blockImage),
            'isImageFirst' => $this->block_image_container_side == 'left',
            'position'     => $this->block_position,
            'imageSize'    => $this->block_image_size
        ];
    }

    // Block Open Positions Link
    private function _getBlockOpenPositionsLink(): array
    {
        return [
            'title' => $this->block_title_text_area,
            'link'  => $this->_getBlockLinkWithStyleInfo($this->block_link)
        ];
    }

    // Block Latest Project
    private function _getBlockLatestProject(): array
    {
        return [
            'title'        => $this->block_title_text_area,
            'description'  => $this->block_primary_text_area,
            'link'         => $this->_getBlockLinkWithStyleInfo($this->block_link),
            'image'        => $this->_getMediaItem($this->blockImage),
            'isImageFirst' => $this->block_image_container_side == 'left'
        ];
    }

    // Block Highlight
    private function _getBlockHighlight(): array
    {
        $keywordArray = [];
        if (strlen(trim($this->block_project_keywords))) {
            $keywordArray = explode(':', $this->block_project_keywords);
        }
        return [
            'title'       => $this->block_title_text_area,
            'description' => $this->block_primary_text_area,
            'link'        => $this->_getBlockLinkWithStyleInfo($this->block_link),
            'image'       => $this->_getMediaItem($this->blockImage),
            'keywords'    => $keywordArray
        ];
    }

    // Block OurSolutionsWithLink
    private function _getBlockOurSolutionsWithLink(): array
    {
        return [
            'title'        => $this->block_title_text_area,
            'description'  => $this->block_primary_text_area,
            'textServices' => $this->block_secondary_text_area,
            'link'         => $this->_getBlockLinkWithStyleInfo($this->block_link),
            'isList'       => $this->block_solutions_is_list == 1,
            'services'     => $this->_getSimpleLinksWithStyleInfo($this->blockSimpleLinks),
            'isCentered'   => $this->block_is_centered == 1
        ];
    }

    // Block ServiceColumns
    private function _getBlockServiceColumns(): array
    {
        return [
            'indexNr'          => $this->block_context_index,
            'title'            => $this->block_title_text_area,
            'descriptionTitle' => $this->block_primary_text_area,
            'descriptionText'  => $this->block_secondary_text_area,
            'image'            => $this->_getMediaItem($this->blockImage),
            'isImageFirst'     => $this->block_image_container_side == 'left',
            'imgLink'          => $this->_getBlockLinkWithStyleInfo($this->block_link),
            'links'            => $this->_getSimpleLinksWithStyleInfo($this->blockSimpleLinks)
        ];
    }

    // Block CapabilitiesHero
    private function _getBlockCapabilitiesHero(): array
    {
        return [
            'title'        => $this->wysiwyg,
            'image'        => $this->_getMediaItem($this->blockImage),
            'isImageFirst' => $this->block_image_container_side == 'left',
            'messages'     => $this->_getKeyMessages($this->blockKeyMessages)
        ];
    }

    // Block OurValues
    private function _getBlockOurValues(): array
    {
        return [
            'title'    => $this->block_title_text_area,
            'messages' => $this->_getKeyMessages($this->blockKeyMessages)
        ];
    }

    // Block PartnerRelationshipss
    private function _getBlockPartnerRelationships(): array
    {
        return [
            'title' => $this->block_title_text_area,
            'logos' => $this->_getClientLogos($this->blockClientLogos)
        ];
    }

    // Block CapabilityDetailTop
    private function _getBlockCapabilityDetailTop(): array
    {
        return [
            'title'        => $this->block_title_text_area,
            'subTitle'     => $this->block_primary_text_area,
            'extraInfo'    => $this->block_secondary_text_area,
            'svgImageType' => $this->block_svg_type
        ];
    }

    // Block TitleAndTextInColumns
    // Block TitleAndTextInRows
    private function _getBlockTitleAndText(): array
    {
        $out = [
            'title' => $this->block_title_text_area,
            'text'  => $this->wysiwyg
        ];

        if (in_array($this->type, ['blockTitleAndTextInRows', 'blockBlogArticleSection'])) {
            $out['titleSize'] = $this->block_title_size;
            $out['textSize'] = $this->block_primary_text_size;
            $out['textPosition'] = $this->block_text_position != 'default' ? $this->block_text_position : '';
            $out['blockSize'] = $this->block_title_container_size;
        }

        return $out;
    }

    // Block ServiceAndSolutions
    private function _getBlockServicesAndSolutions(): array
    {
        return [
            'title'    => $this->block_deliverables_text_box,
            'services' => $this->_getServicesAndSolutions($this->blockServicesSolutions)
        ];
    }

    // Block Benefits
    private function _getBlockBenefits(): array
    {
        return [
            'title'    => $this->block_title_text_box,
            'benefits' => $this->_getBenefits($this->blockBenefits)
        ];
    }

    // Block Case
    private function _getBlockCase(): array
    {
        return [
            'title'         => $this->block_title_text_box,
            'titleTextSize' => $this->block_title_text_size,
            'image'         => $this->_getMediaItem($this->blockImage),
            'link'          => $this->_getBlockLinkWithStyleInfo($this->block_link)
        ];
    }

    // Block Next
    private function _getBlockNext(): array
    {
        return [
            'title' => $this->block_title_text_box,
            'link'  => $this->_getBlockLinkWithStyleInfo($this->block_link)
        ];
    }

    // Block Related
    private function _getBlockRelated(): array
    {
        return [
            'title'        => $this->block_title_text_box,
            'text'         => $this->block_primary_text_area,
            'isTextOnLeft' => $this->block_text_side == 'left',
            'links'        => $this->_getSimpleLinksWithStyleInfo($this->blockSimpleLinks)
        ];
    }

    // Block MeetUs
    private function _getBlockMeetUs(): array
    {
        return [
            'title'       => $this->block_title_text_box,
            'description' => $this->block_primary_text_area,
            'link'        => $this->_getBlockLinkWithStyleInfo($this->block_link),
            'image'       => $this->_getMediaItem($this->blockImage)
        ];
    }

    private function _getBlockAccordion(): array
    {
        return [
            'title'    => $this->block_title_text_box,
            'messages' => $this->_getKeyMessages($this->blockKeyMessages)
        ];
    }

    private function _getBlockOpenPositionsList(): array
    {
        $openPositions = OpenPosition::full()
            ->select('*')
            ->where('status', 'published')
            ->get();

        $linkStyle = [
            'type'        => $this->block_link_effect,
            'iconSize'    => $this->block_link_icon_size,
            'isIconFirst' => $this->block_link_icon_side == 'left',
            'textSize'    => $this->block_link_text_size
        ];
        return [
            'title'         => $this->block_title_text_box,
            'openPositions' => new OpenPositionsCollection($openPositions, $linkStyle)

        ];
    }

    private function _getBlockTeamMembersList(): array
    {
        $query = TeamMember::full()
            ->select('*')
            ->where('status', 'published');
        switch ($this->block_order_by) {
            case "name_desc":
                $query->orderBy('title', 'desc');
                break;
            case "id":
                $query->orderBy('id', 'asc');
                break;
            case "name_asc":
            default:
                $query->orderBy('title', 'asc');
        }
        $teamMembers = $query->get();
        $phrases = $this->_getTeamPhrases($this->blockPhrases);

        $teamMembersArray = [];
        $teamMemberIndex = 0;
        $count = 0;
        $phraseIndex = 0;
        foreach ($teamMembers as $teamMemberRecord) {
            if ($count == (int)$this->block_count_for_phrase && count($phrases) && $phraseIndex < count($phrases)) {
                $teamMembersArray[] = [
                    'type'   => 'blockSentence',
                    'phrase' => $phrases[$phraseIndex]
                ];
                $count = 0;
                $phraseIndex++;
            }
            $count++;
            $newTeamMember = (new TeamMemberResource($teamMemberRecord))->toArray(null);
            $teamMemberIndex++;
            $teamMembersArray[] = array_merge($newTeamMember, ['type' => 'blockTeamMember', 'index' => $teamMemberIndex]);
        }

        return [
            'data' => $teamMembersArray
        ];
    }

    private function _getBlockForms(): array
    {
        return [
            'title' => $this->block_title_text_box
        ];
    }

    private function _getBlockMediaHero(): array
    {
        return [
            'video'               => $this->_getMediaItem($this->blockVideo),
            'image'               => $this->_getMediaItem($this->blockImage),
            'video_show_controls' => (bool)$this->video_show_controls,
            'video_auto_play'     => (bool)$this->video_auto_play,
            'video_muted'         => (bool)$this->video_muted
        ];
    }

    private function _getBlockProjectIntroWithDeliverables(): array
    {
        return [
            'deliverableTitle' => $this->block_deliverables_text_box,
            'deliverables'     => $this->_getServicesAndSolutions($this->blockServicesSolutions),
            'title'            => $this->block_title_text_area,
            'intro'            => $this->block_primary_text_area,
            'description'      => $this->wysiwyg
        ];
    }

    private function _getBlockProjectDetails(): array
    {
        return [
            'link'    => $this->_getBlockLinkWithStyleInfo($this->block_link),
            'details' => $this->_getProjectDetails($this->blockProjectDetails)
        ];
    }

    private function _getBlockWithFilterableList(): array
    {
        $linkStyle = [
            'type'        => $this->block_link_effect,
            'iconSize'    => $this->block_link_icon_size,
            'isIconFirst' => $this->block_link_icon_side == 'left',
            'textSize'    => $this->block_link_text_size
        ];
        return [
            'style' => $linkStyle
        ];
    }

    private function _getBlockSingleImageContainer(): array
    {
        $videoExts = config('backoffice.media.allowedExts.video');

        $mediaUrlObj = $this->_getMediaItem($this->blockImage);
        $mediaType = in_array(pathinfo($mediaUrlObj->src, PATHINFO_EXTENSION), $videoExts) ? 'video' : 'image';
        return [
            $mediaType => $mediaUrlObj,
            'size'     => $this->block_image_container_size
        ];
    }

    private function _getBlockMultipleImageContainer(): array
    {
        return [
            'images' => $this->_getImages($this->blockImages),
            'size'   => $this->block_image_container_size
        ];
    }

    private function _getBlockCaseContainer(): array
    {
        return [
            'data' => new BlocksCollection($this->blockBlocks)
        ];
    }

    private function _getBlockAuthor()
    {
        $author = $this->blockAuthor->first();
        $name = "";
        $role = "";
        $image = null;
        if ($author) {
            $name = $author->title;
            $role = $author->role;
            $image = $this->_getMediaItem($author->memberImage);
        }
        return [
            'name'  => $name,
            'role'  => $role,
            'image' => $image,
            'link'  => $this->_getBlockLinkWithStyleInfo($this->block_link)
        ];
    }

    private function _getBlockCodeSnippet()
    {
        return [
            'title' => $this->block_title,
            'code'  => $this->block_primary_text_area
        ];
    }
}
