<?php
namespace ProVM\Money\Common\Service;

use GuzzleHttp\ClientInterface as Client;
use Carbon\Carbon;
use ProVM\Common\Factory\Model as ModelFactory;
use ProVM\Money\Currency;
use ProVM\Money\Source;
use ProVM\Money\Value;

class Update {
  protected $factory;
  protected $client;
  public function __construct(ModelFactory $factory, Client $client) {
    $this->factory = $factory;
    $this->client = $client;
  }

  protected function get(Client $client, string $url, bool $exception = true) {
    $res = $client->get($url);
    if ($res->getStatusCode() < 200 or $res->getStatusCode() >= 300) {
      if ($exception) {
        throw new \Exception('Url ' . $url . ' not connected.');
      }
      return false;
    }
    return json_decode($res->getBody());
  }

  protected function baseMap($unit) {
    $map = [
      'Dólar' => 'US Dollar',
      'Pesos' => 'Peso Chileno'
    ];
    return $map[$unit] ?? $unit;
  }
  protected function buildUrl(Source $source) {
    $date = Carbon::now();
    return str_replace([
        '{year}',
        '{month}',
        '{day}',
        '{hour}',
        '{minute}',
        '{second}'
      ], [
        $date->year,
        $date->month,
        $date->day,
        $date->hour,
        $date->minute,
        $date->second
      ], $source->url);
  }

  public function update() {
    ini_set('max_execution_time', 300);

    $sources = $this->factory->find(Source::class)->many();
    $output = ['count' => 0, 'values' => []];
    foreach ($sources as $source) {
      $url = $this->buildUrl($source);
      $b = $this->get($this->client, $url, false);
      if ($b === false) {
        continue;
      }
      $base = $this->factory->find(Currency::class)->where([
        ['name', '%' . $this->baseMap($b->unidad_medida) . '%', 'like']
      ])->one();
      if ($base === false) {
        continue;
      }
      foreach ($b->serie as $info) {
        $f = Carbon::parse($info->fecha);
        $data = [
          'currency_id' => $source->currency()->id,
          'date_time' => $f->format('Y-m-d H:i:s'),
          'value' => $info->valor,
          'base_id' => $base->id
        ];
        $result = Value::add($this->factory, $data);
        $output['values'] []= $result;
        if ($result->created === true) {
          $output['count'] ++;
        }
      }
    }
    return $output;
  }
}
