<?php

namespace FSPoster\App\SocialNetworks\Webhook\Adapters;

use FSPoster\App\Providers\Core\Settings;
use FSPoster\App\Providers\Schedules\ScheduleObject;
use FSPoster\App\Providers\Schedules\ScheduleShareException;
use FSPoster\App\SocialNetworks\Webhook\Api\PostingData;
use FSPoster\App\SocialNetworks\Webhook\Helpers\CustomMessageReplacer;

class PostingDataAdapter
{
    private ScheduleObject $scheduleObj;
    private ?string $customMessage = null;

    public function __construct(ScheduleObject $scheduleObj)
    {
        $this->scheduleObj = $scheduleObj;
    }

    /**
     * @return PostingData
     * @throws ScheduleShareException
     */
    public function getPostingData(): PostingData
    {
        $postingData = new PostingData();

        $postingData->url = $this->getPostingDataUrl();
        $postingData->method = $this->getPostingDataMethod();
        $postingData->contentType = $this->getPostingDataContentType();
        $postingData->headers = $this->getPostingDataHeaders();
        $postingData->formData = $this->getPostingDataFormData();
        $postingData->jsonData = $this->getPostingDataJsonData();

        return apply_filters('fsp_schedule_posting_data', $postingData, $this->scheduleObj);
    }

    public function getPostingDataUrl()
    {
        $scheduleData = $this->scheduleObj->getSchedule()->customization_data_obj;

        if (! $this->scheduleObj->readOnlyMode && empty($scheduleData->url)) {
            throw new ScheduleShareException(fsp__('URL can not be empty!'));
        }

        return $this->replaceShortCodes(
            CustomMessageReplacer::replaceForUrl(
                $scheduleData->url ?? '',
                $this->getPostingDataCustomMessage()
            )
        );
    }

    public function getPostingDataMethod()
    {
        $scheduleData = $this->scheduleObj->getSchedule()->customization_data_obj;

        return $scheduleData->method ?? 'GET';
    }

    public function getPostingDataContentType()
    {
        $scheduleData = $this->scheduleObj->getSchedule()->customization_data_obj;

        return $scheduleData->content_type ?? 'form';
    }

    public function getPostingDataHeaders()
    {
        $scheduleData = $this->scheduleObj->getSchedule()->customization_data_obj;

        $headers = CustomMessageReplacer::replaceForHeader(
            $scheduleData->headers ?? [],
            $this->getPostingDataCustomMessage()
        );

        return $this->replaceShortCodes($headers);
    }

    public function getPostingDataFormData()
    {
        $scheduleData = $this->scheduleObj->getSchedule()->customization_data_obj;

        $data = CustomMessageReplacer::replace(
            $scheduleData->form_data ?? [],
            $this->getPostingDataCustomMessage()
        );

        return $this->replaceShortCodes($data);
    }

    public function getPostingDataJsonData()
    {
        $scheduleData = $this->scheduleObj->getSchedule()->customization_data_obj;

        $data = CustomMessageReplacer::replace(
            json_decode($scheduleData->json_data ?? '[]', true),
            $this->getPostingDataCustomMessage()
        );

        return json_encode($this->replaceShortCodes($data));
    }

    public function getPostingDataCustomMessage(): string
    {
        if ($this->customMessage !== null) {
            return $this->customMessage;
        }

        $scheduleData = $this->scheduleObj->getSchedule()->customization_data_obj;

        $message = $this->scheduleObj->replaceShortCodes(
            $scheduleData->post_content ?? Settings::get('webhook_post_content', '{post_title}'),
            ! $this->scheduleObj->readOnlyMode
        );

        $message = strip_tags($message);
        $message = str_replace([ '&nbsp;', "\r\n" ], [ ' ', "\n" ], $message);

        $this->customMessage = apply_filters('fsp_schedule_post_content', trim($message), $this->scheduleObj);

        return $this->customMessage;
    }

    private function replaceShortCodes($value)
    {
        if (is_array($value)) {
            foreach ($value as $key => $item) {
                $value[ $key ] = $this->replaceShortCodes($item);
            }

            return $value;
        }

        if (is_string($value)) {
            return $this->scheduleObj->replaceShortCodes($value, ! $this->scheduleObj->readOnlyMode);
        }

        return $value;
    }
}
