<?php

namespace App\Console\Commands\CurrencyRates;

use App\Core\Repository\CurrencyRates\CurrencyRatesRepository;
use App\Core\Service\CurrencyService;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class CurrencyRatesService extends Command
{
    protected $signature = 'cron:currency-rates';

    protected $description = '';

    protected $serviceUrl;

    private $currencyRatesRepository;
    private $currencyService;

    public function __construct(
        CurrencyRatesRepository $currencyRatesRepository,
        CurrencyService $currencyService
    )
    {
        parent::__construct();

        $this->currencyRatesRepository = $currencyRatesRepository;
        $this->serviceUrl = 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml';
        $this->currencyService = $currencyService;
    }

    public function handle()
    {

        $currencyList = $this->currencyService->getCurrencyList();

        if (!$currencyList['status']) {
            $this->error(date('Y-m-d H:i:s') . ' : CurrencyList alınamadı.');
        }

        $availableCurrencies = [];
        foreach ($currencyList['data'] as $currency) {
            $availableCurrencies[] = $currency['code'];
        }
        $availableCurrency = $availableCurrencies;

        $this->restClient = new Client(['allow_redirects' => false]);
        $request = $this->restClient->GET($this->serviceUrl);
        $requestResponse = $request->getBody();

        $currencyRatesData = json_decode(json_encode(simplexml_load_string($requestResponse)), 1);

        if (empty($currencyRatesData)) {
            $this->error(date('Y-m-d H:i:s') . ' : CurrencyRatesData alınamadı.');

            return false;
        }

        //Georgia GEL
        $tbcBankApiUrl = 'https://nbg.gov.ge/gw/api/ct/monetarypolicy/currencies/en/json/';
        $requestTbcBank = $this->restClient->GET($tbcBankApiUrl);

        $requestResponseTbcBank = $requestTbcBank->getBody()->getContents();
        $currencyRatesDataTbcBank = json_decode($requestResponseTbcBank, 1);

        if (empty($currencyRatesDataTbcBank)) {
            $this->error(date('Y-m-d H:i:s') . ' : GEL CurrencyRatesData alınamadı.');
        }

        $currencyRatesDataTbcBank = reset($currencyRatesDataTbcBank);
        $currencyRatesDataTbcBank = collect($currencyRatesDataTbcBank['currencies'])->where('code','EUR')->first();

        $currencyRatesData['Cube']['Cube']['Cube'][] = [
            '@attributes' => [
                'currency' => 'GEL',
                'rate' => $currencyRatesDataTbcBank['rate']
            ]
        ];
        //Georgia GEL

        //Morocco MAD
        $euroApiUrl = 'https://www.floatrates.com/daily/eur.xml';
        $requestEuroApiUrl = $this->restClient->GET($euroApiUrl);
        $responseEuroApi = $requestEuroApiUrl->getBody();

        $currencyRatesDataEuroApi = json_decode(json_encode(simplexml_load_string($responseEuroApi)), 1);

        if (empty($currencyRatesDataEuroApi)) {
            $this->error(date('Y-m-d H:i:s') . ' : EUR CurrencyRatesData alınamadı.');
        }

        $currencyRatesDataEuroApiSelected = collect($currencyRatesDataEuroApi['item'])->where('targetCurrency','MAD')->first();

        $currencyRatesData['Cube']['Cube']['Cube'][] = [
            '@attributes' => [
                'currency' => 'MAD',
                'rate' => (float)number_format($currencyRatesDataEuroApiSelected['exchangeRate'],4)
            ]
        ];
        //Morocco MAD

        $currencyRatesDataEuroApiSelected = collect($currencyRatesDataEuroApi['item'])->where('targetCurrency','AZN')->first();

        $currencyRatesData['Cube']['Cube']['Cube'][] = [
            '@attributes' => [
                'currency' => 'AZN',
                'rate' => (float)number_format($currencyRatesDataEuroApiSelected['exchangeRate'],4)
            ]
        ];
        //Azerbaijani AZN

        $date = $currencyRatesData['Cube']['Cube']['@attributes']['time'];

        $currencyRatesCriteria = [
            'criteria' => [
                ['field' => 'date', 'condition' => '=', 'value' => $date],
            ],
            'count' => true,
        ];

        $currencyRateCount = $this->currencyRatesRepository->findByCriteria($currencyRatesCriteria);


        if ($currencyRateCount > 0) {
            $this->error(date('Y-m-d H:i:s') . ' : ' . $date . ' tarihi için döviz bilgisi güncel.');

            return false;
        }

        $euroParity[] = [
            'currency_code' => 'EUR',
            'exc_currency_code' => 'EUR',
            'rate' => 1
        ];
        foreach ($currencyRatesData['Cube']['Cube']['Cube'] as $perEuroParity) {
            if (in_array($perEuroParity['@attributes']['currency'], $availableCurrency)) {
                $euroParity[] = [
                    'currency_code' => 'EUR',
                    'exc_currency_code' => $perEuroParity['@attributes']['currency'],
                    'rate' => floatval($perEuroParity['@attributes']['rate']),
                ];
            }
        }

        $exchangeParity = [];
        foreach ($euroParity as $perParity) {
            foreach ($euroParity as $perParityExchange) {
                $exchangeParity[$perParity['exc_currency_code'] . $perParityExchange['exc_currency_code']] = [
                    'currency_code' => $perParity['exc_currency_code'],
                    'exc_currency_code' => $perParityExchange['exc_currency_code'],
                    'rate' => $perParityExchange['rate'] / $perParity['rate']
                ];


                $exchangeParity[$perParityExchange['exc_currency_code'] . $perParity['exc_currency_code']] = [
                    'currency_code' => $perParityExchange['exc_currency_code'],
                    'exc_currency_code' => $perParity['exc_currency_code'],
                    'rate' => $perParity['rate'] / $perParityExchange['rate']
                ];
            }
        }

        ksort($exchangeParity);

        foreach ($exchangeParity as $perExchangeParity) {


            $data[] = [
                'date' => $date,
                'currency_code' => $perExchangeParity['currency_code'],
                'exc_currency_code' => $perExchangeParity['exc_currency_code'],
                'rate' => $perExchangeParity['rate'],
                'created_at' => Carbon::now()->timestamp
            ];
        }

        $currencyRateUpdate = $this->currencyRatesRepository->insert($data);

        if ($currencyRateUpdate['status'] == 'success') {
            $this->info(date('Y-m-d H:i:s') . ' : ' . $date . ' tarihi için ' . count($exchangeParity) . ' adet döviz bilgisi güncellendi.');
        }


    }
}
