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

use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use ProVM\Common\Factory\Model as ModelFactory;
use ProVM\Common\Define\Controller\Json;
use ProVM\Money\Currency;

class Currencies {
  use Json;

  public function __invoke(Request $request, Response $response, ModelFactory $factory): Response {
    $currencies = $factory->find(Currency::class)->order('name')->array();
    $output = compact('currencies');
    return $this->withJson($response, $output);
  }
  public function get(Request $request, Response $response, ModelFactory $factory, $currency_id): Response {
    $currency = $factory->find(Currency::class)->one($currency_id);
    $output = [
      'get_data' => compact('currency_id'),
      'currency' => null
    ];
    if ($currency) {
      $output['currency'] = $currency->asArray();
    }
    return $this->withJson($response, $output);
  }
  public function add(Request $request, Response $response, ModelFactory $factory): Response {
    $post = json_decode($request->getBody()->getContents());
    $currencies = [];
    if (is_array($post)) {
      foreach ($post as $obj) {
        if (!is_object($obj)) {
          continue;
        }
        $currencies []= Currency::add($factory, $obj);
      }
    } else {
      $currencies []= Currency::add($factory, $post);
    }
    $output = [
      'post_data' => $post,
      'currencies' => $currencies
    ];
    return $this->withJson($response, $output);
  }
  public function edit(Request $request, Response $response, ModelFactory $factory, $currency_id): Response {
    $currency = $factory->find(Currency::class)->one($currency_id);
    $post = json_decode($request->getBody()->getContents());
    $edited = false;
    $output = [
      'get_data' => compact('currency_id'),
      'post_data' => $post,
      'currency' => null,
      'edited' => $edited
    ];
    if ($currency) {
      $edited = $currency->edit($post);
      $output['currency'] = $currency->asArray();
      $output['edited'] = $edited;
    }
    return $this->withJson($response, $output);
  }
  public function delete(Request $request, Response $response, ModelFactory $factory, $currency_id): Response {
    $currency = $factory->find(Currency::class)->one($currency_id);
    $output = ['get_data' => compact('currency_id'), 'currency' => null, 'deleted' => false];
    if ($currency) {
      $output['currency'] = $currency->asArray();
      $status = $currency->delete();
      $output['deleted'] = $status;
    }
    return $this->withJson($response, $output);
  }
  public function getAliases(Request $request, Response $response, ModelFactory $factory, $currency_id): Response {
    $currency = $factory->find(Currency::class)->one($currency_id);
    $output = [
      'get_data' => compact('currency_id'),
      'currency' => null,
      'aliases' => []
    ];
    if ($currency) {
      $output['currency'] = $currency->asArray();
      if ($currency->aliases()) {
        $output['aliases'] = array_map(function($item) {
          return $item->asArray();
        }, $currency->aliases());
      }
    }
    return $this->withJson($response, $output);
  }
  public function addAliases(Request $request, Response $response, ModelFactory $factory, $currency_id): Response {
    $currency = $factory->find(Currency::class)->one($currency_id);
    $post = json_decode($request->getBody()->getContents());
    $output = [
      'get_data' => compact('currency_id'),
      'post_data' => $post,
      'currency' => null,
      'aliases' => []
    ];
    if ($currency) {
      $output['currency'] = $currency->asArray();
      $aliases = [];
      if (is_array($post)) {
        foreach ($post as $obj) {
          if (!is_object($obj)) {
            continue;
          }
          $aliases []= $currency->addAlias($obj);
        }
      } else {
        $aliases []= $currency->addAlias($post);
      }
      $output['aliases'] = $aliases;
    }
    return $this->withJson($response, $output);
  }
  public function getValues(Request $request, Response $response, ModelFactory $factory, $currency_id): Response {
    $currency = $factory->find(Currency::class)->one($currency_id);
    $output = [
      'get_data' => compact('currency_id'),
      'currency' => null,
      'values' => []
    ];
    if ($currency) {
      $output['currency'] = $currency->asArray();
      if ($currency->values()) {
        $output['values'] = array_map(function($item) {
          return $item->asArray();
        }, $currency->values());
      }
    }
    return $this->withJson($response, $output);
  }
  public function addValues(Request $request, Response $response, ModelFactory $factory, $currency_id): Response {
    $currency = $factory->find(Currency::class)->one($currency_id);
    $post = json_decode($request->getBody()->getContents());
    $output = [
      'get_data' => compact('currency_id'),
      'post_data' => $post,
      'currency' => null,
      'values' => []
    ];
    if ($currency) {
      $output['currency'] = $currency->asArray();
      $values = [];
      if (is_array($post)) {
        foreach ($post as $obj) {
          if (!is_object($obj)) {
            continue;
          }
          $values []= $currency->addValue($obj);
        }
      } else {
        $values []= $currency->addValue($post);
      }
      $output['values'] = $values;
    }
    return $this->withJson($response, $output);
  }
  public function latestValue(Request $request, Response $response, ModelFactory $factory, $currency_id): Response {
    $currency = $factory->find(Currency::class)->one($currency_id);
    $output = [
      'get_data' => compact('currency_id'),
      'currency' => null,
      'value' => null
    ];
    if ($currency) {
      $output['currency'] = $currency->asArray();
      if ($currency->latest()) {
        $output['value'] = $currency->latest()->asArray();
      }
    }
    return $this->withJson($response, $output);
  }
  public function getSources(Request $request, Response $response, ModelFactory $factory, $currency_id): Response {
    $currency = $factory->find(Currency::class)->one($currency_id);
    $output = [
      'get_data' => compact('currency_id'),
      'currency' => null,
      'sources' => []
    ];
    if ($currency) {
      $output['currency'] = $currency->asArray();
      if ($currency->sources()) {
        $output['sources'] = array_map(function($item) {
          return $item->asArray();
        }, $currency->sources());
      }
    }
    return $this->withJson($response, $output);
  }
  public function addSources(Request $request, Response $response, ModelFactory $factory, $currency_id): Response {
    $currency = $factory->find(Currency::class)->one($currency_id);
    $post = json_decode($request->getBody()->getContents());
    $output = [
      'get_data' => compact('currency_id'),
      'post_data' => $post,
      'currency' => null,
      'sources' => []
    ];
    if ($currency) {
      $output['currency'] = $currency->asArray();
      $sources = [];
      if (is_array($post)) {
        foreach ($post as $obj) {
          if (!is_object($obj)) {
            continue;
          }
          $sources []= $currency->addSource($obj);
        }
      } else {
        $sources []= $currency->addSource($post);
      }
      $output['sources'] = $sources;
    }
    return $this->withJson($response, $output);
  }

  public function find(Request $request, Response $response, ModelFactory $factory, $query): Response {
    $currency = Currency::find($factory, $query);
    $output = [
      'get_data' => compact('query'),
      'currency' => null
    ];
    if ($currency) {
      $output['currency'] = $currency->asArray();
    }
    return $this->withJson($response, $output);
  }
  public function findValues(Request $request, Response $response, ModelFactory $factory, $query): Response {
    $currency = Currency::find($factory, $query);
    $output = [
      'get_data' => compact('query'),
      'currency' => null,
      'values' => []
    ];
    if ($currency) {
      $output['currency'] = $currency->asArray();
      if ($currency->values()) {
        $output['values'] = array_map(function($item) {
          return $item->asArray();
        }, $currency->values());
      }
    }
    return $this->withJson($response, $output);
  }
  public function findLatest(Request $request, Response $response, ModelFactory $factory, $query): Response {
    $currency = Currency::find($factory, $query);
    $output = [
      'get_data' => compact('currency_id'),
      'currency' => null,
      'value' => null
    ];
    if ($currency) {
      $output['currency'] = $currency->asArray();
      if ($currency->latest()) {
        $output['value'] = $currency->latest()->asArray();
      }
    }
    return $this->withJson($response, $output);
  }
  public function findSources(Request $request, Response $response, ModelFactory $factory, $query): Response {
    $currency = Currency::find($factory, $query);
    $output = [
      'get_data' => compact('query'),
      'currency' => null,
      'sources' => []
    ];
    if ($currency) {
      $output['currency'] = $currency->asArray();
      if ($currency->sources()) {
        $output['sources'] = array_map(function($item) {
          return $item->asArray();
        }, $currency->sources());
      }
    }
    return $this->withJson($response, $output);
  }
}
