<?php

namespace Plugins\Sms\Drivers\MelliPayamak;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Plugins\Sms\Contracts\PatternSmsDriverInterface;
use Plugins\Sms\Contracts\Response;
use Plugins\Sms\Exceptions\SmsDriverApiException;

use function getConfig;

class MelliPayamakSmsDriver implements PatternSmsDriverInterface
{
    private string $patternEndpoint = 'https://rest.payamak-panel.com/api/SendSMS/BaseServiceNumber';
    private string $endpoint = 'https://rest.payamak-panel.com/api/SendSMS/SendSMS';
    private array $data;

    /**
     * @throws SmsDriverApiException
     */
    public function sendByPattern(string $to, string $patternName): Response
    {
        $client = new Client();
        $smsSettings = json_decode(getConfig('sms_settings'), true);
        $smsDriverSettings = $smsSettings['drivers'][MELLIPAYAMAK_SMS_DRIVER] ?? [];
        $username = $smsDriverSettings['username'] ?? '';
        $password = $smsDriverSettings['password'] ?? '';
        $patternConfigs = $smsDriverSettings['patterns'][$patternName];
        $data = [
            'username' => $username,
            'password' => $password,
            'to' => $to,
            'bodyId' => $patternConfigs['code'],
            'text' => $this->buildPatternText($patternConfigs['text']),
            'isFlash' => false,
        ];

        try {
            $response = $client->post(
                $this->patternEndpoint,
                [
                    'form_params' => $data
                ]
            );

            $res = new MelliPayamakSmsDriverResponse();
            $res->setData(json_decode($response->getBody()->getContents(), true));

            return $res;
        } catch (GuzzleException $e) {
            throw new SmsDriverApiException($e->getMessage());
        }
    }

    private function buildPatternText(string $patternRawText): string
    {
        preg_match_all('/{:(\w+)}/', $patternRawText, $matches);
        $extractedVars = $matches[1];
        foreach ($extractedVars as $index => $value) {
            $extractedVars[$index] = $this->data[$value];
        }
        return implode(';', $extractedVars);
    }

    /**
     * @throws SmsDriverApiException
     */
    public function send(string $text, array $to): Response
    {
        $client = new Client();
        $smsSettings = json_decode(getConfig('sms_settings'), true);
        $smsDriverSettings = $smsSettings['drivers'][MELLIPAYAMAK_SMS_DRIVER] ?? [];
        $username = $smsDriverSettings['username'] ?? '';
        $password = $smsDriverSettings['password'] ?? '';
        $number = $smsDriverSettings['number'] ?? '';
        $data = [
            'username' => $username,
            'password' => $password,
            'to' => implode(',', $to),
            'from' => $number,
            'text' => $text,
            'isFlash' => false,
        ];

        try {
            $response = $client->post(
                $this->endpoint,
                [
                    'form_params' => $data
                ]
            );

            $res = new MelliPayamakSmsDriverResponse();
            $res->setData(json_decode($response->getBody()->getContents(), true));

            return $res;
        } catch (GuzzleException $e) {
            throw new SmsDriverApiException($e->getMessage());
        }
    }

    public function getEndpoint(): string
    {
        return $this->endpoint;
    }

    public function getPatternEndpoint(): string
    {
        return $this->patternEndpoint;
    }

    public function setData(array $data): void
    {
        $this->data = $data;
    }

    public function shouldSendByPattern(array $settings): bool
    {
        return $settings['send_by_patterns'] == true;
    }
}
