<?php

namespace BitApps\SocialPro\HTTP\Services\Social\LineService;

use AllowDynamicProperties;
use BitApps\Social\Config;
use BitApps\Social\Deps\BitApps\WPKit\Hooks\Hooks;
use BitApps\Social\HTTP\Services\Interfaces\SocialInterface;
use BitApps\Social\HTTP\Services\Traits\LoggerTrait;
use BitApps\Social\Model\Schedule;
use BitApps\Social\Utils\Common;
use BitApps\Social\Utils\Hash;
use BitApps\SocialPro\Deps\BitApps\WPKit\Http\Client\HttpClient;

#[AllowDynamicProperties]
class PostPublishLineService implements SocialInterface
{
    use Common, LoggerTrait;

    public const PUSH_MESSAGE_URL = 'https://api.line.me/v2/bot/message/push';

    private $httpClient;

    private $accessToken;

    private $accountId;

    private $lineData = [];

    public function __construct()
    {
        $this->httpClient = new HttpClient();
    }

    public function publishPost($data)
    {
        $post = $data['post'] ?? null;
        $template = (object) $data['template'];
        $scheduleType = $data['schedule_type'] ?? null;
        $accountDetails = $data['account_details'];
        $schedule_id = $data['schedule_id'] ?? null;
        $accountId = $accountDetails->account_id;
        $accountName = $accountDetails->account_name;

        $this->accessToken = Hash::decrypt($accountDetails->access_token);
        $this->accountId = $accountDetails->account_id;

        $postData = $this->postData($scheduleType, $post, $template);

        $this->lineData['post'] = $this->normalizePostData($postData, true);

        $postPublishResponse = $this->pushMessage($postData);

        $status = \is_object($postPublishResponse) && isset($postPublishResponse->sentMessages) ? 1 : 0;

        $responseData = [
            'schedule_id' => $schedule_id,
            'details'     => [
                'account_id'   => $accountId,
                'account_name' => $accountName,
                'post_id'      => $post['ID'] ?? null,
                'response'     => $postPublishResponse,
                'post_url'     => null,
            ],
            'platform' => 'line',
            'status'   => $status
        ];

        $hookResponse = [
            'account_id'   => $accountId,
            'account_name' => $accountName,
            'post_url'     => $responseData['details']['post_url'],
            'status'       => $responseData['status'],
        ];

        $this->lineData['platform'] = 'line';
        $this->lineData['response'] = $hookResponse;

        if (!(\array_key_exists('keepLogs', $data) && $data['keepLogs'] === false)) {
            $this->logCreate($responseData);
        }

        Hooks::doAction(Config::withPrefix('line_post_publish'), $this->normalizePostData($postData), $hookResponse);

        return $this->lineData;
    }

    public function postData($scheduleType, $post, $template)
    {
        $postData = [];
        $template = (object) $template;

        if ($scheduleType === Schedule::scheduleType['DIRECT_SHARE']) {
            $templateMedia = array_map(function ($item) {
                return $item['url'];
            }, $template->media);

            $postData['content'] = $template->content ?? null;
            $postData['media'] = $template->isAllImages ? $templateMedia : null;
            $postData['link'] = $template->isLinkCard ? $template->link : null;
        } else {
            $template->platform = 'line';
            $postData = $this->replacePostContent($post['ID'], $template);
        }

        return $postData;
    }

    private function pushMessage($postData)
    {
        $bodyData = [
            'to' => $this->accountId,

        ];

        if (isset($postData['content']) && !empty($postData['content'])) {
            $bodyData['messages'] = [
                [
                    'type' => 'text',
                    'text' => $postData['content']
                ]
            ];
        }

        if (isset($postData['media']) && \is_array($postData['media']) && !empty($postData['media'])) {
            foreach ($postData['media'] as $mediaUrl) {
                $bodyData['messages'][] = [
                    'type'               => 'image',
                    'originalContentUrl' => $mediaUrl,
                    'previewImageUrl'    => $mediaUrl,
                ];
            }
        }

        if (isset($postData['link']) && !empty($postData['link'])) {
            $bodyData['messages'][] = [
                'type' => 'text',
                'text' => $postData['link']
            ];
        }

        $headers = [
            'Authorization' => 'Bearer ' . $this->accessToken,
            'Content-Type'  => 'application/json',
        ];

        $response = $this->httpClient->request(static::PUSH_MESSAGE_URL, 'POST', wp_json_encode($bodyData), $headers);

        return $response;
    }
}
