<?php

namespace Ignite\Core\Helpers;

use Ignite\Core\Facades\Program;
use Illuminate\Foundation\Application;
use Illuminate\Support\Traits\Macroable;

class Format
{
    use Macroable;

    /**
     * @var Application
     */
    protected $app;

    /**
     * Format constructor.
     *
     * @param Application $app
     */
    public function __construct(Application $app)
    {
        $this->app = $app;
    }

    /**
     * Format a date.
     *
     * @param string $value
     * @param string $format
     * @param string $default
     *
     * @return false|string
     */
    public function date($value, $format = 'Y-m-d', $default = '')
    {
        return $this->app->make(Date::class, compact('value'))->format($format, $default);
    }

    /**
     * Format a datetime.
     *
     * @param string $value
     * @param string $format
     * @param string $default
     *
     * @return false|string
     */
    public function datetime($value, $format = 'Y-m-d H:i:s', $default = '')
    {
        return $this->app->make(DateTime::class, compact('value'))->format($format, $default);
    }

    /**
     * Format an amount.
     *
     * @param int|float|string $value
     * @param int $decimals
     * @param int $default
     *
     * @return mixed
     */
    public function amount($value, $decimals = 0, $default = 0)
    {
        return $this->app->make(Amount::class, compact('value'))->format($decimals, $default);
    }

    /**
     * Format a currency.
     *
     * @param int|float|string $value
     * @param int $decimals
     * @param int $default
     *
     * @return mixed
     */
    public function currency($value, $decimals = 0, $default = 0)
    {
        return $this->app->make(Currency::class, compact('value'))->format($decimals, $default);
    }

    /**
     * Automatically format a balance depending on the program type.
     *
     * @param  int|float|string $value
     * @param  mixed $decimals
     * @param  int $default
     * @return string
     */
    public function balance($value, $decimals = null, $default = 0)
    {
        return Program::isPayout()
            ? $this->currency($value, $decimals ?? 2, $default)
            : $this->amount($value, $decimals ?? 0, $default);
    }

    /**
     * Format a given file size as human readable.
     *
     * @param int $size
     * @param int $precision
     * @return string
     */
    public function bytes($size, $precision = 2)
    {
        $size = (int) $size;

        if ($size > 0) {
            $base = log($size) / log(1024);
            $suffixes = [' b', ' KB', ' MB', ' GB', ' TB'];

            return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];
        }

        return $size;
    }
}
